ZHaskell / stdio

Haskell Standard Input and Output
105 stars 5 forks source link

Provide CString/ByteString conversions for Bytes #26

Open jac3km4 opened 5 years ago

jac3km4 commented 5 years ago

I think they'd be pretty useful when using stdio with other libraries, I needed to define them in order to use proto-lens. Those seem to work for me:

import           Std.Foreign.PrimArray as F
import qualified Data.ByteString       as BS
import           Std.Data.CBytes        as CBytes

bytesToByteString :: Bytes -> IO ByteString
bytesToByteString bytes =
  F.withPrimVectorSafe bytes (\ptr len -> BS.packCStringLen (castPtr ptr, len))

bytesFromByteString :: ByteString -> IO Bytes
bytesFromByteString bs =
  CBytes.toBytes <$> BU.unsafeUseAsCString bs CBytes.fromCString
winterland1989 commented 5 years ago

Brilliant usage of withPrimVectorSafe, which should be able to do the unpinned/pinned conversion automatically.

The bytesFromByteString can be improved because CBytes.fromCString will always copy the bytes content and add a NUL terminator (which is part of CBytes 's invariant). We can save this copy by looking into ByteString's constructor (then ForeignPtr 's constructor) directly.

I will definitely accept a patch adding these functions, you can add them in Std.Data.Vector.Base, and re-export from Std.Data.Vector if you want. Add another section in the export list is preferred.