module Data.Byteable
( Byteable(..)
, constEqBytes
) where
import Foreign.Ptr (Ptr, plusPtr)
import Foreign.ForeignPtr (withForeignPtr)
import Data.ByteString (ByteString)
import Data.List (foldl')
import Data.Word (Word8)
import qualified Data.ByteString as B (length, zipWith)
import qualified Data.ByteString.Internal as B (toForeignPtr)
class Byteable a where
toBytes :: a -> ByteString
byteableLength :: a -> Int
byteableLength = ByteString -> Int
B.length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Byteable a => a -> ByteString
toBytes
withBytePtr :: a -> (Ptr Word8 -> IO b) -> IO b
withBytePtr a
a Ptr Word8 -> IO b
f = forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fptr forall a b. (a -> b) -> a -> b
$ \Ptr Word8
ptr -> Ptr Word8 -> IO b
f (Ptr Word8
ptr forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
off)
where (ForeignPtr Word8
fptr, Int
off, Int
_) = ByteString -> (ForeignPtr Word8, Int, Int)
B.toForeignPtr forall a b. (a -> b) -> a -> b
$ forall a. Byteable a => a -> ByteString
toBytes a
a
instance Byteable ByteString where
toBytes :: ByteString -> ByteString
toBytes ByteString
bs = ByteString
bs
constEqBytes :: Byteable a => a -> a -> Bool
constEqBytes :: forall a. Byteable a => a -> a -> Bool
constEqBytes a
a a
b = ByteString -> ByteString -> Bool
constEqByteString (forall a. Byteable a => a -> ByteString
toBytes a
a) (forall a. Byteable a => a -> ByteString
toBytes a
b)
{-# RULES "constEqBytes/ByteString" constEqBytes = constEqByteString #-}
{-# INLINE constEqByteString #-}
constEqByteString :: ByteString -> ByteString -> Bool
constEqByteString :: ByteString -> ByteString -> Bool
constEqByteString ByteString
a ByteString
b
| Int
len forall a. Eq a => a -> a -> Bool
/= ByteString -> Int
B.length ByteString
b = Bool
False
| Bool
otherwise = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Bool -> Bool -> Bool
(&&!) Bool
True forall a b. (a -> b) -> a -> b
$ forall a. (Word8 -> Word8 -> a) -> ByteString -> ByteString -> [a]
B.zipWith forall a. Eq a => a -> a -> Bool
(==) ByteString
a ByteString
b
where len :: Int
len = ByteString -> Int
B.length ByteString
a
(&&!) :: Bool -> Bool -> Bool
Bool
True &&! :: Bool -> Bool -> Bool
&&! Bool
True = Bool
True
Bool
True &&! Bool
False = Bool
False
Bool
False &&! Bool
True = Bool
False
Bool
False &&! Bool
False = Bool
False