packages feed

builder (empty) → 0.1

raw patch · 5 files changed

+315/−0 lines, 5 filesdep +basedep +byte-orderdep +primitive

Dependencies added: base, byte-order, primitive, primitive-unaligned

Files

+ CHANGELOG.md view
@@ -0,0 +1,12 @@+# Changelog++`builder` uses [PVP Versioning][1].+The changelog is available [on GitHub][2].++0.0.0+=====++* Initially created.++[1]: https://pvp.haskell.org+[2]: https://github.com/chessai/builder/releases
+ LICENSE view
@@ -0,0 +1,29 @@+BSD 3-Clause License++Copyright (c) 2019, chessai+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this+   list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice,+   this list of conditions and the following disclaimer in the documentation+   and/or other materials provided with the distribution.++3. Neither the name of the copyright holder nor the names of its+   contributors may be used to endorse or promote products derived from+   this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,7 @@+# builder++[![Hackage](https://img.shields.io/hackage/v/builder.svg)](https://hackage.haskell.org/package/builder)+[![BSD3 license](https://img.shields.io/badge/license-BSD3-blue.svg)](LICENSE)+[![Build status](https://secure.travis-ci.org/chessai/builder.svg)](https://travis-ci.org/chessai/builder)++bounded bytearray builder type
+ builder.cabal view
@@ -0,0 +1,56 @@+cabal-version: 2.2+name:+  builder+version:+  0.1+synopsis:+  bounded ByteArray builder type+description:+  A Builder type for ByteArray. Appending these builders+  can be cheaper than when appending ByteArray values, since+  only one buffer allocation is performed.+homepage:+  https://github.com/chessai/builder+bug-reports:+  https://github.com/chessai/builder/issues+license:+  BSD-3-Clause+license-file:+  LICENSE+author:+  chessai+maintainer:+  chessai <chessai1996@gmail.com>+copyright:+  © 2019 chessai+category:+  Data+build-type:+  Simple+extra-doc-files:+    README.md+  , CHANGELOG.md+tested-with:+  GHC == 8.6.5++library+  hs-source-dirs:+    src+  exposed-modules:+    Builder+  build-depends:+    , base >= 4.11 && < 4.14+    , byte-order >= 0.1.1 && < 0.2+    , primitive >= 0.6.4 && < 0.8+    , primitive-unaligned >= 0.1 && < 0.2+  ghc-options:+    -Wall+    -O2+  default-language:+    Haskell2010++source-repository head+  type:+    git+  location:+    https://github.com/chessai/builder.git
+ src/Builder.hs view
@@ -0,0 +1,211 @@+{-# language+    BangPatterns+  , MagicHash+  , RankNTypes+  , UnboxedTuples+  #-}++-- | A 'Builder' type for 'ByteArray'. Appending these builders+--   can be cheaper than when appending 'ByteArray' values, since+--   you only perform one buffer allocation.+module Builder+  ( -- * Builder type+    Builder++    -- * Consumption+  , build++    -- * Construction+  , buildUnaligned+  , buildWord8+  , buildWord16+  , buildWord32+  , buildWord64+  , buildWord+  , buildInt8+  , buildInt16+  , buildInt32+  , buildInt64+  , buildInt+  , buildFloat+  , buildDouble+  , buildChar+  , buildPtr+  , buildByteArray+  , buildFixed+  ) where++import Data.Primitive hiding (writeByteArray)+import Data.Primitive.ByteArray.Unaligned+import Data.Int+import Data.Word+import GHC.Exts hiding (build)+import System.ByteOrder++newtype Writer s = W+  { _w :: ()+      => 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 (<>) #-}++instance Monoid Builder where+  mempty = Builder mempty+  {-# inline mempty #-}++runWriter# :: Int# -> Writer s -> State# s -> (# State# s, ByteArray# #)+runWriter# sz# (W 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# #)+{-# inline runWriter# #-}++-- | Convert a 'Builder' into a 'ByteArray'.+build :: Builder -> ByteArray+build (Builder (BI (I# 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# ->+  case writeUnalignedByteArray# marr# ix0# a s0# of+    s1# -> (# s1#, ix0# +# alignment# a #)+{-# inline writeUnaligned #-}++writeByteArray :: ()+  => ByteArray+  -> Int+  -> Int+  -> Writer s+writeByteArray (ByteArray src#) (I# off#) (I# len#)+  = W $ \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)+  => a+  -> Builder+buildUnaligned a = Builder (BI (sizeOf a) (writeUnaligned a))+{-# inline buildUnaligned #-}++-- | A 'Builder' for 'Word8'.+buildWord8 :: Word8 -> Builder+buildWord8 = buildUnaligned+{-# inline buildWord8 #-}++-- | A 'Builder' for 'Word16'.+buildWord16 :: Word16 -> Builder+buildWord16 = buildUnaligned+{-# inline buildWord16 #-}++-- | A 'Builder' for 'Word32'.+buildWord32 :: Word32 -> Builder+buildWord32 = buildUnaligned+{-# inline buildWord32 #-}++-- | A 'Builder' for 'Word64'.+buildWord64 :: Word64 -> Builder+buildWord64 = buildUnaligned+{-# inline buildWord64 #-}++-- | A 'Builder' for 'Word'.+buildWord :: Word -> Builder+buildWord = buildUnaligned+{-# inline buildWord #-}++-- | A 'Builder' for 'Int8'.+buildInt8 :: Int8 -> Builder+buildInt8 = buildUnaligned+{-# inline buildInt8 #-}++-- | A 'Builder' for 'Int16'.+buildInt16 :: Int16 -> Builder+buildInt16 = buildUnaligned+{-# inline buildInt16 #-}++-- | A 'Builder' for 'Int32'.+buildInt32 :: Int32 -> Builder+buildInt32 = buildUnaligned+{-# inline buildInt32 #-}++-- | A 'Builder' for 'Int64'.+buildInt64 :: Int64 -> Builder+buildInt64 = buildUnaligned+{-# inline buildInt64 #-}++-- | A 'Builder' for 'Int'.+buildInt :: Int -> Builder+buildInt = buildUnaligned+{-# inline buildInt #-}++-- | A 'Builder' for 'Char'.+buildChar :: Char -> Builder+buildChar = buildUnaligned+{-# inline buildChar #-}++-- | A 'Builder' for a 'ByteArray' slice.+buildByteArray :: ()+  => 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 #-}++-- | A 'Builder' for 'Float'.+buildFloat :: Float -> Builder+buildFloat = buildUnaligned+{-# inline buildFloat #-}++-- | A 'Builder' for 'Double'.+buildDouble :: Double -> Builder+buildDouble = buildUnaligned+{-# inline buildDouble #-}++-- | A 'Builder' for @'Ptr' a@.+buildPtr :: Ptr a -> Builder+buildPtr = buildUnaligned+{-# inline buildPtr #-}++-- | A 'Builder' for @'Fixed' b a@+--   This provides better control over endianness when writing.+buildFixed :: (FixedOrdering b, Bytes a, Prim a, PrimUnaligned a)+  => Fixed b a+  -> Builder+buildFixed = buildUnaligned+{-# inline buildFixed #-}