static-bytes 0.1.0 → 0.1.1
raw patch · 3 files changed
+36/−11 lines, 3 files
Files
- CHANGELOG.md +5/−0
- src/Data/StaticBytes.hs +29/−9
- static-bytes.cabal +2/−2
CHANGELOG.md view
@@ -6,6 +6,11 @@ and this project adheres to the [Haskell Package Versioning Policy](https://pvp.haskell.org/). +## 0.1.1 - 2024-10-21 + +* Ensure that the functionality on big-endian machine architectures is the same + as that on little-endian machine architectures. + ## 0.1.0 - 2023-07-07 * Spin out module `Pantry.Internal.StaticBytes` from package `pantry-0.8.3`.
src/Data/StaticBytes.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} @@ -22,18 +23,22 @@ , fromStatic ) where -import Data.Bits -import Data.ByteArray +import Data.Bits ( Bits (..) ) +import Data.ByteArray ( ByteArrayAccess (..) ) import qualified Data.ByteString as B import qualified Data.ByteString.Internal as B import qualified Data.Primitive.ByteArray as BA +#if MIN_VERSION_GLASGOW_HASKELL(9,4,1,0) +import Data.Type.Equality ( type (~) ) +#endif import qualified Data.Vector.Primitive as VP import qualified Data.Vector.Storable as VS import qualified Data.Vector.Unboxed as VU import qualified Data.Vector.Unboxed.Base as VU -import Foreign.ForeignPtr -import Foreign.Ptr -import Foreign.Storable +import Foreign.ForeignPtr ( ForeignPtr, withForeignPtr ) +import Foreign.Ptr ( Ptr, castPtr ) +import Foreign.Storable ( Storable (..) ) +import GHC.ByteOrder ( ByteOrder (..), targetByteOrder ) import RIO hiding ( words ) import System.IO.Unsafe ( unsafePerformIO ) @@ -75,20 +80,23 @@ lengthD :: dbytes -> Int -- Yeah, it looks terrible to use a list here, but fusion should kick in withPeekD :: dbytes -> ((Int -> IO Word64) -> IO a) -> IO a + -- ^ This assumes that the Word64 values are all little-endian. -- | May throw a runtime exception if invariants are violated! fromWordsD :: Int -> [Word64] -> dbytes + -- ^ This assumes that the Word64 values are all little-endian. fromWordsForeign :: (ForeignPtr a -> Int -> b) -> Int -> [Word64] + -- ^ The Word64 values are assumed to be little-endian. -> b fromWordsForeign wrapper len words0 = unsafePerformIO $ do fptr <- B.mallocByteString len withForeignPtr fptr $ \ptr -> do let loop _ [] = pure () loop off (w:ws) = do - pokeElemOff (castPtr ptr) off w + pokeElemOff (castPtr ptr) off (fromLE64 w) loop (off + 1) ws loop 0 words0 pure $ wrapper fptr len @@ -96,6 +104,7 @@ withPeekForeign :: (ForeignPtr a, Int, Int) -> ((Int -> IO Word64) -> IO b) + -- ^ The Word64 values are assumed to be little-endian. -> IO b withPeekForeign (fptr, off, len) inner = withForeignPtr fptr $ \ptr -> do @@ -109,7 +118,7 @@ let w64' = shiftL (fromIntegral w8) (i * 8) .|. w64 loop w64' (i + 1) loop 0 0 - | otherwise = peekByteOff ptr (off + off') + | otherwise = toLE64 <$> peekByteOff ptr (off + off') inner f instance DynamicBytes B.ByteString where @@ -129,7 +138,7 @@ let loop _ [] = VP.Vector 0 len <$> BA.unsafeFreezeByteArray ba loop i (w:ws) = do - BA.writeByteArray ba i w + BA.writeByteArray ba i (fromLE64 w) loop (i + 1) ws loop 0 words0 withPeekD (VP.Vector off len ba) inner = do @@ -143,7 +152,8 @@ let w64' = shiftL (fromIntegral w8) (i * 8) .|. w64 loop w64' (i + 1) loop 0 0 - | otherwise = pure $ BA.indexByteArray ba (off + (off' `div` 8)) + | otherwise = pure $ + toLE64 $ BA.indexByteArray ba (off + (off' `div` 8)) inner f instance word8 ~ Word8 => DynamicBytes (VU.Vector word8) where @@ -244,3 +254,13 @@ => sbytes -> dbytes fromStatic = fromWordsD (lengthS (Nothing :: Maybe sbytes)) . ($ []) . toWordsS + +-- | Convert a 64 bit value in CPU endianess to little endian. +toLE64 :: Word64 -> Word64 +toLE64 = case targetByteOrder of + BigEndian -> byteSwap64 + LittleEndian -> id + +-- | Convert a little endian 64 bit value to CPU endianess. +fromLE64 :: Word64 -> Word64 +fromLE64 = toLE64
static-bytes.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.2.+-- This file has been generated from package.yaml by hpack version 0.37.0. -- -- see: https://github.com/sol/hpack name: static-bytes-version: 0.1.0+version: 0.1.1 synopsis: A Haskell library providing types representing 8, 16, 32, 64 or 128 bytes of data. description: Please see the README on GitHub at <https://github.com/commercialhaskell/static-bytes#readme> category: Data