byteslice 0.2.5.0 → 0.2.5.1
raw patch · 8 files changed
+48/−28 lines, 8 files
Files
- CHANGELOG.md +4/−0
- byteslice.cabal +1/−2
- src-no-unlifted-newtypes/UnliftedBytes.hs +8/−1
- src-unlifted-newtypes/UnliftedBytes.hs +3/−0
- src/Data/Bytes.hs +16/−1
- src/Data/Bytes/Chunks.hs +6/−4
- src/Data/Bytes/Compat.hs +0/−16
- src/Data/Bytes/Pure.hs +10/−4
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for byteslice +## 0.2.5.1 -- 2021-02-22++* Compatibility with GHC 9.0.+ ## 0.2.5.0 -- 2021-01-22 * Add `Data.Bytes.Chunks.concatByteString`.
byteslice.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: byteslice-version: 0.2.5.0+version: 0.2.5.1 synopsis: Slicing managed and unmanaged memory description: This library provides types that allow the user to talk about a slice of@@ -28,7 +28,6 @@ Data.Bytes.Mutable Data.Bytes.Types other-modules:- Data.Bytes.Compat Data.Bytes.Byte Data.Bytes.Pure Data.Bytes.IO
src-no-unlifted-newtypes/UnliftedBytes.hs view
@@ -2,13 +2,20 @@ {-# language TypeFamilies #-} {-# language TypeInType #-} {-# language UndecidableInstances #-}+{-# language UnliftedFFITypes #-} module UnliftedBytes ( Bytes#+ , cstringLength# ) where import GHC.TypeLits-import GHC.Exts (RuntimeRep(..),TYPE)+import GHC.Exts (Addr#,Int#,RuntimeRep(..),TYPE) type family Bytes# :: TYPE ('TupleRep '[ 'UnliftedRep,'IntRep,'IntRep]) where Bytes# = TypeError ('Text "Bytes# not available before GHC 8.10")++foreign import ccall unsafe "strlen" c_strlen :: Addr# -> Int#++cstringLength# :: Addr# -> Int#+cstringLength# = c_strlen
src-unlifted-newtypes/UnliftedBytes.hs view
@@ -7,9 +7,12 @@ module UnliftedBytes ( Bytes#(..)+ , cstringLength# ) where import GHC.Exts (ByteArray#,Int#,RuntimeRep(..),TYPE)+import GHC.Exts (cstringLength#) newtype Bytes# :: TYPE ('TupleRep '[ 'UnliftedRep,'IntRep,'IntRep]) where Bytes# :: (# ByteArray#, Int#, Int# #) -> Bytes#+
src/Data/Bytes.hs view
@@ -141,7 +141,6 @@ import Control.Monad.ST.Run (runByteArrayST) import Data.ByteString (ByteString) import Data.ByteString.Short.Internal (ShortByteString(SBS))-import Data.Bytes.Compat (cstringLength#) import Data.Bytes.Pure (length,fromByteArray) import Data.Bytes.Types (Bytes(Bytes,array,offset)) import Data.Char (ord)@@ -152,6 +151,7 @@ import GHC.Exts (Addr#,Word#,Int#) import GHC.IO (unsafeIOToST) import GHC.Word (Word8(W8#))+import UnliftedBytes (cstringLength#) import qualified Data.ByteString as ByteString import qualified Data.ByteString.Unsafe as ByteString@@ -168,11 +168,13 @@ -- | Is the byte sequence empty? null :: Bytes -> Bool+{-# inline null #-} null (Bytes _ _ len) = len == 0 -- | Extract the head and tail of the 'Bytes', returning 'Nothing' if -- it is empty. uncons :: Bytes -> Maybe (Word8, Bytes)+{-# inline uncons #-} uncons b = case length b of 0 -> Nothing _ -> Just (unsafeIndex b 0, unsafeDrop 1 b)@@ -180,6 +182,7 @@ -- | Extract the @init@ and @last@ of the 'Bytes', returning 'Nothing' if -- it is empty. unsnoc :: Bytes -> Maybe (Bytes, Word8)+{-# inline unsnoc #-} unsnoc b@(Bytes arr off len) = case len of 0 -> Nothing _ -> let !len' = len - 1 in@@ -188,6 +191,7 @@ -- | Does the byte sequence begin with the given byte? False if the -- byte sequence is empty. isBytePrefixOf :: Word8 -> Bytes -> Bool+{-# inline isBytePrefixOf #-} isBytePrefixOf w b = case length b of 0 -> False _ -> unsafeIndex b 0 == w@@ -234,18 +238,22 @@ -- | Create a byte sequence with one byte. singleton :: Word8 -> Bytes+{-# inline singleton #-} singleton !a = Bytes (singletonU a) 0 1 -- | Create a byte sequence with two bytes. doubleton :: Word8 -> Word8 -> Bytes+{-# inline doubleton #-} doubleton !a !b = Bytes (doubletonU a b) 0 2 -- | Create a byte sequence with three bytes. tripleton :: Word8 -> Word8 -> Word8 -> Bytes+{-# inline tripleton #-} tripleton !a !b !c = Bytes (tripletonU a b c) 0 3 -- | Create an unsliced byte sequence with one byte. singletonU :: Word8 -> ByteArray+{-# inline singletonU #-} singletonU !a = runByteArrayST do arr <- PM.newByteArray 1 PM.writeByteArray arr 0 a@@ -253,6 +261,7 @@ -- | Create an unsliced byte sequence with two bytes. doubletonU :: Word8 -> Word8 -> ByteArray+{-# inline doubletonU #-} doubletonU !a !b = runByteArrayST do arr <- PM.newByteArray 2 PM.writeByteArray arr 0 a@@ -261,6 +270,7 @@ -- | Create an unsliced byte sequence with three bytes. tripletonU :: Word8 -> Word8 -> Word8 -> ByteArray+{-# inline tripletonU #-} tripletonU !a !b !c = runByteArrayST do arr <- PM.newByteArray 3 PM.writeByteArray arr 0 a@@ -336,6 +346,7 @@ -- | Index into the byte sequence at the given position. This index -- must be less than the length. unsafeIndex :: Bytes -> Int -> Word8+{-# inline unsafeIndex #-} unsafeIndex (Bytes arr off _) ix = PM.indexByteArray arr (off + ix) -- | /O(n)/ 'dropWhileEnd' @p@ @b@ returns the prefix remaining after@@ -465,6 +476,7 @@ -- | Is the byte sequence, when interpreted as ISO-8859-1-encoded text, -- a singleton whose element matches the character? equalsLatin1 :: Char -> Bytes -> Bool+{-# inline equalsLatin1 #-} equalsLatin1 !c0 (Bytes arr off len) = case len of 1 -> c0 == indexCharArray arr off _ -> False@@ -706,6 +718,7 @@ -- reuses the array backing the sliced 'Bytes' if the slicing metadata -- implies that all of the bytes are used. Otherwise, it makes a copy. toShortByteString :: Bytes -> ShortByteString+{-# inline toShortByteString #-} toShortByteString !b = case Pure.toByteArray b of PM.ByteArray x -> SBS x @@ -713,11 +726,13 @@ -- the array backing the sliced 'Bytes' even if the original array -- could be reused. Prefer 'toShortByteString'. toShortByteStringClone :: Bytes -> ShortByteString+{-# inline toShortByteStringClone #-} toShortByteStringClone !b = case Pure.toByteArrayClone b of PM.ByteArray x -> SBS x -- | /O(1)/ Create 'Bytes' from a 'ShortByteString'. fromShortByteString :: ShortByteString -> Bytes+{-# inline fromShortByteString #-} fromShortByteString (SBS x) = fromByteArray (ByteArray x) -- | /O(n)/ Interpreting the bytes an ASCII-encoded characters, convert
src/Data/Bytes/Chunks.hs view
@@ -208,9 +208,11 @@ reverseOnto (ChunksCons y x) ys unI :: Int -> Int#+{-# inline unI #-} unI (I# i) = i unBa :: ByteArray -> ByteArray#+{-# inline unBa #-} unBa (ByteArray x) = x -- | Read a handle's entire contents strictly into chunks.@@ -277,15 +279,15 @@ -- | Hash byte sequence with 32-bit variant of FNV-1a. fnv1a32 :: Chunks -> Word32-fnv1a32 = foldl'+fnv1a32 !b = foldl' (\acc w -> (fromIntegral @Word8 @Word32 w `xor` acc) * 0x01000193- ) 0x811c9dc5+ ) 0x811c9dc5 b -- | Hash byte sequence with 64-bit variant of FNV-1a. fnv1a64 :: Chunks -> Word64-fnv1a64 = foldl'+fnv1a64 !b = foldl' (\acc w -> (fromIntegral @Word8 @Word64 w `xor` acc) * 0x00000100000001B3- ) 0xcbf29ce484222325+ ) 0xcbf29ce484222325 b -- | Outputs 'Chunks' to the specified 'Handle'. This is implemented -- with 'hPutBuf'.
− src/Data/Bytes/Compat.hs
@@ -1,16 +0,0 @@-{-# language MagicHash #-}-{-# language UnliftedFFITypes #-}--module Data.Bytes.Compat- ( cstringLength#- ) where--import GHC.Exts---- GHC 8.12 comes with a known-key implementation of strlen that supports--- constant folding. Here we define a shim for older GHCs.--foreign import ccall unsafe "strlen" c_strlen :: Addr# -> Int#--cstringLength# :: Addr# -> Int#-cstringLength# = c_strlen
src/Data/Bytes/Pure.hs view
@@ -75,6 +75,7 @@ -- reuses the array backing the sliced 'Bytes' if the slicing metadata -- implies that all of the bytes are used. Otherwise, it makes a copy. toByteArray :: Bytes -> ByteArray+{-# inline toByteArray #-} toByteArray b@(Bytes arr off len) | off == 0, PM.sizeofByteArray arr == len = arr | otherwise = toByteArrayClone b@@ -83,6 +84,7 @@ -- the array backing the sliced 'Bytes' even if the original array -- could be reused. Prefer 'toByteArray'. toByteArrayClone :: Bytes -> ByteArray+{-# inline toByteArrayClone #-} toByteArrayClone (Bytes arr off len) = runByteArrayST $ do m <- PM.newByteArray len PM.copyByteArray m 0 arr off len@@ -102,23 +104,25 @@ -- | Create a slice of 'Bytes' that spans the entire argument array. fromByteArray :: ByteArray -> Bytes+{-# inline fromByteArray #-} fromByteArray b = Bytes b 0 (PM.sizeofByteArray b) -- | The length of a slice of bytes. length :: Bytes -> Int+{-# inline length #-} length (Bytes _ _ len) = len -- | Hash byte sequence with 32-bit variant of FNV-1a. fnv1a32 :: Bytes -> Word32-fnv1a32 = foldl'+fnv1a32 !b = foldl' (\acc w -> (fromIntegral @Word8 @Word32 w `xor` acc) * 0x01000193- ) 0x811c9dc5+ ) 0x811c9dc5 b -- | Hash byte sequence with 64-bit variant of FNV-1a. fnv1a64 :: Bytes -> Word64-fnv1a64 = foldl'+fnv1a64 !b = foldl' (\acc w -> (fromIntegral @Word8 @Word64 w `xor` acc) * 0x00000100000001B3- ) 0xcbf29ce484222325+ ) 0xcbf29ce484222325 b -- | Left fold over bytes, strict in the accumulator. foldl' :: (a -> Word8 -> a) -> a -> Bytes -> a@@ -131,6 +135,7 @@ -- | Yields a pointer to the beginning of the byte sequence. It is only safe -- to call this on a 'Bytes' backed by a pinned @ByteArray@. contents :: Bytes -> Ptr Word8+{-# inline contents #-} contents (Bytes arr off _) = plusPtr (PM.byteArrayContents arr) off -- | Convert the sliced 'Bytes' to an unsliced 'ByteArray'. This@@ -138,6 +143,7 @@ -- implies that all of the bytes are used and they are already pinned. -- Otherwise, it makes a copy. toPinnedByteArray :: Bytes -> ByteArray+{-# inline toPinnedByteArray #-} toPinnedByteArray b@(Bytes arr off len) | off == 0, PM.sizeofByteArray arr == len, PM.isByteArrayPinned arr = arr | otherwise = toPinnedByteArrayClone b