packages feed

byteslice 0.2.10.0 → 0.2.11.0

raw patch · 7 files changed

+202/−6 lines, 7 filesdep +natural-arithmetic

Dependencies added: natural-arithmetic

Files

CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for byteslice +## 0.2.11.0 -- 2023-07-25++* Add `Data.Bytes.Encode.LittleEndian`.+* Add `splitTetragram1`.+ ## 0.2.10.0 -- 2023-05-01  * Add `equals13`, `equals14`, `equals15`.
byteslice.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: byteslice-version: 0.2.10.0+version: 0.2.11.0 synopsis: Slicing managed and unmanaged memory description:   This library provides types that allow the user to talk about a slice of@@ -26,6 +26,7 @@     Data.Bytes     Data.Bytes.Chunks     Data.Bytes.Encode.BigEndian+    Data.Bytes.Encode.LittleEndian     Data.Bytes.Internal     Data.Bytes.Mutable     Data.Bytes.Text.Ascii@@ -45,9 +46,10 @@   build-depends:     , base >=4.14 && <5     , bytestring >=0.10.8 && <0.12+    , natural-arithmetic >=0.1.4     , primitive >=0.7.4 && <0.10-    , primitive-unlifted >=0.1.2 && <0.2     , primitive-addr >=0.1 && <0.2+    , primitive-unlifted >=0.1.2 && <2.2     , run-st >=0.1.1 && <0.2     , text >=1.2.5     , text-short >=0.1.3 && <0.2
src/Data/Bytes.hs view
@@ -1,6 +1,7 @@ {-# language BangPatterns #-} {-# language BlockArguments #-} {-# language DuplicateRecordFields #-}+{-# language KindSignatures #-} {-# language MagicHash #-} {-# language NamedFieldPuns #-} {-# language RankNTypes #-}@@ -72,6 +73,7 @@   , Byte.splitStream     -- ** Fixed from Beginning   , Byte.split1+  , splitTetragram1   , Byte.split2   , Byte.split3   , Byte.split4@@ -85,6 +87,7 @@     -- * Searching   , replace   , findIndices+  , findTetragramIndex     -- * Counting   , Byte.count     -- * Prefix and Suffix@@ -158,6 +161,9 @@     -- * Unlifted Types   , lift   , unlift+    -- * Length Indexed+  , withLength+  , withLengthU   ) where  import Prelude hiding (length,takeWhile,dropWhile,null,foldl,foldr,elem,replicate,any,all,readFile,map)@@ -165,20 +171,24 @@ import Control.Monad.Primitive (PrimMonad,primitive_,unsafeIOToPrim) import Control.Monad.ST.Run (runByteArrayST) import Cstrlen (cstringLength#)+import Data.Bits (unsafeShiftL,(.|.)) import Data.ByteString.Short.Internal (ShortByteString(SBS)) import Data.Bytes.Pure (length,fromByteArray,foldr,unsafeDrop) import Data.Bytes.Pure (unsafeIndex,toShortByteString)-import Data.Bytes.Types (Bytes(Bytes,array,offset))+import Data.Bytes.Types (Bytes(Bytes,array,offset),BytesN(BytesN))+import Data.Bytes.Types (ByteArrayN(ByteArrayN)) import Data.Primitive (Array,ByteArray(ByteArray)) import Data.Text.Short (ShortText) import Foreign.C.String (CString) import Foreign.Ptr (Ptr,plusPtr,castPtr) import GHC.Exts (Addr#,Word#,Int#) import GHC.Exts (Int(I#),Ptr(Ptr))-import GHC.Word (Word8(W8#))+import GHC.Word (Word8(W8#),Word32) import Reps (Bytes#(..),word8ToWord#) import Data.Bytes.Search (findIndices,replace,isInfixOf) +import qualified Arithmetic.Nat as Nat+import qualified Arithmetic.Types as Arithmetic import qualified Data.Bytes.Byte as Byte import qualified Data.Bytes.Chunks as Chunks import qualified Data.Bytes.IO as BIO@@ -193,6 +203,7 @@ import qualified Data.Primitive.Ptr as PM import qualified Data.Text.Short as TS import qualified GHC.Exts as Exts+import qualified GHC.TypeNats as GHC  -- | Extract the head and tail of the 'Bytes', returning 'Nothing' if -- it is empty.@@ -671,3 +682,76 @@ concatArray :: Array Bytes -> Bytes {-# inline concatArray #-} concatArray !xs = Pure.fromByteArray (concatArrayU xs)++-- | Convert 'Bytes' to 'BytesN', exposing the length in a type-safe+-- way in the callback.+withLength ::+     Bytes+  -> (forall (n :: GHC.Nat). Arithmetic.Nat n -> BytesN n -> a)+  -> a+{-# inline withLength #-}+withLength Bytes{array,offset,length=len} f = Nat.with+  len+  (\n -> f n BytesN{array,offset})++withLengthU ::+     ByteArray+  -> (forall (n :: GHC.Nat). Arithmetic.Nat n -> ByteArrayN n -> a)+  -> a+{-# inline withLengthU #-}+withLengthU !arr f = Nat.with+  (PM.sizeofByteArray arr)+  (\n -> f n (ByteArrayN arr))++findTetragramIndex ::+     Word8+  -> Word8+  -> Word8+  -> Word8+  -> Bytes+  -> Maybe Int+findTetragramIndex !w0 !w1 !w2 !w3 (Bytes arr off len) = if len < 4+  then Nothing+  else+    let !target = +          unsafeShiftL (fromIntegral w0 :: Word32) 24+          .|.+          unsafeShiftL (fromIntegral w1 :: Word32) 16+          .|.+          unsafeShiftL (fromIntegral w2 :: Word32) 8+          .|.+          unsafeShiftL (fromIntegral w3 :: Word32) 0+        !end = off + len+        go !ix !acc = if acc == target+          then+            let n = ix - off+             in Just (n - 4)+          else if ix < end+            then+              let !w = PM.indexByteArray arr ix :: Word8+                  acc' =+                    (fromIntegral w :: Word32)+                    .|.+                    unsafeShiftL acc 8+               in go (ix + 1) acc'+            else Nothing+        !acc0 =+          unsafeShiftL (fromIntegral (PM.indexByteArray arr 0 :: Word8) :: Word32) 24+          .|.+          unsafeShiftL (fromIntegral (PM.indexByteArray arr 1 :: Word8) :: Word32) 16+          .|.+          unsafeShiftL (fromIntegral (PM.indexByteArray arr 2 :: Word8) :: Word32) 8+          .|.+          unsafeShiftL (fromIntegral (PM.indexByteArray arr 3 :: Word8) :: Word32) 0+     in go 4 acc0++splitTetragram1 ::+     Word8+  -> Word8+  -> Word8+  -> Word8+  -> Bytes+  -> Maybe (Bytes,Bytes)+splitTetragram1 !w0 !w1 !w2 !w3 !b = case findTetragramIndex w0 w1 w2 w3 b of+  Nothing -> Nothing+  Just n -> Just (Pure.unsafeTake n b, Pure.unsafeDrop (n + 4) b)
src/Data/Bytes/Chunks.hs view
@@ -47,7 +47,7 @@   , writeFile   ) where -import Prelude hiding (length,concat,reverse,readFile,writeFile,null)+import Prelude hiding (Foldable(..),concat,reverse,readFile,writeFile)  import Control.Exception (IOException,catch) import Control.Monad.ST.Run (runIntByteArrayST)
+ src/Data/Bytes/Encode/LittleEndian.hs view
@@ -0,0 +1,77 @@+{-# language BangPatterns #-}+{-# language TypeApplications #-}++module Data.Bytes.Encode.LittleEndian+  ( word16+  , word32+  , word64+  , int16+  , int32+  , int64+  ) where++import Control.Monad.ST.Run (runByteArrayST)+import Data.Bits (unsafeShiftR)+import Data.Bytes.Types (Bytes)+import Data.Int (Int16,Int32,Int64)+import Data.Primitive (ByteArray)+import Data.Word (Word8,Word16,Word32,Word64)++import qualified Data.Bytes.Pure as Pure+import qualified Data.Primitive as PM++-- | Encode a 32-bit signed integer as 4 bytes.+int32 :: Int32 -> Bytes+{-# inline int32 #-}+int32 = word32 . fromIntegral @Int32 @Word32 ++-- | Encode a 32-bit unsigned integer as 4 bytes.+word32 :: Word32 -> Bytes+word32 !w = Pure.fromByteArray (word32U w)++word32U :: Word32 -> ByteArray+word32U !w = runByteArrayST $ do+  arr <- PM.newByteArray 4+  PM.writeByteArray arr 3 (fromIntegral @Word32 @Word8 (unsafeShiftR w 24))+  PM.writeByteArray arr 2 (fromIntegral @Word32 @Word8 (unsafeShiftR w 16))+  PM.writeByteArray arr 1 (fromIntegral @Word32 @Word8 (unsafeShiftR w 8))+  PM.writeByteArray arr 0 (fromIntegral @Word32 @Word8 w)+  PM.unsafeFreezeByteArray arr++-- | Encode a 16-bit signed integer as 4 bytes.+int16 :: Int16 -> Bytes+{-# inline int16 #-}+int16 = word16 . fromIntegral @Int16 @Word16 ++-- | Encode a 16-bit unsigned integer as 4 bytes.+word16 :: Word16 -> Bytes+word16 !w = Pure.fromByteArray (word16U w)++word16U :: Word16 -> ByteArray+word16U !w = runByteArrayST $ do+  arr <- PM.newByteArray 2+  PM.writeByteArray arr 1 (fromIntegral @Word16 @Word8 (unsafeShiftR w 8))+  PM.writeByteArray arr 0 (fromIntegral @Word16 @Word8 w)+  PM.unsafeFreezeByteArray arr++-- | Encode a 16-bit signed integer as 4 bytes.+int64 :: Int64 -> Bytes+{-# inline int64 #-}+int64 = word64 . fromIntegral @Int64 @Word64 ++-- | Encode a 16-bit unsigned integer as 4 bytes.+word64 :: Word64 -> Bytes+word64 !w = Pure.fromByteArray (word64U w)++word64U :: Word64 -> ByteArray+word64U !w = runByteArrayST $ do+  arr <- PM.newByteArray 8+  PM.writeByteArray arr 7 (fromIntegral @Word64 @Word8 (unsafeShiftR w 56))+  PM.writeByteArray arr 6 (fromIntegral @Word64 @Word8 (unsafeShiftR w 48))+  PM.writeByteArray arr 5 (fromIntegral @Word64 @Word8 (unsafeShiftR w 40))+  PM.writeByteArray arr 4 (fromIntegral @Word64 @Word8 (unsafeShiftR w 32))+  PM.writeByteArray arr 3 (fromIntegral @Word64 @Word8 (unsafeShiftR w 24))+  PM.writeByteArray arr 2 (fromIntegral @Word64 @Word8 (unsafeShiftR w 16))+  PM.writeByteArray arr 1 (fromIntegral @Word64 @Word8 (unsafeShiftR w 8))+  PM.writeByteArray arr 0 (fromIntegral @Word64 @Word8 w)+  PM.unsafeFreezeByteArray arr
src/Data/Bytes/Pure.hs view
@@ -41,7 +41,7 @@   , toShortByteString   ) where -import Prelude hiding (length,foldl,foldr,map,null)+import Prelude hiding (Foldable(..),map)  import Control.Monad.Primitive (PrimState,PrimMonad) import Control.Monad.ST.Run (runByteArrayST)
test/Main.hs view
@@ -265,6 +265,34 @@           Nothing -> property False           Just (y2,z2) -> (y1,z1) === (bytesToByteString y2, bytesToByteString z2)         _ -> property Discard+  , testProperty "splitTetragram1A" $ \(w0 :: Word8) (w1 :: Word8) (w2 :: Word8) (w3 :: Word8) (xs :: [Word8]) ->+      (w0 /= 0xEF && w1 /= 0xEF && w2 /= 0xEF && w3 /= 0xEF)+      ==>+      case Bytes.splitTetragram1 w0 w1 w2 w3 (slicedPack (0xEF : w0 : w1 : w2 : w3 : xs)) of+        Nothing -> property False+        Just (pre,post) ->+          (pre,post) === (Exts.fromList [0xEF], Exts.fromList xs) +  , testProperty "splitTetragram1B" $ \(w0 :: Word8) (w1 :: Word8) (w2 :: Word8) (w3 :: Word8) (xs :: [Word8]) ->+      (w0 /= 0xEF && w1 /= 0xEF && w2 /= 0xEF && w3 /= 0xEF)+      ==>+      case Bytes.splitTetragram1 w0 w1 w2 w3 (slicedPack (0xEF : 0xEF : 0xEF : 0xEF : w0 : w1 : w2 : w3 : xs)) of+        Nothing -> property False+        Just (pre,post) ->+          (pre,post) === (Exts.fromList (List.replicate 4 0xEF), Exts.fromList xs) +  , testProperty "splitTetragram1C" $ \(w0 :: Word8) (w1 :: Word8) (w2 :: Word8) (xs :: [Word8]) ->+      (w0 /= 0xEF && w1 /= 0xEF && w2 /= 0xEF)+      ==>+      case Bytes.splitTetragram1 w0 w1 w2 0xEF (slicedPack (xs ++ [w0, w1, w2, 0xEF])) of+        Nothing -> property False+        Just (pre,post) ->+          (pre,post) === (Exts.fromList xs, mempty)+  , testProperty "splitTetragram1D" $ \(w0 :: Word8) (w1 :: Word8) (w2 :: Word8) (xs :: [Word8]) ->+      (w0 /= 0xEF && w1 /= 0xEF && w2 /= 0xEF)+      ==>+      case Bytes.splitTetragram1 w0 w1 w2 0xEF (slicedPack (xs ++ [w0, w1, w2, 0xEF, 0xEF])) of+        Nothing -> property False+        Just (pre,post) ->+          (pre,post) === (Exts.fromList xs, Exts.fromList [0xEF])   , testProperty "split2" $ \(xs :: [Word8]) (ys :: [Word8]) (zs :: [Word8]) ->       (all (/=0xEF) xs && all (/=0xEF) ys && all (/=0xEF) zs)       ==>