diff --git a/CHANGELOG.md b/CHANGELOG.md index 382cae7..9489d74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.22.0 ++ 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 diff --git a/Data/ByteArray/Methods.hs b/Data/ByteArray/Methods.hs index 2b98418..f93e4cb 100644 --- a/Data/ByteArray/Methods.hs +++ b/Data/ByteArray/Methods.hs @@ -39,6 +39,7 @@ module Data.ByteArray.Methods , all , append , concat + , map ) where import Data.ByteArray.Types @@ -49,7 +50,7 @@ import Data.Monoid 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 +201,7 @@ reverse bs = unsafeCreate n $ \d -> withByteArray bs $ \s -> memReverse d s n 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 +297,19 @@ any f b 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) diff --git a/ram.cabal b/ram.cabal index 33ca67d..76a185f 100644 --- a/ram.cabal +++ b/ram.cabal @@ -1,6 +1,6 @@ cabal-version: 3.0 name: ram -version: 0.21.1 +version: 0.22.0 synopsis: memory and related abstraction stuff description: This is a fork of memory. It's open to accept changes from anyone, diff --git a/tests/Tests.hs b/tests/Tests.hs index 0a89405..b47e1d0 100644 --- a/tests/Tests.hs +++ b/tests/Tests.hs @@ -248,4 +248,8 @@ main = defaultMain $ testGroup "memory" , 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) ]