packages feed

bytebuild 0.3.10.0 → 0.3.11.0

raw patch · 8 files changed

+132/−29 lines, 8 filesdep ~basedep ~tastyPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, tasty

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -5,6 +5,12 @@ `small-bytearray-builder` is now just a compatibility shim to ease the migration process. +## 0.3.11.0 -- 2022-04-12++* Support GHC 9.2+* Inline pragmas for better LEB encoding perf+* Bump upper bound on tasty in test suite+ ## 0.3.10.0 -- 2022-03-01  * Add upper bound on base since this does not build with GHC 9.2.
bytebuild.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.2 name: bytebuild-version: 0.3.10.0-synopsis: Serialize to a small byte arrays+version: 0.3.11.0+synopsis: Build byte arrays description:   This is similar to the builder facilities provided by   `Data.ByteString.Builder`. It is intended to be used in@@ -43,10 +43,12 @@     Data.Bytes.Builder.Bounded     Data.Bytes.Builder.Bounded.Class     Data.Bytes.Builder.Bounded.Unsafe+  other-modules:+    Compat   reexported-modules:     Data.Bytes.Chunks   build-depends:-    , base >=4.12.0.0 && <4.16+    , base >=4.12.0.0 && <4.17     , byteslice >=0.2.6 && <0.3     , bytestring >=0.10.8.2 && <0.12     , haskell-src-meta >=0.8@@ -59,6 +61,11 @@     , text-short >=0.1.3 && <0.2     , wide-word >=0.1.0.9 && <0.2     , zigzag+  if impl(ghc >= 9.2)+    hs-source-dirs: src-9.2+  else+    if impl(ghc >= 8.10)+      hs-source-dirs: src-9.0   if flag(checked)     build-depends: primitive-checked >= 0.7 && <0.8   else@@ -89,7 +96,7 @@     , quickcheck-classes >=0.6.4     , quickcheck-instances >=0.3.22     , text-short-    , tasty >=1.2.3 && <1.3+    , tasty >=1.2.3 && <1.5     , tasty-hunit >=0.10.0.2 && <0.11     , tasty-quickcheck >=0.10.1 && <0.11     , text >=1.2 && <1.3
+ src-9.0/Compat.hs view
@@ -0,0 +1,53 @@+{-# language MagicHash #-}++-- This is actually used with both GHC 8.10 and with GHC 9.0.+-- The name of the directory is a little misleading.+module Compat+  ( int8ToInt#+  , int16ToInt#+  , int32ToInt#+  , wordToWord8#+  , wordToWord16#+  , wordToWord32#+  , word8ToWord#+  , word16ToWord#+  , word32ToWord#+  ) where++import GHC.Exts (Int#,Word#)++int8ToInt# :: Int# -> Int#+{-# inline int8ToInt# #-}+int8ToInt# x = x++int16ToInt# :: Int# -> Int#+{-# inline int16ToInt# #-}+int16ToInt# x = x++int32ToInt# :: Int# -> Int#+{-# inline int32ToInt# #-}+int32ToInt# x = x++wordToWord8# :: Word# -> Word#+{-# inline wordToWord8# #-}+wordToWord8#  x = x++wordToWord16# :: Word# -> Word#+{-# inline wordToWord16# #-}+wordToWord16# x = x++wordToWord32# :: Word# -> Word#+{-# inline wordToWord32# #-}+wordToWord32# x = x++word8ToWord# :: Word# -> Word#+{-# inline word8ToWord# #-}+word8ToWord# x = x++word16ToWord# :: Word# -> Word#+{-# inline word16ToWord# #-}+word16ToWord# x = x++word32ToWord# :: Word# -> Word#+{-# inline word32ToWord# #-}+word32ToWord# x = x
+ src-9.2/Compat.hs view
@@ -0,0 +1,15 @@+{-# language MagicHash #-}++module Compat +  ( int8ToInt#+  , int16ToInt#+  , int32ToInt#+  , wordToWord8# +  , wordToWord16#+  , wordToWord32#+  , word8ToWord#+  , word16ToWord#+  , word32ToWord#+  ) where++import GHC.Exts
src/Data/Bytes/Builder.hs view
@@ -172,6 +172,8 @@ import GHC.Word (Word(W#),Word8(W8#)) import Numeric.Natural (Natural) +import qualified Compat as C+ import qualified Arithmetic.Nat as Nat import qualified Arithmetic.Types as Arithmetic import qualified Data.Bytes as Bytes@@ -1160,14 +1162,17 @@  -- | Encode a machine-sized word with LEB-128. wordLEB128 :: Word -> Builder+{-# inline wordLEB128 #-} wordLEB128 w = fromBounded Nat.constant (Bounded.wordLEB128 w)  -- | Encode a 32-bit word with LEB-128. word32LEB128 :: Word32 -> Builder+{-# inline word32LEB128 #-} word32LEB128 w = fromBounded Nat.constant (Bounded.word32LEB128 w)  -- | Encode a 64-bit word with LEB-128. word64LEB128 :: Word64 -> Builder+{-# inline word64LEB128 #-} word64LEB128 w = fromBounded Nat.constant (Bounded.word64LEB128 w)  -- | Encode a signed arbitrary-precision integer as decimal.@@ -1277,7 +1282,7 @@ --               (# sX, bufX, 0#, lenX, Mutable buf0 off0 cs0 #)  unsafeWordToWord8 :: Word -> Word8-unsafeWordToWord8 (W# w) = W8# w+unsafeWordToWord8 (W# w) = W8# (C.wordToWord8# w)  -- | This function and the documentation for it are copied from -- Takano Akio's fast-builder library.
src/Data/Bytes/Builder/Bounded.hs view
@@ -123,6 +123,8 @@ import GHC.Word (Word8(W8#),Word16(W16#),Word32(W32#),Word64(W64#)) import Data.Bytes.Types (Bytes(Bytes)) +import qualified Compat as C+ import qualified Arithmetic.Lte as Lte import qualified Arithmetic.Nat as Nat import qualified Arithmetic.Types as Arithmetic@@ -230,12 +232,12 @@ -- | Requires up to 10 bytes. Encodes an unsigned 32-bit integer as decimal. -- This encoding never starts with a zero unless the argument was zero. word32Dec :: Word32 -> Builder 10-word32Dec (W32# w) = wordCommonDec# w+word32Dec (W32# w) = wordCommonDec# (C.word32ToWord# w)  -- | Requires up to 5 bytes. Encodes an unsigned 16-bit integer as decimal. -- This encoding never starts with a zero unless the argument was zero. word16Dec :: Word16 -> Builder 5-word16Dec (W16# w) = wordCommonDec# w+word16Dec (W16# w) = wordCommonDec# (C.word16ToWord# w)  -- | Requires up to 3 bytes. Encodes an unsigned 8-bit integer as decimal. -- This encoding never starts with a zero unless the argument was zero.@@ -247,7 +249,7 @@   -- However, I (Andrew Martin) am concerned that although lookup   -- table perform very well in microbenchmarks, they can thrash   -- L1 cache in real applications.-  word8Dec# w+  word8Dec# (C.word8ToWord# w)  -- | Requires up to 19 bytes. Encodes an unsigned machine-sized integer -- as decimal. This encoding never starts with a zero unless the argument@@ -267,21 +269,21 @@ -- Negative numbers are preceded by a minus sign. Positive numbers -- are not preceded by anything. int32Dec :: Int32 -> Builder 11-int32Dec (I32# w) = intCommonDec# w+int32Dec (I32# w) = intCommonDec# (C.int32ToInt# w)  -- | Requires up to 6 bytes. Encodes a signed 16-bit integer as decimal. -- This encoding never starts with a zero unless the argument was zero. -- Negative numbers are preceded by a minus sign. Positive numbers -- are not preceded by anything. int16Dec :: Int16 -> Builder 6-int16Dec (I16# w) = intCommonDec# w+int16Dec (I16# w) = intCommonDec# (C.int16ToInt# w)  -- | Requires up to 4 bytes. Encodes a signed 8-bit integer as decimal. -- This encoding never starts with a zero unless the argument was zero. -- Negative numbers are preceded by a minus sign. Positive numbers -- are not preceded by anything. int8Dec :: Int8 -> Builder 4-int8Dec (I8# w) = intCommonDec# w+int8Dec (I8# w) = intCommonDec# (C.int8ToInt# w)  -- | Requires up to 20 bytes. Encodes a signed machine-sized integer -- as decimal. This encoding never starts with a zero unless the@@ -441,13 +443,13 @@ -- hexadecimal, zero-padding the encoding to 8 digits. This uses -- uppercase for the alphabetical digits. word32PaddedUpperHex :: Word32 -> Builder 8-word32PaddedUpperHex (W32# w) = word32PaddedUpperHex# w+word32PaddedUpperHex (W32# w) = word32PaddedUpperHex# (C.word32ToWord# w)  -- | Requires exactly 8 bytes. Encodes a 32-bit unsigned integer as -- hexadecimal, zero-padding the encoding to 8 digits. This uses -- lowercase for the alphabetical digits. word32PaddedLowerHex :: Word32 -> Builder 8-word32PaddedLowerHex (W32# w) = word32PaddedLowerHex# w+word32PaddedLowerHex (W32# w) = word32PaddedLowerHex# (C.word32ToWord# w)  -- | Requires exactly 4 bytes. Encodes a 16-bit unsigned integer as -- hexadecimal, zero-padding the encoding to 4 digits. This uses@@ -456,7 +458,7 @@ -- >>> word16PaddedUpperHex 0xab0 -- 0AB0 word16PaddedUpperHex :: Word16 -> Builder 4-word16PaddedUpperHex (W16# w) = word16PaddedUpperHex# w+word16PaddedUpperHex (W16# w) = word16PaddedUpperHex# (C.word16ToWord# w)  -- | Requires exactly 4 bytes. Encodes a 16-bit unsigned integer as -- hexadecimal, zero-padding the encoding to 4 digits. This uses@@ -465,7 +467,7 @@ -- >>> word16PaddedLowerHex 0xab0 -- 0ab0 word16PaddedLowerHex :: Word16 -> Builder 4-word16PaddedLowerHex (W16# w) = word16PaddedLowerHex# w+word16PaddedLowerHex (W16# w) = word16PaddedLowerHex# (C.word16ToWord# w)  -- | Requires at most 4 bytes. Encodes a 16-bit unsigned integer as -- hexadecimal. No leading zeroes are displayed. Letters are presented@@ -474,7 +476,7 @@ -- >>> word16LowerHex 0xab0 -- ab0 word16LowerHex :: Word16 -> Builder 4-word16LowerHex (W16# w) = word16LowerHex# w+word16LowerHex (W16# w) = word16LowerHex# (C.word16ToWord# w)  -- | Requires at most 4 bytes. Encodes a 16-bit unsigned integer as -- hexadecimal. No leading zeroes are displayed. Letters are presented@@ -483,25 +485,25 @@ -- >>> word16UpperHex 0xab0 -- AB0 word16UpperHex :: Word16 -> Builder 4-word16UpperHex (W16# w) = word16UpperHex# w+word16UpperHex (W16# w) = word16UpperHex# (C.word16ToWord# w)  -- | Requires at most 2 bytes. Encodes a 8-bit unsigned integer as -- hexadecimal. No leading zeroes are displayed. If the number is zero, -- a single zero digit is used. word8LowerHex :: Word8 -> Builder 2-word8LowerHex (W8# w) = word8LowerHex# w+word8LowerHex (W8# w) = word8LowerHex# (C.word8ToWord# w)  -- | Requires exactly 2 bytes. Encodes a 8-bit unsigned integer as -- hexadecimal, zero-padding the encoding to 2 digits. This uses -- uppercase for the alphabetical digits. word8PaddedUpperHex :: Word8 -> Builder 2-word8PaddedUpperHex (W8# w) = word8PaddedUpperHex# w+word8PaddedUpperHex (W8# w) = word8PaddedUpperHex# (C.word8ToWord# w)  -- | Requires exactly 2 bytes. Encodes a 8-bit unsigned integer as -- hexadecimal, zero-padding the encoding to 2 digits. This uses -- lowercase for the alphabetical digits. word8PaddedLowerHex :: Word8 -> Builder 2-word8PaddedLowerHex (W8# w) = word8PaddedLowerHex# w+word8PaddedLowerHex (W8# w) = word8PaddedLowerHex# (C.word8ToWord# w)  -- TODO: Is it actually worth unrolling this loop. I suspect that it -- might not be. Benchmark this.@@ -849,14 +851,17 @@  -- | Encode a machine-sized word with LEB-128. wordLEB128 :: Word -> Builder 10+{-# inline wordLEB128 #-} wordLEB128 (W# w) = lebCommon (W# w)  -- | Encode a 32-bit word with LEB-128. word32LEB128 :: Word32 -> Builder 5-word32LEB128 (W32# w) = lebCommon (W# w)+{-# inline word32LEB128 #-}+word32LEB128 (W32# w) = lebCommon (W# (C.word32ToWord# w))  -- | Encode a 64-bit word with LEB-128. word64LEB128 :: Word64 -> Builder 10+{-# inline word64LEB128 #-} word64LEB128 (W64# w) = lebCommon (W# w)  lebCommon :: Word -> Builder n@@ -933,19 +938,19 @@ int64BE (I64# i) = word64BE (W64# (int2Word# i))  int32BE :: Int32 -> Builder 4-int32BE (I32# i) = word32BE (W32# (int2Word# i))+int32BE (I32# i) = word32BE (W32# (C.wordToWord32# (int2Word# (C.int32ToInt# i))))  int16BE :: Int16 -> Builder 2-int16BE (I16# i) = word16BE (W16# (int2Word# i))+int16BE (I16# i) = word16BE (W16# (C.wordToWord16# (int2Word# (C.int16ToInt# i))))  int64LE :: Int64 -> Builder 8 int64LE (I64# i) = word64LE (W64# (int2Word# i))  int32LE :: Int32 -> Builder 4-int32LE (I32# i) = word32LE (W32# (int2Word# i))+int32LE (I32# i) = word32LE (W32# (C.wordToWord32# (int2Word# (C.int32ToInt# i))))  int16LE :: Int16 -> Builder 2-int16LE (I16# i) = word16LE (W16# (int2Word# i))+int16LE (I16# i) = word16LE (W16# (C.wordToWord16# (int2Word# (C.int16ToInt# i))))  word128LE :: Word128 -> Builder 16 word128LE (Word128 hi lo) = append (word64LE lo) (word64LE hi)@@ -1072,7 +1077,7 @@ approxDiv10 !n = unsafeShiftR (0x1999999A * n) 32  unsafeWordToWord8 :: Word -> Word8-unsafeWordToWord8 (W# w) = W8# w+unsafeWordToWord8 (W# w) = W8# (C.wordToWord8# w)  foreign import ccall unsafe "bytebuild_paste_double" c_paste_double ::   MutableByteArray# s -> Int# -> Double# -> IO Int
src/Data/Bytes/Builder/Unsafe.hs view
@@ -47,6 +47,8 @@ import GHC.ST (ST(ST)) import GHC.IO (stToIO) +import qualified Compat as C+ import qualified Data.Bytes.Builder.Bounded as Bounded import qualified Data.Bytes.Builder.Bounded.Unsafe as UnsafeBounded import qualified Data.Primitive as PM@@ -246,16 +248,16 @@  goCString :: Addr# -> MutableByteArray# s -> Int# -> Int# -> Commits s   -> State# s -> (# State# s, MutableByteArray# s, Int#, Int#, Commits s #)-goCString addr buf0 off0 len0 cs0 s0 = case Exts.indexWord8OffAddr# addr 0# of+goCString addr buf0 off0 len0 cs0 s0 = case C.word8ToWord# (Exts.indexWord8OffAddr# addr 0#) of   0## -> (# s0, buf0, off0, len0, cs0 #)   w -> case len0 of     0# -> case Exts.newByteArray# 4080# s0 of-      (# s1, buf1 #) -> case Exts.writeWord8Array# buf1 0# w s1 of+      (# s1, buf1 #) -> case Exts.writeWord8Array# buf1 0# (C.wordToWord8# w) s1 of         s2 -> goCString           (Exts.plusAddr# addr 1# ) buf1 1# (4080# -# 1# )           (Mutable buf0 off0 cs0)           s2-    _ -> case Exts.writeWord8Array# buf0 off0 w s0 of+    _ -> case Exts.writeWord8Array# buf0 off0 (C.wordToWord8# w) s0 of       s1 -> goCString (Exts.plusAddr# addr 1# ) buf0 (off0 +# 1# ) (len0 -# 1# ) cs0 s1  fromEffect ::
test/Main.hs view
@@ -255,6 +255,16 @@         runConcat 1 (naturalDec y)         ===         pack (show y)+    , testGroup "leb128-encoding"+      [ THU.testCase "16" $+          Chunks.concat (run 16 (word64LEB128 16))+          @=?+          Latin1.fromString "\x10"+      , THU.testCase "deadbeef-smile" $ do+        let inp = Latin1.fromString "\xDE\xAD\xBE\xEF"+        (Chunks.concat . run 16) (sevenEightSmile inp)+          @=?Latin1.fromString "\x6F\x2B\x37\x6E\x0F"+      ]     , testGroup "seven/eight encoding"       [ THU.testCase "deadbeef" $ do         let inp = Latin1.fromString "\xDE\xAD\xBE\xEF"