packages feed

ram 0.20.1 → 0.22.1

raw patch · 11 files changed

Files

CHANGELOG.md view
@@ -1,3 +1,45 @@+## 0.22.1++ Use correct signatures for 'memset' and 'memcpy'+The WASM linker is more strict about function signatures matching, see https://releases.llvm.org/11.1.0/tools/lld/docs/WebAssembly.html#function-signatures++thanks @clinton-grc++## 0.22.0++ Added `slice :: ByteArray bs => bs -> Int -> Int -> Maybe bs`+  and `unsafeSlice :: ByteArray bs => bs -> Int -> Int -> bs`+  to `Data.ByteArray.Methods` (re-exported via `Data.ByteArray`).+  `slice bs offset len` extracts `len` bytes starting at `offset`.+  Returns `Nothing` for negative offset/length or out-of-bounds access.+  `unsafeSlice` calls `error` on invalid arguments. (closes #7)++ Added `map :: (ByteArrayAccess ba, ByteArray ba) => (Word8 -> Word8) -> ba -> ba`+  to `Data.ByteArray.Methods` (re-exported via `Data.ByteArray`).+  Applies a function to each byte of a byte array. (closes #5)++## 0.21.1++ Reverted 0.21.0 changes: restored custom Base16/Base32/Base64 encode/decode,+  the GHC.Prim-based `Bytes` implementation, and `readWord8OffAddr#`-based FNV+  hashing. The `base16`, `base32`, `base64`, and `text` dependencies are removed+  again.++ Deleted `Data.Memory.Internal.CompatPrim64` (unreferenced).++ Added GitHub Actions CI (nix + cabal matrix).++## 0.21.0+++ `Data.ByteArray.Encoding`: replaced custom Base16/Base32/Base64 encode/decode+  with `base16`, `base32`, and `base64` library calls. Input is converted to+  `ByteString` via `B.convert`, the library function is applied, and the result+  is converted back. `Base64OpenBSD` retains its custom implementation (no+  library equivalent exists).++ `Data.ByteArray.Bytes`: replaced low-level `GHC.Prim` `MutableByteArray#`+  implementation with `newtype Bytes = Bytes ByteString`. Both use GHC's pinned+  allocator; `ByteString` already implements `ByteArrayAccess` / `ByteArray`.++ `Data.Memory.Hash.FNV`: replaced `readWord8OffAddr#` (GHC.Prim) with+  `Foreign.Storable.peekByteOff` — portable and equivalent.++ `Data.Memory.Internal.CompatPrim64`: deleted (was entirely unreferenced).++ New dependencies: `base16 >=1.0 && <2`, `base32 >=0.4 && <1`,+  `base64 >=1.0 && <2`, `text >=1.0 && <3`.++ Net reduction: ~350 lines removed.+ ## 0.20.1 + Remove `WITH_BYTESTRING_SUPPORT` CPP flag. `ByteString` instances for   `ByteArrayAccess` and `ByteArray` are now always compiled in, since
Data/ByteArray/Bytes.hs view
@@ -25,7 +25,6 @@ import           Data.Semigroup import           Data.Foldable (toList) import           Data.Memory.PtrMethods-import           Data.Memory.Internal.Imports import           Data.Memory.Internal.CompatPrim import           Data.Memory.Internal.Compat      (unsafeDoIO) import           Data.ByteArray.Types
Data/ByteArray/Methods.hs view
@@ -39,6 +39,9 @@     , all     , append     , concat+    , map+    , slice+    , unsafeSlice     ) where  import           Data.ByteArray.Types@@ -49,7 +52,7 @@ import           Foreign.Storable import           Foreign.Ptr -import           Prelude hiding (length, take, drop, span, reverse, concat, replicate, splitAt, null, pred, last, any, all)+import           Prelude hiding (length, take, drop, span, reverse, concat, replicate, splitAt, null, pred, last, any, all, map) import qualified Prelude  @@ -200,7 +203,7 @@ concat :: (ByteArrayAccess bin, ByteArray bout) => [bin] -> bout concat l = unsafeCreate retLen (loopCopy l)   where-    retLen = sum $ map length l+    retLen = sum $ Prelude.map length l      loopCopy []     _   = return ()     loopCopy (x:xs) dst = do@@ -296,6 +299,45 @@ all :: (ByteArrayAccess ba) => (Word8 -> Bool) -> ba -> Bool all f b = not (any (not . f) b) +-- | Map a function over each byte of a bytearray+map :: (ByteArrayAccess ba, ByteArray ba) => (Word8 -> Word8) -> ba -> ba+map f ba = copyAndFreeze ba $ loop 0+  where+    len = length ba+    loop i ptr+        | i == len  = return ()+        | otherwise = do+            let ptr' = ptr `plusPtr` i+            x <- peek ptr'+            poke ptr' $ f x+            loop (i + 1) ptr+ -- | Convert a bytearray to another type of bytearray convert :: (ByteArrayAccess bin, ByteArray bout) => bin -> bout convert bs = inlineUnsafeCreate (length bs) (copyByteArrayToPtr bs)++-- | Extract @len@ bytes starting at byte @offset@.+-- Returns 'Nothing' if @offset@ or @len@ is negative, or if @offset + len@+-- exceeds the byte array length.+slice :: ByteArray bs => bs -> Int -> Int -> Maybe bs+slice bs offset len+    | offset < 0           = Nothing+    | len < 0              = Nothing+    | offset + len > bsLen = Nothing+    | otherwise            = Just $ unsafeCreate len $ \d ->+        withByteArray bs $ \s -> memCopy d (s `plusPtr` offset) len+  where+    bsLen = length bs++-- | Like 'slice' but calls 'error' when arguments are out of bounds.+-- This includes negative @offset@, negative @len@, or @offset + len@+-- exceeding the byte array length.+unsafeSlice :: ByteArray bs => bs -> Int -> Int -> bs+unsafeSlice bs offset len+    | offset < 0           = error "unsafeSlice: negative offset"+    | len < 0              = error "unsafeSlice: negative length"+    | offset + len > bsLen = error "unsafeSlice: offset + length exceeds byte array size"+    | otherwise            = unsafeCreate len $ \d ->+        withByteArray bs $ \s -> memCopy d (s `plusPtr` offset) len+  where+    bsLen = length bs
Data/ByteArray/ScrubbedBytes.hs view
@@ -33,7 +33,6 @@ import           Data.Memory.PtrMethods import           Data.Memory.Internal.CompatPrim import           Data.Memory.Internal.Compat     (unsafeDoIO)-import           Data.Memory.Internal.Imports import           Data.ByteArray.Types import           Foreign.Storable 
Data/ByteArray/Types.hs view
@@ -23,10 +23,6 @@  import           Data.Memory.PtrMethods (memCopy) --import           Data.Proxy (Proxy(..))-import           Data.Word (Word8)- import Prelude hiding (length)  -- | Class to Access size properties and data of a ByteArray
− Data/Memory/Internal/CompatPrim64.hs
@@ -1,169 +0,0 @@--- |--- Module      : Data.Memory.Internal.CompatPrim--- License     : BSD-style--- Maintainer  : Vincent Hanquez <vincent@snarc.org>--- Stability   : stable--- Portability : Compat------ This module try to keep all the difference between versions of ghc primitive--- or other needed packages, so that modules don't need to use CPP.------ Note that MagicHash and CPP conflicts in places, making it "more interesting"--- to write compat code for primitives----{-# LANGUAGE CPP #-}-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE MagicHash #-}-{-# LANGUAGE UnboxedTuples #-}-#include "MachDeps.h"-module Data.Memory.Internal.CompatPrim64-    ( Word64#-    , Int64#-    , eqInt64#-    , neInt64#-    , ltInt64#-    , leInt64#-    , gtInt64#-    , geInt64#-    , quotInt64#-    , remInt64#-    , eqWord64#-    , neWord64#-    , ltWord64#-    , leWord64#-    , gtWord64#-    , geWord64#-    , and64#-    , or64#-    , xor64#-    , not64#-    , timesWord64#-    , uncheckedShiftL64#-    , uncheckedShiftRL64#--    , int64ToWord64#-    , word64ToInt64#-    , intToInt64#-    , int64ToInt#-    , wordToWord64#-    , word64ToWord#-    , w64#-    ) where---#if WORD_SIZE_IN_BITS == 64-import GHC.Prim hiding (Word64#, Int64#)--#if __GLASGOW_HASKELL__ >= 708-type OutBool = Int#-#else-type OutBool = Bool-#endif--type Word64# = Word#-type Int64# = Int#--#if __GLASGOW_HASKELL__ < 904-eqWord64# :: Word64# -> Word64# -> OutBool-eqWord64# = eqWord#--neWord64# :: Word64# -> Word64# -> OutBool-neWord64# = neWord#--ltWord64# :: Word64# -> Word64# -> OutBool-ltWord64# = ltWord#--leWord64# :: Word64# -> Word64# -> OutBool-leWord64# = leWord#--gtWord64# :: Word64# -> Word64# -> OutBool-gtWord64# = gtWord#--geWord64# :: Word64# -> Word64# -> OutBool-geWord64# = geWord#--eqInt64# :: Int64# -> Int64# -> OutBool-eqInt64# = (==#)--neInt64# :: Int64# -> Int64# -> OutBool-neInt64# = (/=#)--ltInt64# :: Int64# -> Int64# -> OutBool-ltInt64# = (<#)--leInt64# :: Int64# -> Int64# -> OutBool-leInt64# = (<=#)--gtInt64# :: Int64# -> Int64# -> OutBool-gtInt64# = (>#)--geInt64# :: Int64# -> Int64# -> OutBool-geInt64# = (<=#)--quotInt64# :: Int64# -> Int64# -> Int64#-quotInt64# = quotInt#--remInt64# :: Int64# -> Int64# -> Int64#-remInt64# = remInt#--and64# :: Word64# -> Word64# -> Word64#-and64# = and#--or64# :: Word64# -> Word64# -> Word64#-or64# = or#--xor64# :: Word64# -> Word64# -> Word64#-xor64# = xor#--not64# :: Word64# -> Word64#-not64# = not#--uncheckedShiftL64# :: Word64# -> Int# -> Word64#-uncheckedShiftL64# = uncheckedShiftL#--uncheckedShiftRL64#  :: Word64# -> Int# -> Word64#-uncheckedShiftRL64# = uncheckedShiftL#--int64ToWord64# :: Int64# -> Word64#-int64ToWord64# = int2Word#--word64ToInt64# :: Word64# -> Int64#-word64ToInt64# = word2Int#--intToInt64# :: Int# -> Int64#-intToInt64# w = w--int64ToInt# :: Int64# -> Int#-int64ToInt# w = w--wordToWord64# :: Word# -> Word64#-wordToWord64# w = w--word64ToWord# :: Word64# -> Word#-word64ToWord# w = w--timesWord64# :: Word64# -> Word64# -> Word64#-timesWord64# = timesWord#-#endif--w64# :: Word# -> Word# -> Word# -> Word64#-w64# w _ _ = w--#elif WORD_SIZE_IN_BITS == 32-import GHC.IntWord64-import GHC.Prim (Word#)--timesWord64# :: Word64# -> Word64# -> Word64#-timesWord64# a b =-    let !ai = word64ToInt64# a-        !bi = word64ToInt64# b-     in int64ToWord64# (timesInt64# ai bi)--w64# :: Word# -> Word# -> Word# -> Word64#-w64# _ hw lw =-    let !h = wordToWord64# hw-        !l = wordToWord64# lw-     in or64# (uncheckedShiftL64# h 32#) l-#else-#error "not a supported architecture. supported WORD_SIZE_IN_BITS is 32 bits or 64 bits"-#endif
Data/Memory/PtrMethods.hs view
@@ -63,7 +63,7 @@  -- | Copy a set number of bytes from @src to @dst memCopy :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()-memCopy dst src n = c_memcpy dst src (fromIntegral n)+memCopy dst src n = c_memcpy dst src (fromIntegral n) >>= \_ -> return () {-# INLINE memCopy #-}  -- | Set @n number of bytes to the same value @v@@ -114,7 +114,7 @@             loop (i+1) (acc .|. e)  foreign import ccall unsafe "memset"-    c_memset :: Ptr Word8 -> Word8 -> CSize -> IO ()+    c_memset :: Ptr Word8 -> Word8 -> CSize -> IO (Ptr Word8)  foreign import ccall unsafe "memcpy"-    c_memcpy :: Ptr Word8 -> Ptr Word8 -> CSize -> IO ()+    c_memcpy :: Ptr Word8 -> Ptr Word8 -> CSize -> IO (Ptr Word8)
README.md view
@@ -1,4 +1,4 @@-memory+ram ======  [![BSD](http://b.repl.ca/v1/license-BSD-blue.png)](http://en.wikipedia.org/wiki/BSD_licenses)
ram.cabal view
@@ -1,6 +1,6 @@ cabal-version:   3.0 name:            ram-version:         0.20.1+version:         0.22.1 synopsis:        memory and related abstraction stuff description:   This is a fork of memory. It's open to accept changes from anyone,@@ -65,7 +65,6 @@     Data.Memory.Hash.SipHash     Data.Memory.Internal.Compat     Data.Memory.Internal.CompatPrim-    Data.Memory.Internal.CompatPrim64     Data.Memory.Internal.Imports    exposed-modules:  Data.ByteArray.Sized
tests/Imports.hs view
@@ -5,6 +5,7 @@     , testCase     , assertBool     , assertEqual+    , assertException     , (@?=)     ) where @@ -16,13 +17,13 @@ import Test.QuickCheck              as X     ( Arbitrary(..), Gen, Property     , (===), (.&&.)-    , elements, choose, forAll, property, ioProperty+    , elements, choose, forAll, property, ioProperty, (==>)     , Testable     )  import Test.Tasty.Providers         (singleTest, IsTest(..), testPassed, testFailed) import Test.QuickCheck              (quickCheckWithResult, stdArgs, isSuccess, Args(..))-import Control.Exception            (SomeException, try)+import Control.Exception            (SomeException, ErrorCall, try, evaluate)  -- | QuickCheck property test provider for tasty newtype QCTest = QCTest Property@@ -71,3 +72,11 @@ actual @?= expected     | actual == expected = return ()     | otherwise = fail ("expected: " ++ show expected ++ "\n but got: " ++ show actual)++-- | Assert that evaluating a value throws an 'ErrorCall' exception.+assertException :: forall a . a -> IO ()+assertException val = do+    r <- try (evaluate val) :: IO (Either ErrorCall a)+    case r of+        Left _  -> return ()+        Right _ -> fail "expected an exception but none was thrown"
tests/Tests.hs view
@@ -248,4 +248,30 @@         , testProperty "span (const False)" $ \(Words8 l) ->             let b = witnessID (B.pack l)              in B.span (const False) b == (B.empty, b)+        , testProperty "map f == pack . Prelude.map f . unpack" $ \(Words8 l) (Positive w) ->+            let b = witnessID (B.pack l)+                f x = x + fromIntegral w :: Word8+             in B.map f b == (witnessID . B.pack . Prelude.map f $ l)+        , testProperty "slice == Just (take len . drop offset)" $ \(Words8 l) ->+            let bs = witnessID (B.pack l)+                bsLen = B.length bs+            in bsLen > 0 ==>+               forAll (choose (0, bsLen)) $ \offset ->+               forAll (choose (0, bsLen - offset)) $ \len ->+                 B.slice bs offset len == Just (B.take len (B.drop offset bs))+        , testProperty "slice out of bounds == Nothing" $ \(Words8 l) ->+            let bs = witnessID (B.pack l)+                bsLen = B.length bs+            in B.slice bs 0 (bsLen + 1) == Nothing+        , testProperty "slice negative offset == Nothing" $ \(Words8 l) ->+            let bs = witnessID (B.pack l)+            in B.slice bs (-1) 0 == Nothing+        , testProperty "slice negative length == Nothing" $ \(Words8 l) ->+            let bs = witnessID (B.pack l)+            in B.slice bs 0 (-1) == Nothing+        , testCase "unsafeSlice errors on out of bounds" $ do+            let bs = witnessID (B.pack [1,2,3,4,5])+            assertException (B.unsafeSlice bs (-1) 1)+            assertException (B.unsafeSlice bs 0 (-1))+            assertException (B.unsafeSlice bs 0 (B.length bs + 1))         ]