Add cstringLen

This commit is contained in:
Andrew Martin 2020-02-26 16:15:41 -05:00
parent 4c7227e7e9
commit d1d4ed0d12
2 changed files with 19 additions and 2 deletions

View file

@ -5,6 +5,7 @@
* Add `wordPaddedDec4`. * Add `wordPaddedDec4`.
* Add `reversedOnto` and `commitsOntoChunks`. * Add `reversedOnto` and `commitsOntoChunks`.
* Add `ascii(2|3|4|5|6)`. * Add `ascii(2|3|4|5|6)`.
* Add `cstringLen` unbounded builder.
## 0.3.3.0 -- 2020-02-10 ## 0.3.3.0 -- 2020-02-10

View file

@ -26,6 +26,7 @@ module Data.ByteArray.Builder
, shortTextUtf8 , shortTextUtf8
, shortTextJsonString , shortTextJsonString
, cstring , cstring
, cstringLen
, stringUtf8 , stringUtf8
-- * Encode Integral Types -- * Encode Integral Types
-- ** Human-Readable -- ** Human-Readable
@ -132,6 +133,7 @@ import Data.Primitive (ByteArray(..),MutableByteArray(..),PrimArray(..))
import Data.Text.Short (ShortText) import Data.Text.Short (ShortText)
import Data.WideWord (Word128,Word256) import Data.WideWord (Word128,Word256)
import Data.Word (Word64,Word32,Word16,Word8) import Data.Word (Word64,Word32,Word16,Word8)
import Foreign.C.String (CStringLen)
import GHC.ByteOrder (ByteOrder(BigEndian,LittleEndian),targetByteOrder) import GHC.ByteOrder (ByteOrder(BigEndian,LittleEndian),targetByteOrder)
import GHC.Exts (Int(I#),Char(C#),Int#,State#,ByteArray#,(>=#)) import GHC.Exts (Int(I#),Char(C#),Int#,State#,ByteArray#,(>=#))
import GHC.Exts (RealWorld,MutableByteArray#,(+#),(-#),(<#)) import GHC.Exts (RealWorld,MutableByteArray#,(+#),(-#),(<#))
@ -324,11 +326,11 @@ fromBoundedOne (UnsafeBounded.Builder f) = Builder $ \buf0 off0 len0 cs0 s0 ->
in case f buf1 off1 s1 of in case f buf1 off1 s1 of
(# s2, off2 #) -> (# s2, buf1, off2, len1 -# (off2 -# off1), cs1 #) (# s2, off2 #) -> (# s2, buf1, off2, len1 -# (off2 -# off1), cs1 #)
-- | Create a builder from an unsliced byte sequence. -- | Create a builder from an unsliced byte sequence. Implemented with 'bytes'.
byteArray :: ByteArray -> Builder byteArray :: ByteArray -> Builder
byteArray a = bytes (Bytes a 0 (PM.sizeofByteArray a)) byteArray a = bytes (Bytes a 0 (PM.sizeofByteArray a))
-- | Create a builder from a short bytestring. -- | Create a builder from a short bytestring. Implemented with 'bytes'.
shortByteString :: ShortByteString -> Builder shortByteString :: ShortByteString -> Builder
shortByteString (SBS x) = bytes (Bytes a 0 (PM.sizeofByteArray a)) shortByteString (SBS x) = bytes (Bytes a 0 (PM.sizeofByteArray a))
where a = ByteArray x where a = ByteArray x
@ -368,6 +370,20 @@ copy (Bytes (ByteArray src# ) (I# soff# ) (I# slen# )) = Builder
where where
!(I# newSz) = max (I# slen#) 4080 !(I# newSz) = max (I# slen#) 4080
-- | Create a builder from a C string with explicit length. The builder
-- must be executed before the C string is freed.
cstringLen :: CStringLen -> Builder
cstringLen (Exts.Ptr src#, I# slen# ) = Builder
(\buf0 off0 len0 cs0 s0 -> case len0 <# slen# of
1# -> case Exts.newByteArray# newSz s0 of
(# s1, buf1 #) -> case Exts.copyAddrToByteArray# src# buf1 0# slen# s1 of
s2 -> (# s2, buf1, slen#, newSz -# slen#, Mutable buf0 off0 cs0 #)
_ -> let !s1 = Exts.copyAddrToByteArray# src# buf0 off0 slen# s0 in
(# s1, buf0, off0 +# slen#, len0 -# slen#, cs0 #)
)
where
!(I# newSz) = max (I# slen#) 4080
-- | Create a builder from a byte sequence. This never calls @memcpy@. -- | Create a builder from a byte sequence. This never calls @memcpy@.
-- Instead, it pushes a chunk that references the argument byte sequence. -- Instead, it pushes a chunk that references the argument byte sequence.
-- This wastes the remaining space in the active chunk, so it may adversely -- This wastes the remaining space in the active chunk, so it may adversely