Skip to content

Instantly share code, notes, and snippets.

@chessai
Created October 4, 2019 13:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chessai/6f2822e18619fe3a2ef28e1754f14100 to your computer and use it in GitHub Desktop.
Save chessai/6f2822e18619fe3a2ef28e1754f14100 to your computer and use it in GitHub Desktop.
bytearray <===> bytestring
-- | Like 'unsafeByteArrayToByteString', but might perform a copy
-- if the 'ByteArray' is not pinned.
byteArrayToByteString :: ByteArray -> ByteString
byteArrayToByteString b@(ByteArray b#)
| isTrue# (isByteArrayPinned# b#) = unsafeByteArrayToByteString b
| otherwise = runST $ do
let len = sizeofByteArray b
marr@(MutableByteArray marr#) <- newPinnedByteArray len
copyByteArray marr 0 b 0 len
let addr# = byteArrayContents# (unsafeCoerce# marr#)
copyMutableByteArrayToAddr (Ptr addr#) marr 0 len
pure (PS (ForeignPtr addr# (PlainPtr (unsafeCoerce# marr#))) 0 len)
-- | Convert a (necessarily pinned) 'ByteArray' to a
-- 'ByteString', without copying. This has undefined behaviour if you
-- use it on an unpinned 'ByteArray'.
unsafeByteArrayToByteString :: ByteArray -> ByteString
unsafeByteArrayToByteString (ByteArray b#) =
let contents# = byteArrayContents# b#
fp = ForeignPtr contents# (PlainPtr (unsafeCoerce# b#))
len = I# (sizeofByteArray# b#)
in PS fp 0 len
{-# inline unsafeByteArrayToByteString #-}
byteStringToByteArray :: ByteString -> ByteArray
byteStringToByteArray (PS fp off len) =
accursedUnutterablePerformIO $
withForeignPtr fp $ \ptr -> do
marr <- newByteArray len
copyPtrToMutableByteArray (ptr `plusPtr` off) marr 0 len
unsafeFreezeByteArray marr
{-# inline byteStringToByteArray #-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment