diff --git a/src/Data/ByteArray/Builder/Small.hs b/src/Data/ByteArray/Builder/Small.hs index 7e59810..c1f71b0 100644 --- a/src/Data/ByteArray/Builder/Small.hs +++ b/src/Data/ByteArray/Builder/Small.hs @@ -12,17 +12,22 @@ module Data.ByteArray.Builder.Small -- * Evaluation , run , pasteST + , pasteIO + -- * Materialized Byte Sequences + , bytes + , bytearray -- * Numbers , word64Dec ) where import Control.Monad.Primitive +import Control.Monad.ST +import Data.Bytes.Types import Data.Char (ord) import Data.Primitive import GHC.Exts -import GHC.Word -import Data.Bytes.Types import GHC.ST +import GHC.Word -- | An unmaterialized sequence of bytes that may be pasted -- into a mutable byte array. @@ -59,6 +64,10 @@ pasteST (Builder f) (MutableBytes (MutableByteArray arr) (I# off) (I# len)) = then (# s1, Just (I# r) #) else (# s1, Nothing #) +pasteIO :: Builder -> MutableBytes RealWorld -> IO (Maybe Int) +{-# inline pasteIO #-} +pasteIO b m = stToIO (pasteST b m) + construct :: (forall s. MutableBytes s -> ST s (Maybe Int)) -> Builder construct f = Builder $ \arr off len s0 -> @@ -67,6 +76,16 @@ construct f = Builder Nothing -> (# s1, (-1#) #) Just (I# n) -> (# s1, n #) +bytearray :: ByteArray -> Builder +bytearray a = bytes (Bytes a 0 (sizeofByteArray a)) + +bytes :: Bytes -> Builder +bytes (Bytes src soff slen) = construct $ \(MutableBytes arr off len) -> if len >= slen + then do + copyByteArray arr off src soff slen + pure (Just (len - slen)) + else pure Nothing + word64Dec :: Word64 -> Builder word64Dec (W64# w) = word64Dec# w