Add runByteString for bounded builders

This commit is contained in:
Andrew Martin 2020-12-18 13:26:26 -05:00
parent 57e2c7b777
commit e4ecf54aba
3 changed files with 24 additions and 3 deletions

View file

@ -5,9 +5,10 @@ Note: Prior to version 0.3.4.0, this library was named
`small-bytearray-builder` is now just a compatibility shim `small-bytearray-builder` is now just a compatibility shim
to ease the migration process. to ease the migration process.
## 0.3.7.1 -- 2020-??-?? ## 0.3.8.0 -- 2020-??-??
* Fix `doubleDec`, which was encoding small numbers incorrectly. * Fix `doubleDec`, which was encoding small numbers incorrectly.
* Add `runByteString` for producing `ByteString` from bounded builders.
## 0.3.7.0 -- 2020-11-06 ## 0.3.7.0 -- 2020-11-06

View file

@ -44,7 +44,7 @@ library
Data.Bytes.Chunks Data.Bytes.Chunks
build-depends: build-depends:
, base >=4.12.0.0 && <5 , base >=4.12.0.0 && <5
, byteslice >=0.2 && <0.3 , byteslice >=0.2.5 && <0.3
, bytestring >=0.10.8.2 && <0.11 , bytestring >=0.10.8.2 && <0.11
, integer-logarithms >=1.0.3 && <1.1 , integer-logarithms >=1.0.3 && <1.1
, natural-arithmetic >=0.1 && <0.2 , natural-arithmetic >=0.1 && <0.2

View file

@ -18,6 +18,7 @@ module Data.Bytes.Builder.Bounded
Builder Builder
-- * Execute -- * Execute
, run , run
, runByteString
, pasteGrowST , pasteGrowST
-- * Combine -- * Combine
, empty , empty
@ -104,9 +105,10 @@ module Data.Bytes.Builder.Bounded
import Arithmetic.Types (type (<=), type (:=:)) import Arithmetic.Types (type (<=), type (:=:))
import Control.Monad.Primitive (primitive_) import Control.Monad.Primitive (primitive_)
import Control.Monad.ST (ST) import Control.Monad.ST (ST)
import Control.Monad.ST.Run (runByteArrayST) import Control.Monad.ST.Run (runByteArrayST,runIntByteArrayST)
import Data.Bits import Data.Bits
import Data.Bytes.Builder.Bounded.Unsafe (Builder(..)) import Data.Bytes.Builder.Bounded.Unsafe (Builder(..))
import Data.ByteString (ByteString)
import Data.Char (ord) import Data.Char (ord)
import Data.Primitive (MutableByteArray(..),ByteArray,writeByteArray) import Data.Primitive (MutableByteArray(..),ByteArray,writeByteArray)
import Data.Primitive (readByteArray,newByteArray,unsafeFreezeByteArray) import Data.Primitive (readByteArray,newByteArray,unsafeFreezeByteArray)
@ -118,10 +120,12 @@ import GHC.IO (unsafeIOToST)
import GHC.ST (ST(ST)) import GHC.ST (ST(ST))
import GHC.TypeLits (type (+)) import GHC.TypeLits (type (+))
import GHC.Word (Word8(W8#),Word16(W16#),Word32(W32#),Word64(W64#)) import GHC.Word (Word8(W8#),Word16(W16#),Word32(W32#),Word64(W64#))
import Data.Bytes.Types (Bytes(Bytes))
import qualified Arithmetic.Lte as Lte import qualified Arithmetic.Lte as Lte
import qualified Arithmetic.Nat as Nat import qualified Arithmetic.Nat as Nat
import qualified Arithmetic.Types as Arithmetic import qualified Arithmetic.Types as Arithmetic
import qualified Data.Bytes as Bytes
import qualified Data.Bytes.Builder.Bounded.Unsafe as Unsafe import qualified Data.Bytes.Builder.Bounded.Unsafe as Unsafe
import qualified Data.Primitive as PM import qualified Data.Primitive as PM
@ -139,6 +143,22 @@ run n b = runByteArrayST $ do
shrinkMutableByteArray arr len shrinkMutableByteArray arr len
unsafeFreezeByteArray arr unsafeFreezeByteArray arr
-- | Variant of 'run' that puts the result in a pinned buffer and
-- packs it up in a 'ByteString'.
runByteString ::
Arithmetic.Nat n
-> Builder n -- ^ Builder
-> ByteString
{-# inline runByteString #-}
runByteString n b =
let (finalLen,r) = runIntByteArrayST $ do
arr <- PM.newPinnedByteArray (Nat.demote n)
len <- Unsafe.pasteST b arr 0
shrinkMutableByteArray arr len
arr' <- unsafeFreezeByteArray arr
pure (len,arr')
in Bytes.pinnedToByteString (Bytes r 0 finalLen)
-- | Paste the builder into the byte array starting at offset zero. -- | Paste the builder into the byte array starting at offset zero.
-- This reallocates the byte array if it cannot accomodate the builder, -- This reallocates the byte array if it cannot accomodate the builder,
-- growing it by the minimum amount necessary. -- growing it by the minimum amount necessary.