builder 0.1 → 0.2
raw patch · 2 files changed
+100/−109 lines, 2 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Builder: buildByteArray :: () => ByteArray -> Int -> Int -> Builder
- Builder: buildChar :: Char -> Builder
- Builder: buildDouble :: Double -> Builder
- Builder: buildFixed :: (FixedOrdering b, Bytes a, Prim a, PrimUnaligned a) => Fixed b a -> Builder
- Builder: buildFloat :: Float -> Builder
- Builder: buildInt :: Int -> Builder
- Builder: buildInt16 :: Int16 -> Builder
- Builder: buildInt32 :: Int32 -> Builder
- Builder: buildInt64 :: Int64 -> Builder
- Builder: buildInt8 :: Int8 -> Builder
- Builder: buildPtr :: Ptr a -> Builder
- Builder: buildUnaligned :: (Prim a, PrimUnaligned a) => a -> Builder
- Builder: buildWord :: Word -> Builder
- Builder: buildWord16 :: Word16 -> Builder
- Builder: buildWord32 :: Word32 -> Builder
- Builder: buildWord64 :: Word64 -> Builder
- Builder: buildWord8 :: Word8 -> Builder
- Builder: instance GHC.Base.Monoid (Builder.BI s)
- Builder: instance GHC.Base.Monoid (Builder.Writer s)
- Builder: instance GHC.Base.Semigroup (Builder.BI s)
- Builder: instance GHC.Base.Semigroup (Builder.Writer s)
+ Builder: bytearray :: () => ByteArray -> Int -> Int -> Builder
+ Builder: char :: Char -> Builder
+ Builder: double :: Double -> Builder
+ Builder: fixed :: (FixedOrdering b, Bytes a, Prim a, PrimUnaligned a) => Fixed b a -> Builder
+ Builder: float :: Float -> Builder
+ Builder: int :: Int -> Builder
+ Builder: int16 :: Int16 -> Builder
+ Builder: int32 :: Int32 -> Builder
+ Builder: int64 :: Int64 -> Builder
+ Builder: int8 :: Int8 -> Builder
+ Builder: ptr :: Ptr a -> Builder
+ Builder: unaligned :: (Prim a, PrimUnaligned a) => a -> Builder
+ Builder: word :: Word -> Builder
+ Builder: word16 :: Word16 -> Builder
+ Builder: word32 :: Word32 -> Builder
+ Builder: word64 :: Word64 -> Builder
+ Builder: word8 :: Word8 -> Builder
Files
- builder.cabal +1/−1
- src/Builder.hs +99/−108
builder.cabal view
@@ -2,7 +2,7 @@ name: builder version:- 0.1+ 0.2 synopsis: bounded ByteArray builder type description:
src/Builder.hs view
@@ -16,23 +16,23 @@ , build -- * Construction- , buildUnaligned- , buildWord8- , buildWord16- , buildWord32- , buildWord64- , buildWord- , buildInt8- , buildInt16- , buildInt32- , buildInt64- , buildInt- , buildFloat- , buildDouble- , buildChar- , buildPtr- , buildByteArray- , buildFixed+ , unaligned+ , word8+ , word16+ , word32+ , word64+ , word+ , int8+ , int16+ , int32+ , int64+ , int+ , float+ , double+ , char+ , ptr+ , bytearray+ , fixed ) where import Data.Primitive hiding (writeByteArray)@@ -42,50 +42,41 @@ import GHC.Exts hiding (build) import System.ByteOrder -newtype Writer s = W- { _w :: ()+-- | A 'Builder' for 'ByteArray's that has O(1) append.+-- To create a 'ByteArray', use 'build'. This will only+-- do one allocation.+data Builder = Builder+ { size :: Int#+ , writer :: forall s. () => MutableByteArray# s- -- buffer -> Int#- -- offset into buffer -> (State# s -> (# State# s, Int# #))- -- update to offset } -instance Semigroup (Writer s) where- W x <> W y = W $ \marr# ix0# s0# -> case x marr# ix0# s0# of- (# s1#, ix1# #) -> y marr# ix1# s1#- {-# inline (<>) #-}--instance Monoid (Writer s) where- mempty = W $ \_ ix0# s0# -> (# s0#, ix0# #)- {-# inline mempty #-}--data BI s = BI !Int !(Writer s)--instance Semigroup (BI s) where- BI len0 w0 <> BI len1 w1 = BI (len0 + len1) (w0 <> w1)- {-# inline (<>) #-}--instance Monoid (BI s) where- mempty = BI 0 mempty- {-# inline mempty #-}---- | A 'Builder' for 'ByteArray's that has O(1) append.--- To create a 'ByteArray', use 'build'. This will only--- do one allocation.-newtype Builder = Builder (forall s. BI s)- instance Semigroup Builder where- Builder b0 <> Builder b1 = Builder (b0 <> b1)- {-# inline (<>) #-}+ Builder len0 w0 <> Builder len1 w1 = Builder+ { size = len0 +# len1+ , writer = \marr# ix0# s0# ->+ case w0 marr# ix0# s0# of+ (# s1#, ix1# #) -> w1 marr# ix1# s1#+ } instance Monoid Builder where- mempty = Builder mempty- {-# inline mempty #-}+ mempty = Builder+ { size = 0#+ , writer = \_ ix0# s0# -> (# s0#, ix0# #)+ } -runWriter# :: Int# -> Writer s -> State# s -> (# State# s, ByteArray# #)-runWriter# sz# (W g) = \s0# -> case newByteArray# sz# s0# of+type Writer# s = MutableByteArray# s+ -> Int#+ -> (State# s -> (# State# s, Int# #))++runWriter# :: ()+ => Int#+ -> Writer# s+ -> State# s+ -> (# State# s, ByteArray# #)+runWriter# sz# g = \s0# -> case newByteArray# sz# s0# of (# s1#, marr# #) -> case g marr# 0# s1# of (# s2#, _ #) -> case unsafeFreezeByteArray# marr# s2# of (# s3#, b# #) -> (# s3#, b# #)@@ -93,14 +84,14 @@ -- | Convert a 'Builder' into a 'ByteArray'. build :: Builder -> ByteArray-build (Builder (BI (I# len#) w)) = case runRW# (runWriter# len# w) of+build (Builder len# w) = case runRW# (runWriter# len# w) of (# _, b# #) -> ByteArray b# {-# inline build #-} writeUnaligned :: (Prim a, PrimUnaligned a) => a- -> Writer s-writeUnaligned a = W $ \marr# ix0# s0# ->+ -> Writer# s+writeUnaligned a = \marr# ix0# s0# -> case writeUnalignedByteArray# marr# ix0# a s0# of s1# -> (# s1#, ix0# +# alignment# a #) {-# inline writeUnaligned #-}@@ -109,103 +100,103 @@ => ByteArray -> Int -> Int- -> Writer s+ -> Writer# s writeByteArray (ByteArray src#) (I# off#) (I# len#)- = W $ \marr# ix0# s0# ->+ = \marr# ix0# s0# -> case copyByteArray# src# off# marr# ix0# len# s0# of s1# -> (# s1#, ix0# +# len# #) {-# inline writeByteArray #-} -- | A 'Builder' for any 'Prim' and 'PrimUnaligned' value.-buildUnaligned :: (Prim a, PrimUnaligned a)+unaligned :: (Prim a, PrimUnaligned a) => a -> Builder-buildUnaligned a = Builder (BI (sizeOf a) (writeUnaligned a))-{-# inline buildUnaligned #-}+unaligned a = Builder (sizeOf# a) (writeUnaligned a)+{-# inline unaligned #-} -- | A 'Builder' for 'Word8'.-buildWord8 :: Word8 -> Builder-buildWord8 = buildUnaligned-{-# inline buildWord8 #-}+word8 :: Word8 -> Builder+word8 = unaligned+{-# inline word8 #-} -- | A 'Builder' for 'Word16'.-buildWord16 :: Word16 -> Builder-buildWord16 = buildUnaligned-{-# inline buildWord16 #-}+word16 :: Word16 -> Builder+word16 = unaligned+{-# inline word16 #-} -- | A 'Builder' for 'Word32'.-buildWord32 :: Word32 -> Builder-buildWord32 = buildUnaligned-{-# inline buildWord32 #-}+word32 :: Word32 -> Builder+word32 = unaligned+{-# inline word32 #-} -- | A 'Builder' for 'Word64'.-buildWord64 :: Word64 -> Builder-buildWord64 = buildUnaligned-{-# inline buildWord64 #-}+word64 :: Word64 -> Builder+word64 = unaligned+{-# inline word64 #-} -- | A 'Builder' for 'Word'.-buildWord :: Word -> Builder-buildWord = buildUnaligned-{-# inline buildWord #-}+word :: Word -> Builder+word = unaligned+{-# inline word #-} -- | A 'Builder' for 'Int8'.-buildInt8 :: Int8 -> Builder-buildInt8 = buildUnaligned-{-# inline buildInt8 #-}+int8 :: Int8 -> Builder+int8 = unaligned+{-# inline int8 #-} -- | A 'Builder' for 'Int16'.-buildInt16 :: Int16 -> Builder-buildInt16 = buildUnaligned-{-# inline buildInt16 #-}+int16 :: Int16 -> Builder+int16 = unaligned+{-# inline int16 #-} -- | A 'Builder' for 'Int32'.-buildInt32 :: Int32 -> Builder-buildInt32 = buildUnaligned-{-# inline buildInt32 #-}+int32 :: Int32 -> Builder+int32 = unaligned+{-# inline int32 #-} -- | A 'Builder' for 'Int64'.-buildInt64 :: Int64 -> Builder-buildInt64 = buildUnaligned-{-# inline buildInt64 #-}+int64 :: Int64 -> Builder+int64 = unaligned+{-# inline int64 #-} -- | A 'Builder' for 'Int'.-buildInt :: Int -> Builder-buildInt = buildUnaligned-{-# inline buildInt #-}+int :: Int -> Builder+int = unaligned+{-# inline int #-} -- | A 'Builder' for 'Char'.-buildChar :: Char -> Builder-buildChar = buildUnaligned-{-# inline buildChar #-}+char :: Char -> Builder+char = unaligned+{-# inline char #-} -- | A 'Builder' for a 'ByteArray' slice.-buildByteArray :: ()+bytearray :: () => ByteArray -- ^ source array -> Int -- ^ offset into source array -> Int -- ^ number of bytes to copy -> Builder-buildByteArray b o n = Builder (BI n (writeByteArray b o n))-{-# inline buildByteArray #-}+bytearray b o n@(I# n#) = Builder n# (writeByteArray b o n)+{-# inline bytearray #-} -- | A 'Builder' for 'Float'.-buildFloat :: Float -> Builder-buildFloat = buildUnaligned-{-# inline buildFloat #-}+float :: Float -> Builder+float = unaligned+{-# inline float #-} -- | A 'Builder' for 'Double'.-buildDouble :: Double -> Builder-buildDouble = buildUnaligned-{-# inline buildDouble #-}+double :: Double -> Builder+double = unaligned+{-# inline double #-} -- | A 'Builder' for @'Ptr' a@.-buildPtr :: Ptr a -> Builder-buildPtr = buildUnaligned-{-# inline buildPtr #-}+ptr :: Ptr a -> Builder+ptr = unaligned+{-# inline ptr #-} -- | A 'Builder' for @'Fixed' b a@ -- This provides better control over endianness when writing.-buildFixed :: (FixedOrdering b, Bytes a, Prim a, PrimUnaligned a)+fixed :: (FixedOrdering b, Bytes a, Prim a, PrimUnaligned a) => Fixed b a -> Builder-buildFixed = buildUnaligned-{-# inline buildFixed #-}+fixed = unaligned+{-# inline fixed #-}