-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Haskus binary format manipulation -- -- A set of types and tools to manipulate binary data, memory, etc. In -- particular to interface Haskell data types with foreign data types (C -- structs, unions, enums, etc.). @package haskus-binary @version 1.2 -- | Bit orderings module Haskus.Format.Binary.Bits.Order -- | Bit order -- -- The first letter indicates the outer bit ordering, i.e. how bytes are -- filled: -- -- -- -- The second letter indicates the inner bit ordering, i.e. how words are -- stored: -- -- -- -- E.g. two successive words of 5 bits: ABCDE, VWXYZ BB: ABCDEVWX -- YZxxxxxx BL: EDCBAZYX WVxxxxxx LB: XWVEDCBA -- xxxxxxZY LL: XYZABCDE xxxxxxVW data BitOrder BB :: BitOrder LB :: BitOrder BL :: BitOrder LL :: BitOrder instance GHC.Classes.Eq Haskus.Format.Binary.Bits.Order.BitOrder instance GHC.Show.Show Haskus.Format.Binary.Bits.Order.BitOrder -- | Memory layout -- -- Describe a memory region module Haskus.Format.Binary.Layout -- | Type obtained when following path p type family LayoutPathType l p :: * -- | Offset obtained when following path p type family LayoutPathOffset l p :: Nat type LayoutRoot = LayoutPath '[] -- | Path in a layout data LayoutPath (path :: [*]) LayoutPath :: LayoutPath -- | Index in a layout path data LayoutIndex (n :: Nat) LayoutIndex :: LayoutIndex -- | Symbol in a layout path data LayoutSymbol (s :: Symbol) LayoutSymbol :: LayoutSymbol -- | Index in the layout path layoutIndex :: forall n. LayoutPath '[LayoutIndex n] -- | Symbol in the layout path layoutSymbol :: forall s. LayoutPath '[LayoutSymbol s] type family (:->) p (s :: Symbol) type family (:#>) p (n :: Nat) -- | Pointers -- -- A pointer is a number: an offset into a memory. This is the `Addr#` -- type. -- -- We want the type-system to help us avoid errors when we use pointers, -- hence we decorate them with phantom types describing the memory layout -- at the pointed address. This is the `Ptr a` data type that wraps an -- `Addr#`. -- -- We often want to associate finalizers to pointers, i.e., actions to be -- run when the pointer is collected by the GC. These actions take the -- pointer as a parameter. This is the `ForeignPtr a` data type. -- -- A `ForeignPtr a` cannot be manipulated like a number because somehow -- we need to keep the pointer value that will be passed to the -- finalizers. Moreover we don't want finalizers to be executed too -- early, so we can't easily create a new ForeignPtr from another (it -- would require a way to disable the existing finalizers of a -- ForeignPtr, which would in turn open a whole can of worms). Hence we -- use the `FinalizedPtr a` pointer type, which has an additional offset -- field. module Haskus.Format.Binary.Ptr -- | Pointer operations class PtrLike (p :: * -> *) -- | Cast a pointer from one type to another castPtr :: PtrLike p => p a -> p b -- | Null pointer (offset is 0) nullPtr :: forall a. PtrLike p => p a -- | Advance a pointer by the given amount of bytes (may be negative) indexPtr :: PtrLike p => p a -> Int -> p a -- | Distance between two pointers in bytes (p2 - p1) ptrDistance :: PtrLike p => p a -> p b -> Int -- | Use the pointer withPtr :: PtrLike p => p a -> (Ptr a -> IO b) -> IO b -- | Malloc the given number of bytes mallocBytes :: (PtrLike p, MonadIO m) => Word -> m (p a) -- | Add offset to the given layout field indexField :: forall path l. (PtrLike p, KnownNat (LayoutPathOffset l path)) => p l -> path -> p (LayoutPathType l path) -- | Add offset corresponding to the layout field with the given symbol (-->) :: forall s l. (PtrLike p, KnownNat (LayoutPathOffset l (LayoutPath '[LayoutSymbol s]))) => p l -> LayoutSymbol s -> p (LayoutPathType l (LayoutPath '[LayoutSymbol s])) -- | Add offset corresponding to the layout field with the given index (-#>) :: forall n l. (PtrLike p, KnownNat (LayoutPathOffset l (LayoutPath '[LayoutIndex n]))) => p l -> LayoutIndex n -> p (LayoutPathType l (LayoutPath '[LayoutIndex n])) -- | Generalized version of indexPtr indexPtr' :: Integral b => Ptr a -> b -> Ptr a -- | A value of type Ptr a represents a pointer to an -- object, or an array of objects, which may be marshalled to or from -- Haskell values of type a. -- -- The type a will often be an instance of class Storable -- which provides the marshalling operations. However this is not -- essential, and you can provide your own operations to access the -- pointer. For example you might write small foreign functions to get or -- set the fields of a C struct. data Ptr a Ptr :: Addr# -> Ptr a -- | Free a malloced memory free :: MonadIO m => Ptr a -> m () -- | A finalized pointer -- -- We use an offset because we can't modify the pointer directly (it is -- passed to the foreign pointer destructors) data FinalizedPtr l FinalizedPtr :: {-# UNPACK #-} !ForeignPtr l -> {-# UNPACK #-} !Word -> FinalizedPtr l -- | Use a finalized pointer withFinalizedPtr :: FinalizedPtr a -> (Ptr a -> IO b) -> IO b -- | The type ForeignPtr represents references to objects that are -- maintained in a foreign language, i.e., that are not part of the data -- structures usually managed by the Haskell storage manager. The -- essential difference between ForeignPtrs and vanilla memory -- references of type Ptr a is that the former may be associated -- with finalizers. A finalizer is a routine that is invoked when -- the Haskell storage manager detects that - within the Haskell heap and -- stack - there are no more references left that are pointing to the -- ForeignPtr. Typically, the finalizer will, then, invoke -- routines in the foreign language that free the resources bound by the -- foreign object. -- -- The ForeignPtr is parameterised in the same way as Ptr. -- The type argument of ForeignPtr should normally be an instance -- of class Storable. data ForeignPtr a -- | Use a foreign pointer withForeignPtr :: MonadInIO m => ForeignPtr a -> (Ptr a -> m b) -> m b -- | Malloc a foreign pointer mallocForeignPtrBytes :: MonadIO m => Word -> m (ForeignPtr a) -- | Null foreign pointer nullForeignPtr :: ForeignPtr a -- | A value of type FunPtr a is a pointer to a function -- callable from foreign code. The type a will normally be a -- foreign type, a function type with zero or more arguments where -- -- -- -- A value of type FunPtr a may be a pointer to a foreign -- function, either returned by another foreign function or imported with -- a a static address import like -- --
--   foreign import ccall "stdlib.h &free"
--     p_free :: FunPtr (Ptr a -> IO ())
--   
-- -- or a pointer to a Haskell function created using a wrapper stub -- declared to produce a FunPtr of the correct type. For example: -- --
--   type Compare = Int -> Int -> Bool
--   foreign import ccall "wrapper"
--     mkCompare :: Compare -> IO (FunPtr Compare)
--   
-- -- Calls to wrapper stubs like mkCompare allocate storage, which -- should be released with freeHaskellFunPtr when no longer -- required. -- -- To convert FunPtr values to corresponding Haskell functions, -- one can define a dynamic stub for the specific foreign type, -- e.g. -- --
--   type IntFunction = CInt -> IO ()
--   foreign import ccall "dynamic"
--     mkFun :: FunPtr IntFunction -> IntFunction
--   
data FunPtr a -- | The constant nullFunPtr contains a distinguished value of -- FunPtr that is not associated with a valid memory location. nullFunPtr :: () => FunPtr a -- | Casts a Ptr to a FunPtr. -- -- Note: this is valid only on architectures where data and -- function pointers range over the same set of addresses, and should -- only be used for bindings to external libraries whose interface -- already relies on this assumption. castPtrToFunPtr :: () => Ptr a -> FunPtr b -- | Casts a FunPtr to a Ptr. -- -- Note: this is valid only on architectures where data and -- function pointers range over the same set of addresses, and should -- only be used for bindings to external libraries whose interface -- already relies on this assumption. castFunPtrToPtr :: () => FunPtr a -> Ptr b -- | An unsigned integral type that can be losslessly converted to and from -- Ptr. This type is also compatible with the C99 type -- uintptr_t, and can be marshalled to and from that type -- safely. data WordPtr -- | casts a WordPtr to a Ptr wordPtrToPtr :: () => WordPtr -> Ptr a -- | casts a Ptr to a WordPtr ptrToWordPtr :: () => Ptr a -> WordPtr instance GHC.Show.Show (Haskus.Format.Binary.Ptr.FinalizedPtr l) instance Haskus.Format.Binary.Ptr.PtrLike GHC.Ptr.Ptr instance Haskus.Format.Binary.Ptr.PtrLike Haskus.Format.Binary.Ptr.FinalizedPtr -- | Unsigned and signed words module Haskus.Format.Binary.Word -- | Return a Word with at least n bits type family WordAtLeast (n :: Nat) -- | Return a Int with at least n bits type family IntAtLeast (n :: Nat) -- | Return a Word with exactly n bits type family WordN (n :: Nat) -- | Return a Int with exactly n bits type family IntN (n :: Nat) -- | Haskell type representing the C size_t type. newtype CSize CSize :: Word64 -> CSize -- | Haskell type representing the C unsigned short type. data CUShort -- | Haskell type representing the C short type. data CShort -- | Haskell type representing the C unsigned int type. data CUInt -- | Haskell type representing the C int type. data CInt -- | Haskell type representing the C unsigned long type. data CULong -- | Haskell type representing the C long type. data CLong data Word# :: TYPE WordRep data Int# :: TYPE IntRep plusWord# :: Word# -> Word# -> Word# minusWord# :: Word# -> Word# -> Word# (+#) :: Int# -> Int# -> Int# infixl 6 +# (-#) :: Int# -> Int# -> Int# infixl 6 -# (==#) :: Int# -> Int# -> Int# infix 4 ==# (>#) :: Int# -> Int# -> Int# infix 4 ># (<#) :: Int# -> Int# -> Int# infix 4 <# (>=#) :: Int# -> Int# -> Int# infix 4 >=# (<=#) :: Int# -> Int# -> Int# infix 4 <=# ltWord# :: Word# -> Word# -> Int# leWord# :: Word# -> Word# -> Int# gtWord# :: Word# -> Word# -> Int# geWord# :: Word# -> Word# -> Int# eqWord# :: Word# -> Word# -> Int# -- | Alias for tagToEnum#. Returns True if its parameter is 1# and -- False if it is 0#. isTrue# :: Int# -> Bool -- | Storable class module Haskus.Format.Binary.Storable -- | A storable data in constant space whose size is known at compile time class StaticStorable a where { -- | Size of the stored data (in bytes) type family SizeOf a :: Nat; -- | Alignment requirement (in bytes) type family Alignment a :: Nat; } -- | Peek (read) a value from a memory address staticPeekIO :: StaticStorable a => Ptr a -> IO a -- | Poke (write) a value at the given memory address staticPokeIO :: StaticStorable a => Ptr a -> a -> IO () -- | Peek (read) a value from a memory address staticPeek :: (StaticStorable a, MonadIO m) => Ptr a -> m a -- | Poke (write) a value at the given memory address staticPoke :: (StaticStorable a, MonadIO m) => Ptr a -> a -> m () -- | Compute the required padding between a and b to respect b's alignment type family RequiredPadding a b -- | Compute the required padding between the size sz and b to respect b's -- alignment type family Padding (sz :: Nat) b type family PaddingEx (m :: Nat) (a :: Nat) -- | Get statically known size staticSizeOf :: forall a. KnownNat (SizeOf a) => a -> Word -- | Get statically known alignment staticAlignment :: forall a. KnownNat (Alignment a) => a -> Word -- | Get bytes in host-endianness order wordBytes :: forall a. (Storable a, KnownNat (SizeOf a)) => a -> [Word8] -- | Storable data-types -- -- Currently we cannot automatically derive a Storable class with -- type-level naturals for "alignment" and "sizeOf". Instead we define a -- Storable class isomorphic to the Foreign.Storable's one but with -- default methods using DefaultSignatures (i.e., the Storable instance -- can be automatically derived from a Generic instance). class Storable a peekIO :: Storable a => Ptr a -> IO a peekIO :: (Storable a, Generic a, GStorable (Rep a)) => Ptr a -> IO a pokeIO :: Storable a => Ptr a -> a -> IO () pokeIO :: (Storable a, Generic a, GStorable (Rep a)) => Ptr a -> a -> IO () alignment :: Storable a => a -> Word alignment :: (Storable a, Generic a, GStorable (Rep a)) => a -> Word sizeOf :: Storable a => a -> Word sizeOf :: (Storable a, Generic a, GStorable (Rep a)) => a -> Word -- | Peek a value from a pointer peek :: (Storable a, MonadIO m) => Ptr a -> m a -- | Poke a value to a pointer poke :: (Storable a, MonadIO m) => Ptr a -> a -> m () -- | Generalized sizeOf sizeOf' :: (Integral b, Storable a) => a -> b -- | SizeOf (for type-application) sizeOfT :: forall a. Storable a => Word -- | SizeOf' (for type-application) sizeOfT' :: forall a b. (Storable a, Integral b) => b -- | Generalized alignment alignment' :: (Integral b, Storable a) => a -> b -- | Alignment (for type-application) alignmentT :: forall a. Storable a => Word -- | Alignment' (for type-application) alignmentT' :: forall a b. (Storable a, Integral b) => b -- | Peek with byte offset peekByteOff :: (MonadIO m, Storable a) => Ptr a -> Int -> m a -- | Poke with byte offset pokeByteOff :: (MonadIO m, Storable a) => Ptr a -> Int -> a -> m () -- | Peek with element size offset peekElemOff :: forall a m. (MonadIO m, Storable a) => Ptr a -> Int -> m a -- | Poke with element size offset pokeElemOff :: (MonadIO m, Storable a) => Ptr a -> Int -> a -> m () -- | alloca f executes the computation f, passing -- as argument a pointer to a temporarily allocated block of memory -- sufficient to hold values of type a. -- -- The memory is freed when f terminates (either normally or via -- an exception), so the pointer passed to f must not be -- used after this. alloca :: forall a b m. (MonadInIO m, Storable a) => (Ptr a -> m b) -> m b -- | Allocate some bytes allocaBytes :: MonadInIO m => Word -> (Ptr a -> m b) -> m b -- | Allocate some aligned bytes allocaBytesAligned :: MonadInIO m => Word -> Word -> (Ptr a -> m b) -> m b -- | Allocate a block of memory that is sufficient to hold values of type -- a. The size of the area allocated is determined by the -- sizeOf method from the instance of Storable for the -- appropriate type. -- -- The memory may be deallocated using free or -- finalizerFree when no longer required. malloc :: forall a m. (MonadIO m, Storable a) => m (Ptr a) -- | with val f executes the computation f, -- passing as argument a pointer to a temporarily allocated block of -- memory into which val has been marshalled (the combination of -- alloca and poke). -- -- The memory is freed when f terminates (either normally or via -- an exception), so the pointer passed to f must not be -- used after this. with :: (MonadInIO m, Storable a) => a -> (Ptr a -> m b) -> m b -- | Replicates a withXXX combinator over a list of objects, -- yielding a list of marshalled objects withMany :: (a -> (b -> res) -> res) -> [a] -> ([b] -> res) -> res -- | Temporarily allocate space for the given number of elements (like -- alloca, but for multiple elements). allocaArray :: forall a b m. (MonadInIO m, Storable a) => Word -> (Ptr a -> m b) -> m b -- | Allocate space for the given number of elements (like malloc, -- but for multiple elements). mallocArray :: forall a m. (MonadIO m, Storable a) => Word -> m (Ptr a) -- | Temporarily store a list of storable values in memory (like -- with, but for multiple elements). withArray :: (MonadInIO m, Storable a) => [a] -> (Ptr a -> m b) -> m b -- | Like withArray, but the action gets the number of values as an -- additional parameter withArrayLen :: (MonadInIO m, Storable a) => [a] -> (Word -> Ptr a -> m b) -> m b -- | Convert an array of given length into a Haskell list. The -- implementation is tail-recursive and so uses constant stack space. peekArray :: (MonadIO m, Storable a) => Word -> Ptr a -> m [a] -- | Write the list elements consecutive into memory pokeArray :: (MonadIO m, Storable a) => Ptr a -> [a] -> m () instance Haskus.Format.Binary.Storable.Storable a => Haskus.Format.Binary.Storable.GStorable (GHC.Generics.K1 i a) instance Haskus.Format.Binary.Storable.Storable GHC.Word.Word8 instance Haskus.Format.Binary.Storable.Storable GHC.Word.Word16 instance Haskus.Format.Binary.Storable.Storable GHC.Word.Word32 instance Haskus.Format.Binary.Storable.Storable GHC.Word.Word64 instance Haskus.Format.Binary.Storable.Storable GHC.Int.Int8 instance Haskus.Format.Binary.Storable.Storable GHC.Int.Int16 instance Haskus.Format.Binary.Storable.Storable GHC.Int.Int32 instance Haskus.Format.Binary.Storable.Storable GHC.Int.Int64 instance Haskus.Format.Binary.Storable.Storable GHC.Types.Float instance Haskus.Format.Binary.Storable.Storable GHC.Types.Double instance Haskus.Format.Binary.Storable.Storable GHC.Types.Char instance Haskus.Format.Binary.Storable.Storable GHC.Types.Word instance Haskus.Format.Binary.Storable.Storable GHC.Types.Int instance Haskus.Format.Binary.Storable.Storable (GHC.Ptr.Ptr a) instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CSize instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CChar instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CULong instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CLong instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CUInt instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CInt instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CUShort instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CShort instance Haskus.Format.Binary.Storable.Storable Foreign.Ptr.WordPtr instance Haskus.Format.Binary.Storable.GStorable GHC.Generics.U1 instance (Haskus.Format.Binary.Storable.GStorable a, Haskus.Format.Binary.Storable.GStorable b) => Haskus.Format.Binary.Storable.GStorable (a GHC.Generics.:*: b) instance Haskus.Format.Binary.Storable.GStorable a => Haskus.Format.Binary.Storable.GStorable (GHC.Generics.M1 i c a) instance Haskus.Format.Binary.Storable.StaticStorable GHC.Word.Word8 instance Haskus.Format.Binary.Storable.StaticStorable GHC.Word.Word16 instance Haskus.Format.Binary.Storable.StaticStorable GHC.Word.Word32 instance Haskus.Format.Binary.Storable.StaticStorable GHC.Word.Word64 instance Haskus.Format.Binary.Storable.StaticStorable GHC.Int.Int8 instance Haskus.Format.Binary.Storable.StaticStorable GHC.Int.Int16 instance Haskus.Format.Binary.Storable.StaticStorable GHC.Int.Int32 instance Haskus.Format.Binary.Storable.StaticStorable GHC.Int.Int64 -- | Store an Enum in the given backing word type module Haskus.Format.Binary.Enum -- | Store enum a as a b data EnumField b a -- | Extended Enum -- -- By default, use fromEnum and toEnum to convert from and to an -- Integral. -- -- But it can be overloaded to perform transformation before using -- fromEnum/toEnum. E.g. if values are shifted by 1 compared to Enum -- values, define fromCEnum = (+1) . fromIntegral . fromEnum class CEnum a fromCEnum :: (CEnum a, Integral b) => a -> b fromCEnum :: (CEnum a, Enum a, Integral b) => a -> b toCEnum :: (CEnum a, Integral b) => b -> a toCEnum :: (CEnum a, Enum a, Integral b) => b -> a -- | Read an enum field fromEnumField :: (CEnum a, Integral b) => EnumField b a -> a -- | Create an enum field toEnumField :: (CEnum a, Integral b) => a -> EnumField b a -- | Make an enum from a number (0 indexed) makeEnum :: forall a i. (Data a, Integral i) => i -> a -- | Make an enum with the last constructor taking a parameter for the rest -- of the range, but don't build the last constructor -- --
--   data T = A | B | C | D Word8
--   
--   makeEnumMaybe :: Int -> T
--   makeEnumMaybe x = case x of
--      0 -> Just A
--      1 -> Just B
--      2 -> Just C
--      n -> Nothing
--   
makeEnumMaybe :: forall a i. (Data a, Integral i) => i -> Maybe a -- | Make an enum with the last constructor taking a parameter for the rest -- of the range -- --
--   data T = A | B | C | D Word8
--   
--   makeEnumWithCustom :: Int -> T
--   makeEnumWithCustom x = case x of
--      0 -> A
--      1 -> B
--      2 -> C
--      n -> D (n - 3)
--   
makeEnumWithCustom :: forall a i. (Data a, Integral i) => i -> a instance Haskus.Format.Binary.Storable.Storable b => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.Enum.EnumField b a) instance GHC.Classes.Eq b => GHC.Classes.Eq (Haskus.Format.Binary.Enum.EnumField b a) instance GHC.Show.Show b => GHC.Show.Show (Haskus.Format.Binary.Enum.EnumField b a) instance (GHC.Real.Integral b, Haskus.Format.Binary.Storable.StaticStorable b, Haskus.Format.Binary.Enum.CEnum a) => Haskus.Format.Binary.Storable.StaticStorable (Haskus.Format.Binary.Enum.EnumField b a) -- | Character module Haskus.Format.Binary.Char -- | 8-bit character (ASCII, etc.) newtype Char8 Char8 :: Word8 -> Char8 instance Haskus.Format.Binary.Storable.Storable Haskus.Format.Binary.Char.Char8 instance GHC.Classes.Ord Haskus.Format.Binary.Char.Char8 instance GHC.Classes.Eq Haskus.Format.Binary.Char.Char8 instance GHC.Show.Show Haskus.Format.Binary.Char.Char8 -- | Bit shifts module Haskus.Format.Binary.Bits.Shift -- | Bit shifts -- -- Checked means that there is an additional test to ensure that -- the shift offset is valid (less than the bit count). If you are sure -- that the offset is valid, use the "unchecked" version which should be -- faster. -- -- To shift signed numbers, see SignedShiftableBits class methods. class ShiftableBits a -- | Checked right shift shiftR :: ShiftableBits a => a -> Word -> a -- | Checked left shift shiftL :: ShiftableBits a => a -> Word -> a -- | Unchecked right shift uncheckedShiftR :: ShiftableBits a => a -> Word -> a -- | Unchecked left shift uncheckedShiftL :: ShiftableBits a => a -> Word -> a -- | Checked shift to the left if positive, to the right if negative shift :: ShiftableBits a => a -> Int -> a -- | Unchecked shift to the left if positive, to the right if negative uncheckedShift :: ShiftableBits a => a -> Int -> a -- | Signed bit shifts -- -- Signed means that the sign bit (the higher order bit): - -- propagates to the right during right shifts and - keeps its value -- during left shifts (except when all other bits are 0) -- -- Checked means that there is an additional test to ensure that -- the shift offset is valid (less than the bit count). If you are sure -- that the offset is valid, use the "unchecked" version which should be -- faster. class SignedShiftableBits a -- | Checked signed right shift signedShiftR :: SignedShiftableBits a => a -> Word -> a -- | Checked signed left shift signedShiftL :: SignedShiftableBits a => a -> Word -> a -- | Unchecked signed right shift uncheckedSignedShiftR :: SignedShiftableBits a => a -> Word -> a -- | Unchecked signed left shift uncheckedSignedShiftL :: SignedShiftableBits a => a -> Word -> a -- | Checked signed shift to the left if positive, to the right if negative signedShift :: SignedShiftableBits a => a -> Int -> a -- | Unchecked signed shift to the left if positive, to the right if -- negative uncheckedSignedShift :: SignedShiftableBits a => a -> Int -> a instance Haskus.Format.Binary.Bits.Shift.SignedShiftableBits GHC.Types.Int instance Haskus.Format.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int8 instance Haskus.Format.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int16 instance Haskus.Format.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int32 instance Haskus.Format.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int64 instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Types.Word instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Word.Word8 instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Word.Word16 instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Word.Word32 instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Word.Word64 instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Types.Int instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Int.Int8 instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Int.Int16 instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Int.Int32 instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Int.Int64 instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Integer.Type.Integer -- | Bitwise bit operations module Haskus.Format.Binary.Bits.Bitwise -- | Bitwise bit operations class Bitwise a -- | Bitwise "and" (.&.) :: Bitwise a => a -> a -> a -- | Bitwise "or" (.|.) :: Bitwise a => a -> a -> a -- | Bitwise "xor" xor :: Bitwise a => a -> a -> a -- | Complement complement :: Bitwise a => a -> a instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Types.Word instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Word.Word8 instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Word.Word16 instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Word.Word32 instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Word.Word64 instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Types.Int instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Int.Int8 instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Int.Int16 instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Int.Int32 instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Int.Int64 instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Integer.Type.Integer -- | Bit indexable types module Haskus.Format.Binary.Bits.Index -- | Type whose bits are indexable class IndexableBits a -- | bit i is a value with the ith bit set -- and all other bits clear. bit :: IndexableBits a => Word -> a -- | bit i is a value with the ith bit set -- and all other bits clear. bit :: (IndexableBits a, Num a, ShiftableBits a) => Word -> a -- | x `setBit` i is the same as x .|. bit i setBit :: IndexableBits a => a -> Word -> a -- | x `setBit` i is the same as x .|. bit i setBit :: (IndexableBits a, Bitwise a) => a -> Word -> a -- | x `clearBit` i is the same as x .&. complement (bit -- i) clearBit :: IndexableBits a => a -> Word -> a -- | x `clearBit` i is the same as x .&. complement (bit -- i) clearBit :: (IndexableBits a, Bitwise a) => a -> Word -> a -- | x `complementBit` i is the same as x `xor` bit i complementBit :: IndexableBits a => a -> Word -> a -- | x `complementBit` i is the same as x `xor` bit i complementBit :: (IndexableBits a, Bitwise a) => a -> Word -> a -- | Return True if the nth bit of the argument is 1 testBit :: IndexableBits a => a -> Word -> Bool -- | Return True if the nth bit of the argument is 1 testBit :: (IndexableBits a, Bitwise a, Num a, Eq a) => a -> Word -> Bool -- | Return the number of set bits popCount :: IndexableBits a => a -> Word -- | Return the number of set bits popCount :: (IndexableBits a, Bitwise a, Num a, Eq a) => a -> Word instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Types.Word instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Word.Word8 instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Word.Word16 instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Word.Word32 instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Word.Word64 instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Types.Int instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Int.Int8 instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Int.Int16 instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Int.Int32 instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Int.Int64 -- | Types with finite bit count module Haskus.Format.Binary.Bits.Finite -- | Type representable by a fixed amount of bits class FiniteBits a where { -- | Number of bits type family BitSize a :: Nat; } -- | Number of bits (the value is ignored) bitSize :: (FiniteBits a, Integral i, KnownNat (BitSize a)) => a -> i -- | All bits set to 0 zeroBits :: FiniteBits a => a -- | All bits set to 1 oneBits :: FiniteBits a => a -- | All bits set to 1 oneBits :: (FiniteBits a, Bitwise a) => a -- | Count number of zero bits preceding the most significant set bit countLeadingZeros :: FiniteBits a => a -> Word -- | Count number of zero bits following the least significant set bit countTrailingZeros :: FiniteBits a => a -> Word instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Types.Word instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Word.Word8 instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Word.Word16 instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Word.Word32 instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Word.Word64 instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Types.Int instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Int.Int8 instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Int.Int16 instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Int.Int32 instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Int.Int64 -- | Bit rotations module Haskus.Format.Binary.Bits.Rotate -- | Types whose bits can be rotated class RotatableBits a -- | Rotate left if positive, right if negative rotate :: RotatableBits a => a -> Int -> a -- | Rotate left if positive, right if negative rotate :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Int -> a -- | Checked left bit rotation rotateL :: RotatableBits a => a -> Word -> a -- | Checked left bit rotation rotateL :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Word -> a -- | Checked right bit rotation rotateR :: RotatableBits a => a -> Word -> a -- | Checked right bit rotation rotateR :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Word -> a -- | Unchecked rotate left if positive, right if negative uncheckedRotate :: RotatableBits a => a -> Int -> a -- | Unchecked left bit rotation uncheckedRotateL :: RotatableBits a => a -> Word -> a -- | Unchecked left bit rotation uncheckedRotateL :: (RotatableBits a, ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => a -> Word -> a -- | Unchecked right bit rotation uncheckedRotateR :: RotatableBits a => a -> Word -> a -- | Unchecked right bit rotation uncheckedRotateR :: (RotatableBits a, ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => a -> Word -> a instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Types.Word instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Word.Word8 instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Word.Word16 instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Word.Word32 instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Word.Word64 instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Types.Int instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Int.Int8 instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Int.Int16 instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Int.Int32 instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Int.Int64 -- | Memory utilities module Haskus.Utils.Memory -- | Copy memory memCopy :: MonadIO m => Ptr a -> Ptr b -> Word64 -> m () -- | Set memory memSet :: MonadIO m => Ptr a -> Word64 -> Word8 -> m () -- | Allocate several arrays allocaArrays :: (MonadInIO m, Storable s, Integral a) => [a] -> ([Ptr s] -> m b) -> m b -- | Peek several arrays peekArrays :: (MonadIO m, Storable s, Integral a) => [a] -> [Ptr s] -> m [[s]] -- | Poke several arrays pokeArrays :: (MonadIO m, Storable s) => [Ptr s] -> [[s]] -> m () -- | Allocate several arrays withArrays :: (MonadInIO m, Storable s) => [[s]] -> ([Ptr s] -> m b) -> m b -- | Execute f with a pointer to a or NULL withMaybeOrNull :: (Storable a, MonadInIO m) => Maybe a -> (Ptr a -> m b) -> m b -- | Union (as in C) -- -- Unions are storable and can contain any storable data. -- -- Use fromUnion to read an alternative: -- --
--   {--}
--   
--   getUnion :: IO (Union '[Word16, Word32, Word64])
--   getUnion = ...
--   
--   test = do
--      u <- getUnion
--   
--      -- to get one of the member
--      let v = fromUnion u :: Word16
--      let v = fromUnion u :: Word32
--      let v = fromUnion u :: Word64
--   
--      -- This won't compile (Word8 is not a member of the union)
--      let v = fromUnion u :: Word8
--   
-- -- Use toUnion to create a new union: -- --
--   let
--      u2 :: Union '[Word32, Vector 4 Word8]
--      u2 = toUnion (0x12345678 :: Word32)
--   
module Haskus.Format.Binary.Union -- | An union -- -- We use a list of types as a parameter. -- -- The union is just a pointer to a buffer containing the value(s). The -- size of the buffer is implicitly known from the types in the list. data Union (x :: [*]) -- | Retrieve a union member from its type fromUnion :: (Storable a, Member a l) => Union l -> a -- | Create a new union from one of the union types toUnion :: forall a l. (Storable (Union l), Storable a, Member a l) => a -> Union l -- | Like toUnion but set the remaining bytes to 0 toUnionZero :: forall a l. (Storable (Union l), Storable a, Member a l) => a -> Union l instance GHC.Show.Show (Haskus.Format.Binary.Union.Union x) instance (r Data.Type.Equality.~ GHC.Types.Word, Haskus.Format.Binary.Storable.Storable a) => Haskus.Utils.HList.Apply Haskus.Format.Binary.Union.FoldAlignment (a, GHC.Types.Word) r instance (Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Union.FoldSizeOf GHC.Types.Word l GHC.Types.Word, Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Union.FoldAlignment GHC.Types.Word l GHC.Types.Word) => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.Union.Union l) instance (Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Union.FoldSizeOf GHC.Types.Word l GHC.Types.Word, Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Union.FoldAlignment GHC.Types.Word l GHC.Types.Word) => Foreign.Storable.Storable (Haskus.Format.Binary.Union.Union l) instance (r Data.Type.Equality.~ GHC.Types.Word, Haskus.Format.Binary.Storable.Storable a) => Haskus.Utils.HList.Apply Haskus.Format.Binary.Union.FoldSizeOf (a, GHC.Types.Word) r instance (GHC.TypeNats.KnownNat (Haskus.Utils.Types.List.Max (Haskus.Format.Binary.Union.MapSizeOf fs)), GHC.TypeNats.KnownNat (Haskus.Utils.Types.List.Max (Haskus.Format.Binary.Union.MapAlignment fs))) => Haskus.Format.Binary.Storable.StaticStorable (Haskus.Format.Binary.Union.Union fs) -- | Record (similar to C struct) module Haskus.Format.Binary.Record -- | Record data Record (fields :: [*]) -- | Field data Field (name :: Symbol) typ -- | Get record size without the ending padding bytes type family RecordSize (fs :: [*]) (sz :: Nat) -- | Alignment requirement (in bytes) type family Alignment a :: Nat -- | Modulo type family Modulo (a :: Nat) (b :: Nat) :: Nat data Path (fs :: [Symbol]) -- | Get record size recordSize :: forall fs. KnownNat (FullRecordSize fs) => Record fs -> Word -- | Get record alignment recordAlignment :: forall fs. KnownNat (RecordAlignment fs 1) => Record fs -> Word -- | Get a field recordField :: forall (name :: Symbol) a fs. (KnownNat (FieldOffset name fs 0), a ~ FieldType name fs, StaticStorable a) => Record fs -> a -- | Get a field offset recordFieldOffset :: forall (name :: Symbol) fs. KnownNat (FieldOffset name fs 0) => Record fs -> Int -- | Get a field from its path recordFieldPath :: forall path a fs o. (o ~ FieldPathOffset fs path 0, a ~ FieldPathType fs path, KnownNat o, StaticStorable a) => Path path -> Record fs -> a -- | Get a field offset from its path recordFieldPathOffset :: forall path fs o. (o ~ FieldPathOffset fs path 0, KnownNat o) => Path path -> Record fs -> Int -- | Convert a record into a HList recordToList :: forall fs. HFoldr' Extract (Record fs, HList '[]) fs (Record fs, HList fs) => Record fs -> HList fs instance (rec Data.Type.Equality.~ Haskus.Format.Binary.Record.Record fs, b Data.Type.Equality.~ Haskus.Format.Binary.Record.Field name typ, i Data.Type.Equality.~ (rec, Haskus.Utils.HList.HList l2), typ Data.Type.Equality.~ Haskus.Format.Binary.Record.FieldType name fs, GHC.TypeNats.KnownNat (Haskus.Format.Binary.Record.FieldOffset name fs 0), Haskus.Format.Binary.Storable.StaticStorable typ, GHC.TypeLits.KnownSymbol name, r Data.Type.Equality.~ (rec, Haskus.Utils.HList.HList ((GHC.Base.String, typ) : l2))) => Haskus.Utils.HList.Apply Haskus.Format.Binary.Record.Extract (b, i) r instance (Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Record.Extract (Haskus.Format.Binary.Record.Record fs, Haskus.Utils.HList.HList '[]) fs (Haskus.Format.Binary.Record.Record fs, Haskus.Utils.HList.HList fs), GHC.Show.Show (Haskus.Utils.HList.HList fs)) => GHC.Show.Show (Haskus.Format.Binary.Record.Record fs) instance (s Data.Type.Equality.~ Haskus.Format.Binary.Record.FullRecordSize fs, GHC.TypeNats.KnownNat s) => Haskus.Format.Binary.Storable.StaticStorable (Haskus.Format.Binary.Record.Record fs) -- | A memory buffer with a fixed address -- -- A buffer is a strict ByteString but with: -- -- module Haskus.Format.Binary.Buffer -- | A buffer newtype Buffer Buffer :: ByteString -> Buffer -- | Unsafe: be careful if you modify the buffer contents or you may break -- referential transparency withBufferPtr :: Buffer -> (Ptr b -> IO a) -> IO a -- | Buffer size bufferSize :: Buffer -> Word -- | Test if the buffer is empty isBufferEmpty :: Buffer -> Bool -- | Empty buffer emptyBuffer :: Buffer -- | Buffer filled with zero bufferZero :: Word -> Buffer -- | Map bufferMap :: (Word8 -> Word8) -> Buffer -> Buffer -- | Reverse bufferReverse :: Buffer -> Buffer -- | Drop some bytes O(1) bufferDrop :: Word -> Buffer -> Buffer -- | Tail bufferTail :: Buffer -> Buffer -- | Append bufferAppend :: Buffer -> Buffer -> Buffer -- | Cons bufferCons :: Word8 -> Buffer -> Buffer -- | Snoc bufferSnoc :: Buffer -> Word8 -> Buffer -- | Init bufferInit :: Buffer -> Buffer -- | Split on the given Byte values bufferSplitOn :: Word8 -> Buffer -> [Buffer] -- | Head bufferHead :: Buffer -> Word8 -- | Index bufferIndex :: Buffer -> Word -> Word8 -- | Take some bytes O(1) bufferTake :: Word -> Buffer -> Buffer -- | Take some bytes O(n) bufferTakeWhile :: (Word8 -> Bool) -> Buffer -> Buffer -- | Take some bytes O(1) bufferTakeAtMost :: Word -> Buffer -> Buffer -- | Zip two buffers with the given function bufferZipWith :: (Word8 -> Word8 -> Word8) -> Buffer -> Buffer -> Buffer -- | Duplicate a buffer bufferDup :: Buffer -> IO Buffer -- | Peek a storable bufferPeekStorable :: forall a. Storable a => Buffer -> a -- | Peek a storable at the given offset bufferPeekStorableAt :: forall a. Storable a => Buffer -> Word -> a -- | Pop a Storable and return the new buffer bufferPopStorable :: forall a. Storable a => Buffer -> (Buffer, a) -- | Poke a buffer bufferPoke :: Ptr a -> Buffer -> IO () -- | Pack a ByteString bufferPackByteString :: ByteString -> Buffer -- | Pack a list of bytes bufferPackByteList :: [Word8] -> Buffer -- | Pack a Storable bufferPackStorable :: forall a. Storable a => a -> Buffer -- | Pack a list of Storable bufferPackStorableList :: forall a. Storable a => [a] -> Buffer -- | Pack from a pointer (copy) bufferPackPtr :: MonadIO m => Word -> Ptr () -> m Buffer -- | Unpack bufferUnpackByteList :: Buffer -> [Word8] -- | Unpack bufferUnpackByteString :: Buffer -> ByteString -- | Unsafe drop (don't check the size) bufferUnsafeDrop :: Word -> Buffer -> Buffer -- | Unsafe take (don't check the size) bufferUnsafeTake :: Word -> Buffer -> Buffer -- | Unsafe tail (don't check the size) bufferUnsafeTail :: Buffer -> Buffer -- | Unsafe head (don't check the size) bufferUnsafeHead :: Buffer -> Word8 -- | Unsafe last (don't check the size) bufferUnsafeLast :: Buffer -> Word8 -- | Unsafe init (don't check the size) bufferUnsafeInit :: Buffer -> Buffer -- | Unsafe index (don't check the size) bufferUnsafeIndex :: Buffer -> Word -> Word8 -- | Map memory bufferUnsafeMapMemory :: MonadIO m => Word -> Ptr () -> m Buffer -- | Use buffer pointer bufferUnsafeUsePtr :: MonadInIO m => Buffer -> (Ptr () -> Word -> m a) -> m a -- | Pack from a pointer (add finalizer) bufferUnsafePackPtr :: MonadIO m => Word -> Ptr a -> m Buffer -- | Read file bufferReadFile :: MonadIO m => FilePath -> m Buffer -- | Write file bufferWriteFile :: MonadIO m => FilePath -> Buffer -> m () instance GHC.Classes.Ord Haskus.Format.Binary.Buffer.Buffer instance GHC.Classes.Eq Haskus.Format.Binary.Buffer.Buffer instance GHC.Show.Show Haskus.Format.Binary.Buffer.Buffer instance Haskus.Format.Binary.Bits.Bitwise.Bitwise Haskus.Format.Binary.Buffer.Buffer instance Haskus.Format.Binary.Bits.Index.IndexableBits Haskus.Format.Binary.Buffer.Buffer -- | Put monad module Haskus.Format.Binary.Put -- | Put merely lifts Builder into a Writer monad, applied to (). type Put = PutM () -- | Execute Put runPut :: Put -> Buffer -- | Put a buffer putBuffer :: Buffer -> Put -- | Put a ByteString putByteString :: ByteString -> Put -- | Put null bytes putPadding :: Word -> Put -- | Put null bytes to align the given value to the second putPaddingAlign :: Word -> Word -> Put -- | Put a Word8 putWord8 :: Word8 -> Put -- | Put a Word16 little-endian putWord16le :: Word16 -> Put -- | Put a Word16 big-endian putWord16be :: Word16 -> Put -- | Put a Word32 little-endian putWord32le :: Word32 -> Put -- | Put a Word32 big-endian putWord32be :: Word32 -> Put -- | Put a Word64 little-endian putWord64le :: Word64 -> Put -- | Put a Word64 big-endian putWord64be :: Word64 -> Put -- | Buffer list -- -- BufferList is a lazy ByteString module Haskus.Format.Binary.BufferList -- | BufferList newtype BufferList BufferList :: ByteString -> BufferList -- | Convert to a buffer toBuffer :: BufferList -> Buffer -- | Convert from a buffer toBufferList :: Buffer -> BufferList -- | Convert to a lazy ByteString toLazyByteString :: BufferList -> ByteString -- | Buffer builder module Haskus.Format.Binary.BufferBuilder -- | Buffer builder data BufferBuilder -- | Empty buffer builder emptyBufferBuilder :: BufferBuilder -- | Execute a Builder and return the generated chunks as a BufferList. The -- work is performed lazily, i.e., only when a chunk of the BufferList is -- forced. toBufferList :: BufferBuilder -> BufferList -- | Execute a Builder and return the generated chunks as a Buffer. toBuffer :: BufferBuilder -> Buffer -- | Create a Builder denoting the same sequence of bytes as a strict -- ByteString. The Builder inserts large ByteStrings directly, but copies -- small ones to ensure that the generated chunks are large on average. fromBuffer :: Buffer -> BufferBuilder -- | Encode a single unsigned byte as-is. fromWord8 :: Word8 -> BufferBuilder instance GHC.Base.Monoid Haskus.Format.Binary.BufferBuilder.BufferBuilder instance GHC.Base.Semigroup Haskus.Format.Binary.BufferBuilder.BufferBuilder -- | Reverse bits -- -- There are several algorithms performing the same thing here (reversing -- bits into words of different sizes). There are benchmarks for them in -- the "bench" directory. The fastest one for the current architecture -- should be selected below. If you find that another algorithm is faster -- on your architecture, please report it. module Haskus.Format.Binary.Bits.Reverse -- | Data whose bits can be reversed class ReversableBits w reverseBits :: ReversableBits w => w -> w -- | Reverse bits in a Word reverseBitsGeneric :: (FiniteBits a, Integral a, ShiftableBits a, Bitwise a, KnownNat (BitSize a)) => a -> a -- | Obvious recursive version reverseBitsObvious :: forall a. (FiniteBits a, ShiftableBits a, IndexableBits a, Bitwise a, KnownNat (BitSize a), Eq a) => a -> a -- | Reverse bits in a Word8 (3 64-bit operations, modulus division) reverseBits3Ops :: Word8 -> Word8 -- | Reverse bits in a Word8 (4 64-bit operations, no division) reverseBits4Ops :: Word8 -> Word8 -- | Reverse bits using a lookup table reverseBitsTable :: Word8 -> Word8 -- | Reverse bits in a Word8 (7 no 64-bit operations, no division) reverseBits7Ops :: Word8 -> Word8 -- | Parallel recursive version reverseBits5LgN :: forall a. (FiniteBits a, ShiftableBits a, Bitwise a, KnownNat (BitSize a)) => a -> a -- | Convert a function working on Word8 to one working on any Word -- -- The number of bits in the Word must be a multiple of 8 liftReverseBits :: (ShiftableBits a, Bitwise a, FiniteBits a, Integral a, KnownNat (BitSize a)) => (Word8 -> Word8) -> a -> a instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Word.Word8 instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Word.Word16 instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Word.Word32 instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Word.Word64 instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Types.Word instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Int.Int8 instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Int.Int16 instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Int.Int32 instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Int.Int64 instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Types.Int -- | Operations on bits module Haskus.Format.Binary.Bits type Bits a = (Eq a, FiniteBits a, IndexableBits a, ShiftableBits a, Bitwise a, RotatableBits a, KnownNat (BitSize a)) -- | Type representable by a fixed amount of bits class FiniteBits a where { -- | Number of bits type family BitSize a :: Nat; } -- | Number of bits (the value is ignored) bitSize :: (FiniteBits a, Integral i, KnownNat (BitSize a)) => a -> i -- | All bits set to 0 zeroBits :: FiniteBits a => a -- | All bits set to 1 oneBits :: FiniteBits a => a -- | All bits set to 1 oneBits :: (FiniteBits a, Bitwise a) => a -- | Count number of zero bits preceding the most significant set bit countLeadingZeros :: FiniteBits a => a -> Word -- | Count number of zero bits following the least significant set bit countTrailingZeros :: FiniteBits a => a -> Word -- | Type whose bits are indexable class IndexableBits a -- | bit i is a value with the ith bit set -- and all other bits clear. bit :: IndexableBits a => Word -> a -- | bit i is a value with the ith bit set -- and all other bits clear. bit :: (IndexableBits a, Num a, ShiftableBits a) => Word -> a -- | x `setBit` i is the same as x .|. bit i setBit :: IndexableBits a => a -> Word -> a -- | x `setBit` i is the same as x .|. bit i setBit :: (IndexableBits a, Bitwise a) => a -> Word -> a -- | x `clearBit` i is the same as x .&. complement (bit -- i) clearBit :: IndexableBits a => a -> Word -> a -- | x `clearBit` i is the same as x .&. complement (bit -- i) clearBit :: (IndexableBits a, Bitwise a) => a -> Word -> a -- | x `complementBit` i is the same as x `xor` bit i complementBit :: IndexableBits a => a -> Word -> a -- | x `complementBit` i is the same as x `xor` bit i complementBit :: (IndexableBits a, Bitwise a) => a -> Word -> a -- | Return True if the nth bit of the argument is 1 testBit :: IndexableBits a => a -> Word -> Bool -- | Return True if the nth bit of the argument is 1 testBit :: (IndexableBits a, Bitwise a, Num a, Eq a) => a -> Word -> Bool -- | Return the number of set bits popCount :: IndexableBits a => a -> Word -- | Return the number of set bits popCount :: (IndexableBits a, Bitwise a, Num a, Eq a) => a -> Word -- | Bit shifts -- -- Checked means that there is an additional test to ensure that -- the shift offset is valid (less than the bit count). If you are sure -- that the offset is valid, use the "unchecked" version which should be -- faster. -- -- To shift signed numbers, see SignedShiftableBits class methods. class ShiftableBits a -- | Checked right shift shiftR :: ShiftableBits a => a -> Word -> a -- | Checked left shift shiftL :: ShiftableBits a => a -> Word -> a -- | Unchecked right shift uncheckedShiftR :: ShiftableBits a => a -> Word -> a -- | Unchecked left shift uncheckedShiftL :: ShiftableBits a => a -> Word -> a -- | Checked shift to the left if positive, to the right if negative shift :: ShiftableBits a => a -> Int -> a -- | Unchecked shift to the left if positive, to the right if negative uncheckedShift :: ShiftableBits a => a -> Int -> a -- | Signed bit shifts -- -- Signed means that the sign bit (the higher order bit): - -- propagates to the right during right shifts and - keeps its value -- during left shifts (except when all other bits are 0) -- -- Checked means that there is an additional test to ensure that -- the shift offset is valid (less than the bit count). If you are sure -- that the offset is valid, use the "unchecked" version which should be -- faster. class SignedShiftableBits a -- | Checked signed right shift signedShiftR :: SignedShiftableBits a => a -> Word -> a -- | Checked signed left shift signedShiftL :: SignedShiftableBits a => a -> Word -> a -- | Unchecked signed right shift uncheckedSignedShiftR :: SignedShiftableBits a => a -> Word -> a -- | Unchecked signed left shift uncheckedSignedShiftL :: SignedShiftableBits a => a -> Word -> a -- | Checked signed shift to the left if positive, to the right if negative signedShift :: SignedShiftableBits a => a -> Int -> a -- | Unchecked signed shift to the left if positive, to the right if -- negative uncheckedSignedShift :: SignedShiftableBits a => a -> Int -> a -- | Types whose bits can be rotated class RotatableBits a -- | Rotate left if positive, right if negative rotate :: RotatableBits a => a -> Int -> a -- | Rotate left if positive, right if negative rotate :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Int -> a -- | Checked left bit rotation rotateL :: RotatableBits a => a -> Word -> a -- | Checked left bit rotation rotateL :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Word -> a -- | Checked right bit rotation rotateR :: RotatableBits a => a -> Word -> a -- | Checked right bit rotation rotateR :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Word -> a -- | Unchecked rotate left if positive, right if negative uncheckedRotate :: RotatableBits a => a -> Int -> a -- | Unchecked left bit rotation uncheckedRotateL :: RotatableBits a => a -> Word -> a -- | Unchecked left bit rotation uncheckedRotateL :: (RotatableBits a, ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => a -> Word -> a -- | Unchecked right bit rotation uncheckedRotateR :: RotatableBits a => a -> Word -> a -- | Unchecked right bit rotation uncheckedRotateR :: (RotatableBits a, ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => a -> Word -> a -- | Bitwise bit operations class Bitwise a -- | Bitwise "and" (.&.) :: Bitwise a => a -> a -> a -- | Bitwise "or" (.|.) :: Bitwise a => a -> a -> a -- | Bitwise "xor" xor :: Bitwise a => a -> a -> a -- | Complement complement :: Bitwise a => a -> a -- | Data whose bits can be reversed class ReversableBits w reverseBits :: ReversableBits w => w -> w -- | Reverse bits in a Word reverseBitsGeneric :: (FiniteBits a, Integral a, ShiftableBits a, Bitwise a, KnownNat (BitSize a)) => a -> a -- | Reverse the n least important bits of the given value. The -- higher bits are set to 0. reverseLeastBits :: (ShiftableBits a, FiniteBits a, ReversableBits a, KnownNat (BitSize a)) => Word -> a -> a -- | makeMask 3 = 00000111 makeMask :: forall a. (ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => Word -> a -- | Keep only the n least-significant bits of the given value maskLeastBits :: forall a. (ShiftableBits a, FiniteBits a, Bitwise a, KnownNat (BitSize a)) => Word -> a -> a -- | Convert bits into a string composed of '0' and '1' chars bitsToString :: forall a. (FiniteBits a, IndexableBits a, KnownNat (BitSize a)) => a -> String -- | Convert a specified amount of bits into a string composed of '0' and -- '1' chars bitsToStringN :: forall a. IndexableBits a => Word -> a -> String -- | Convert a string of '0' and '1' chars into a word bitsFromString :: Bits a => String -> a -- | `getBitRange bo offset n c` takes n bits at offset in c and put them -- in the least-significant bits of the result getBitRange :: forall b. (ShiftableBits b, ReversableBits b, FiniteBits b, KnownNat (BitSize b), Bitwise b) => BitOrder -> Word -> Word -> b -> b -- | Compute bit offset (equivalent to x mod 8 but faster) bitOffset :: Word -> Word -- | Compute byte offset (equivalent to x div 8 but faster) byteOffset :: Word -> Word -- | Vector with size in the type module Haskus.Format.Binary.Vector -- | Vector with type-checked size data Vector (n :: Nat) a Vector :: Buffer -> Vector a -- | Return the buffer backing the vector vectorBuffer :: Vector n a -> Buffer -- | Reverse a vector vectorReverse :: (KnownNat n, Storable a) => Vector n a -> Vector n a -- | Yield the first n elements take :: forall n m a. KnownNat (SizeOf a * n) => Vector (m + n) a -> Vector n a -- | Drop the first n elements drop :: forall n m a. KnownNat (SizeOf a * n) => Vector (m + n) a -> Vector m a -- | O(1) Index safely into the vector using a type level index. index :: forall i a n. (KnownNat (ElemOffset a i n), Storable a) => Vector n a -> a -- | Convert a list into a vector if the number of elements matches fromList :: forall a (n :: Nat). (KnownNat n, Storable a) => [a] -> Maybe (Vector n a) -- | Take at most n element from the list, then use z fromFilledList :: forall a (n :: Nat). (KnownNat n, Storable a) => a -> [a] -> Vector n a -- | Take at most (n-1) element from the list, then use z fromFilledListZ :: forall a (n :: Nat). (KnownNat n, Storable a) => a -> [a] -> Vector n a -- | Convert a vector into a list toList :: forall a (n :: Nat). (KnownNat n, Storable a) => Vector n a -> [a] -- | Create a vector by replicating a value replicate :: forall a (n :: Nat). (KnownNat n, Storable a) => a -> Vector n a -- | Concat several vectors into a single one concat :: forall l (n :: Nat) a. (n ~ WholeSize l, KnownNat n, Storable a, StaticStorable a, HFoldr StoreVector (IO (Ptr a)) l (IO (Ptr a))) => HList l -> Vector n a -- | Zip two vectors zipWith :: (KnownNat n, Storable a, Storable b, Storable c) => (a -> b -> c) -> Vector n a -> Vector n b -> Vector n c instance (v Data.Type.Equality.~ Haskus.Format.Binary.Vector.Vector n a, r Data.Type.Equality.~ GHC.Types.IO (GHC.Ptr.Ptr a), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat (Haskus.Format.Binary.Storable.SizeOf a), Haskus.Format.Binary.Storable.StaticStorable a, Haskus.Format.Binary.Storable.Storable a) => Haskus.Utils.HList.Apply Haskus.Format.Binary.Vector.StoreVector (v, GHC.Types.IO (GHC.Ptr.Ptr a)) r instance (Haskus.Format.Binary.Storable.Storable a, GHC.Show.Show a, GHC.TypeNats.KnownNat n) => GHC.Show.Show (Haskus.Format.Binary.Vector.Vector n a) instance GHC.TypeNats.KnownNat (Haskus.Format.Binary.Storable.SizeOf a GHC.TypeNats.* n) => Haskus.Format.Binary.Storable.StaticStorable (Haskus.Format.Binary.Vector.Vector n a) instance (GHC.TypeNats.KnownNat n, Haskus.Format.Binary.Storable.Storable a) => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.Vector.Vector n a) instance (GHC.TypeNats.KnownNat n, Haskus.Format.Binary.Storable.Storable a, GHC.Classes.Eq a) => GHC.Classes.Eq (Haskus.Format.Binary.Vector.Vector n a) instance (GHC.TypeNats.KnownNat n, Haskus.Format.Binary.Bits.Bitwise.Bitwise a, Haskus.Format.Binary.Storable.Storable a) => Haskus.Format.Binary.Bits.Bitwise.Bitwise (Haskus.Format.Binary.Vector.Vector n a) instance (GHC.TypeNats.KnownNat (Haskus.Format.Binary.Bits.Finite.BitSize a), Haskus.Format.Binary.Bits.Finite.FiniteBits a, GHC.TypeNats.KnownNat n, Haskus.Format.Binary.Storable.Storable a) => Haskus.Format.Binary.Bits.Finite.FiniteBits (Haskus.Format.Binary.Vector.Vector n a) instance (Haskus.Format.Binary.Storable.Storable a, Haskus.Format.Binary.Bits.Shift.ShiftableBits a, Haskus.Format.Binary.Bits.Bitwise.Bitwise a, Haskus.Format.Binary.Bits.Finite.FiniteBits a, GHC.TypeNats.KnownNat (Haskus.Format.Binary.Bits.Finite.BitSize a), GHC.TypeNats.KnownNat (n GHC.TypeNats.* Haskus.Format.Binary.Bits.Finite.BitSize a), GHC.TypeNats.KnownNat n) => Haskus.Format.Binary.Bits.Shift.ShiftableBits (Haskus.Format.Binary.Vector.Vector n a) instance (Haskus.Format.Binary.Storable.Storable a, Haskus.Format.Binary.Bits.Index.IndexableBits a, Haskus.Format.Binary.Bits.Finite.FiniteBits a, GHC.TypeNats.KnownNat (Haskus.Format.Binary.Bits.Finite.BitSize a), GHC.TypeNats.KnownNat n, Haskus.Format.Binary.Bits.Bitwise.Bitwise a) => Haskus.Format.Binary.Bits.Index.IndexableBits (Haskus.Format.Binary.Vector.Vector n a) instance (Haskus.Format.Binary.Storable.Storable a, Haskus.Format.Binary.Bits.Bits a, GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat (n GHC.TypeNats.* Haskus.Format.Binary.Bits.Finite.BitSize a)) => Haskus.Format.Binary.Bits.Rotate.RotatableBits (Haskus.Format.Binary.Vector.Vector n a) -- | Posit (type III unum) module Haskus.Format.Binary.Posit newtype Posit (nbits :: Nat) (es :: Nat) Posit :: IntN nbits -> Posit data PositKind ZeroK :: PositKind InfinityK :: PositKind NormalK :: PositKind -- | Kinded Posit -- -- GADT that can be used to ensure at the type level that we deal with -- non-infinite/non-zero Posit values data PositK k nbits es [Zero] :: PositK 'ZeroK nbits es [Infinity] :: PositK 'InfinityK nbits es [Value] :: Posit nbits es -> PositK 'NormalK nbits es -- | Get the kind of the posit at the type level positKind :: forall n es. (Bits (IntN n), KnownNat n, Eq (IntN n)) => Posit n es -> SomePosit n es -- | Check if a posit is zero isZero :: forall n es. (Bits (IntN n), Eq (IntN n), KnownNat n) => Posit n es -> Bool -- | Check if a posit is infinity isInfinity :: forall n es. (Bits (IntN n), Eq (IntN n), KnownNat n) => Posit n es -> Bool -- | Check if a posit is positive isPositive :: forall n es. (Bits (IntN n), Ord (IntN n), KnownNat n) => PositValue n es -> Bool -- | Check if a posit is negative isNegative :: forall n es. (Bits (IntN n), Ord (IntN n), KnownNat n) => PositValue n es -> Bool -- | Posit absolute value positAbs :: forall n es. (Num (IntN n), KnownNat n) => PositValue n es -> PositValue n es data PositEncoding PositInfinity :: PositEncoding PositZero :: PositEncoding PositEncoding :: PositFields -> PositEncoding data PositFields PositFields :: Bool -> Word -> Word -> Word -> Int -> Word -> Word -> PositFields [positNegative] :: PositFields -> Bool [positRegimeBitCount] :: PositFields -> Word [positExponentBitCount] :: PositFields -> Word [positFractionBitCount] :: PositFields -> Word [positRegime] :: PositFields -> Int [positExponent] :: PositFields -> Word [positFraction] :: PositFields -> Word positEncoding :: forall n es. (Bits (IntN n), Ord (IntN n), Num (IntN n), KnownNat n, KnownNat es, Integral (IntN n)) => Posit n es -> PositEncoding -- | Decode posit fields positFields :: forall n es. (Bits (IntN n), Ord (IntN n), Num (IntN n), KnownNat n, KnownNat es, Integral (IntN n)) => PositValue n es -> PositFields -- | Convert a Posit into a Rational positToRational :: forall n es. (KnownNat n, KnownNat es, Eq (IntN n), Bits (IntN n), Integral (IntN n)) => Posit n es -> Rational -- | Convert a rational into the approximate Posit positFromRational :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), KnownNat es, KnownNat n) => Rational -> Posit n es -- | Factor of approximation for a given Rational when encoded as a Posit. -- The closer to 1, the better. -- -- Usage: -- -- positApproxFactor @(Posit 8 2) (52 % 137) positApproxFactor :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), Integral (IntN n), KnownNat es, KnownNat n) => Rational -> Double -- | Compute the decimal error if the given Rational is encoded as a Posit. -- -- Usage: -- -- positDecimalError @(Posit 8 2) (52 % 137) positDecimalError :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), Integral (IntN n), KnownNat es, KnownNat n) => Rational -> Double -- | Compute the number of decimals of accuracy if the given Rational is -- encoded as a Posit. -- -- Usage: -- -- positDecimalAccuracy @(Posit 8 2) (52 % 137) positDecimalAccuracy :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), Integral (IntN n), KnownNat es, KnownNat n) => Rational -> Double -- | Compute the binary error if the given Rational is encoded as a Posit. -- -- Usage: -- -- positBinaryError @(Posit 8 2) (52 % 137) positBinaryError :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), Integral (IntN n), KnownNat es, KnownNat n) => Rational -> Double -- | Compute the number of bits of accuracy if the given Rational is -- encoded as a Posit. -- -- Usage: -- -- positBinaryAccuracy @(Posit 8 2) (52 % 137) positBinaryAccuracy :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), Integral (IntN n), KnownNat es, KnownNat n) => Rational -> Double -- | Compute the number of bits of accuracy if the given Rational is -- encoded as a Float/Double. -- -- Usage: -- -- floatBinaryAccuracy @Double (52 % 137) floatBinaryAccuracy :: forall f. (Fractional f, Real f) => Rational -> Double instance GHC.Show.Show Haskus.Format.Binary.Posit.PositEncoding instance GHC.Show.Show Haskus.Format.Binary.Posit.PositFields instance GHC.Classes.Eq Haskus.Format.Binary.Posit.PositKind instance GHC.Show.Show Haskus.Format.Binary.Posit.PositKind instance (Haskus.Format.Binary.Bits.Bits (Haskus.Format.Binary.Word.IntN n), Haskus.Format.Binary.Bits.Finite.FiniteBits (Haskus.Format.Binary.Word.IntN n), GHC.Classes.Ord (Haskus.Format.Binary.Word.IntN n), GHC.Num.Num (Haskus.Format.Binary.Word.IntN n), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat es, GHC.Real.Integral (Haskus.Format.Binary.Word.IntN n)) => GHC.Show.Show (Haskus.Format.Binary.Posit.Posit n es) -- | A bit set based on Enum to name the bits. Use bitwise operations and -- minimal storage in a safer way. -- -- Similar to Data.Bitset.Generic from bitset package, but -- -- -- -- Example: -- --
--   {--}
--   data Flag
--      = FlagXXX
--      | FlagYYY
--      | FlagWWW
--      deriving (Show,Eq,Enum,CBitSet)
--   
--   -- Adapt the backing type, here we choose Word16
--   type Flags = BitSet Word16 Flag
--   
-- -- Then you can convert (for free) a Word16 into Flags with -- fromBits and convert back with toBits. -- -- You can check if a flag is set or not with member and -- notMember and get a list of set flags with toList. You -- can insert or delete flags. You can also perform set -- operations such as union and intersection. module Haskus.Format.Binary.BitSet -- | A bit set: use bitwise operations (fast!) and minimal storage (sizeOf -- basetype) -- -- -- -- The elements in the Enum a are flags corresponding to each bit of b -- starting from the least-significant bit. data BitSet b a -- | Bit set indexed with a class CBitSet a -- | Return the bit offset of an element toBitOffset :: CBitSet a => a -> Word -- | Return the bit offset of an element toBitOffset :: (CBitSet a, Enum a) => a -> Word -- | Return the value associated with a bit offset fromBitOffset :: CBitSet a => Word -> a -- | Return the value associated with a bit offset fromBitOffset :: (CBitSet a, Enum a) => Word -> a -- | Indicate if the set is empty null :: (FiniteBits b, Eq b) => BitSet b a -> Bool -- | Empty bitset empty :: FiniteBits b => BitSet b a -- | Create a BitSet from a single element singleton :: (IndexableBits b, CBitSet a) => a -> BitSet b a -- | Insert an element in the set insert :: (IndexableBits b, CBitSet a) => BitSet b a -> a -> BitSet b a -- | Remove an element from the set delete :: (IndexableBits b, CBitSet a) => BitSet b a -> a -> BitSet b a -- | Unwrap the bitset toBits :: BitSet b a -> b -- | Wrap a bitset fromBits :: (CBitSet a, FiniteBits b) => b -> BitSet b a -- | Test if an element is in the set member :: (CBitSet a, FiniteBits b, IndexableBits b) => BitSet b a -> a -> Bool -- | Test if an element is in the set elem :: (CBitSet a, FiniteBits b, IndexableBits b) => a -> BitSet b a -> Bool -- | Test if an element is not in the set notMember :: (CBitSet a, FiniteBits b, IndexableBits b) => BitSet b a -> a -> Bool -- | Retrieve elements in the set elems :: (CBitSet a, FiniteBits b, IndexableBits b, Eq b) => BitSet b a -> [a] -- | Intersection of two sets intersection :: (FiniteBits b, Bitwise b) => BitSet b a -> BitSet b a -> BitSet b a -- | Intersection of two sets union :: (FiniteBits b, Bitwise b) => BitSet b a -> BitSet b a -> BitSet b a -- | Intersection of several sets unions :: (FiniteBits b, Bitwise b) => [BitSet b a] -> BitSet b a -- | Convert a list of enum elements into a bitset Warning: b must have -- enough bits to store the given elements! (we don't perform any check, -- for performance reason) fromListToBits :: (CBitSet a, FiniteBits b, IndexableBits b, Foldable m) => m a -> b -- | Convert a bitset into a list of Enum elements toListFromBits :: (CBitSet a, FiniteBits b, IndexableBits b, Eq b) => b -> [a] -- | Convert a bitset into a list of Enum elements by testing the Enum -- values successively. -- -- The difference with toListFromBits is that extra values in the -- BitSet will be ignored. enumerateSetBits :: (CBitSet a, FiniteBits b, IndexableBits b, Eq b, Bounded a, Enum a) => b -> [a] -- | Convert a Foldable into a set fromList :: (CBitSet a, IndexableBits b, FiniteBits b, Foldable m) => m a -> BitSet b a -- | Convert a set into a list toList :: (CBitSet a, FiniteBits b, IndexableBits b, Eq b) => BitSet b a -> [a] instance Haskus.Format.Binary.Storable.Storable b => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.BitSet.BitSet b a) instance GHC.Classes.Ord b => GHC.Classes.Ord (Haskus.Format.Binary.BitSet.BitSet b a) instance GHC.Classes.Eq b => GHC.Classes.Eq (Haskus.Format.Binary.BitSet.BitSet b a) instance (GHC.Show.Show a, Haskus.Format.Binary.BitSet.CBitSet a, Haskus.Format.Binary.Bits.Finite.FiniteBits b, Haskus.Format.Binary.Bits.Index.IndexableBits b, GHC.Classes.Eq b) => GHC.Show.Show (Haskus.Format.Binary.BitSet.BitSet b a) instance Haskus.Format.Binary.BitSet.CBitSet GHC.Types.Int instance Haskus.Format.Binary.BitSet.CBitSet GHC.Types.Word instance (Haskus.Format.Binary.Bits.Finite.FiniteBits b, Haskus.Format.Binary.Bits.Index.IndexableBits b, Haskus.Format.Binary.BitSet.CBitSet a, GHC.Classes.Eq b) => GHC.Exts.IsList (Haskus.Format.Binary.BitSet.BitSet b a) -- | Bit fields (as in C) -- -- This module allows you to define bit fields over words. For instance, -- you can have a Word16 split into 3 fields X, Y and Z composed of 5, 9 -- and 2 bits respectively. -- -- X Y Z w :: Word16 |0 0 0 0 0|0 0 0 0 0 0 0 0 0|0 0| -- -- -- You define it as follows: -- --
--   {--}
--   
--   w :: BitFields Word16 '[ BitField 5 X Word8 
--                          , BitField 9 Y Word16
--                          , BitField 2 Z Word8
--                          ]
--   w = BitFields 0x0102
--   
-- -- Note that each field has its own associated type (e.g. Word8 for X and -- Z) that must be large enough to hold the number of bits for the field. -- -- Operations on BitFields expect that the cumulated size of the fields -- is equal to the whole word size: use a padding field if necessary. -- Otherwise you can use unsafe versions of the functions: extractField', -- updateField', withField'. -- -- You can extract and update the value of a field by its name: -- --
--   x = extractField X w
--   z = extractField Z w
--   w' = updateField @Y 0x16 w
--   
-- -- Fields can also be BitSet or EnumField: -- --
--   {--}
--   
--   data A = A0 | A1 | A2 | A3 deriving (Enum,CEnum)
--   
--   data B = B0 | B1 deriving (Enum,CBitSet)
--   
--   w :: BitFields Word16 '[ BitField 5 X (EnumField Word8 A)
--                          , BitField 9 Y Word16
--                          , BitField 2 Z (BitSet Word8 B)
--                          ]
--   w = BitFields 0x0102
--   
module Haskus.Format.Binary.BitField -- | Bit fields on a base type b newtype BitFields b (f :: [*]) BitFields :: b -> BitFields b -- | Get backing word bitFieldsBits :: BitFields b f -> b -- | A field of n bits newtype BitField (n :: Nat) (name :: Symbol) s BitField :: s -> BitField s -- | Get the value of a field extractField :: forall (name :: Symbol) fields b. (KnownNat (Offset name fields), KnownNat (Size name fields), WholeSize fields ~ BitSize b, Bits b, Integral b, Field (Output name fields)) => BitFields b fields -> Output name fields -- | Get the value of a field (without checking sizes) extractField' :: forall (name :: Symbol) fields b. (KnownNat (Offset name fields), KnownNat (Size name fields), Bits b, Integral b, Field (Output name fields)) => BitFields b fields -> Output name fields -- | Set the value of a field updateField :: forall name fields b. (KnownNat (Offset name fields), KnownNat (Size name fields), WholeSize fields ~ BitSize b, Bits b, Integral b, Field (Output name fields)) => Output name fields -> BitFields b fields -> BitFields b fields -- | Set the value of a field (without checking sizes) updateField' :: forall name fields b. (KnownNat (Offset name fields), KnownNat (Size name fields), Bits b, Integral b, Field (Output name fields)) => Output name fields -> BitFields b fields -> BitFields b fields -- | Modify the value of a field withField :: forall name fields b f. (KnownNat (Offset name fields), KnownNat (Size name fields), WholeSize fields ~ BitSize b, Bits b, Integral b, f ~ Output name fields, Field f) => (f -> f) -> BitFields b fields -> BitFields b fields -- | Modify the value of a field (without checking sizes) withField' :: forall (name :: Symbol) fields b f. (KnownNat (Offset name fields), KnownNat (Size name fields), Bits b, Integral b, f ~ Output name fields, Field f) => (f -> f) -> BitFields b fields -> BitFields b fields -- | Get values in a tuple matchFields :: forall l l2 w bs t. (bs ~ BitFields w l, HFoldr' Extract (bs, HList '[]) l (bs, HList l2), HTuple' l2 t) => bs -> t -- | Get field names and values in a tuple matchNamedFields :: forall lt lv ln lnv w bs t. (bs ~ BitFields w lt, HFoldr' Extract (bs, HList '[]) lt (bs, HList lv), HFoldr' Name (HList '[]) lt (HList ln), HZipList ln lv lnv, HTuple' lnv t) => bs -> t class Field f instance Haskus.Format.Binary.Storable.Storable s => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.BitField.BitField n name s) instance Haskus.Format.Binary.Storable.Storable b => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.BitField.BitFields b f) instance (bs Data.Type.Equality.~ Haskus.Format.Binary.BitField.BitFields w l, b Data.Type.Equality.~ Haskus.Format.Binary.BitField.BitField n name s, i Data.Type.Equality.~ Haskus.Utils.HList.HList l2, r Data.Type.Equality.~ Haskus.Utils.HList.HList (GHC.Base.String : l2), GHC.TypeLits.KnownSymbol name) => Haskus.Utils.HList.Apply Haskus.Format.Binary.BitField.Name (b, i) r instance (bs Data.Type.Equality.~ Haskus.Format.Binary.BitField.BitFields w lt, ln Data.Type.Equality.~ Haskus.Utils.Types.List.Replicate (Haskus.Utils.Types.List.Length lt) GHC.Base.String, Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.BitField.Extract (bs, Haskus.Utils.HList.HList '[]) lt (bs, Haskus.Utils.HList.HList (Haskus.Format.Binary.BitField.BitFieldTypes lt)), Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.BitField.Name (Haskus.Utils.HList.HList '[]) lt (Haskus.Utils.HList.HList ln), Haskus.Utils.HList.HZipList ln (Haskus.Format.Binary.BitField.BitFieldTypes lt) lnv, GHC.Show.Show (Haskus.Utils.HList.HList lnv)) => GHC.Show.Show (Haskus.Format.Binary.BitField.BitFields w lt) instance (bs Data.Type.Equality.~ Haskus.Format.Binary.BitField.BitFields w l, b Data.Type.Equality.~ Haskus.Format.Binary.BitField.BitField n name s, i Data.Type.Equality.~ (bs, Haskus.Utils.HList.HList l2), r Data.Type.Equality.~ (bs, Haskus.Utils.HList.HList (Haskus.Format.Binary.BitField.Output name l : l2)), Haskus.Format.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ Haskus.Format.Binary.BitField.WholeSize l, GHC.Real.Integral w, Haskus.Format.Binary.Bits.Bits w, GHC.TypeNats.KnownNat (Haskus.Format.Binary.BitField.Offset name l), GHC.TypeNats.KnownNat (Haskus.Format.Binary.BitField.Size name l), Haskus.Format.Binary.BitField.Field (Haskus.Format.Binary.BitField.Output name l)) => Haskus.Utils.HList.Apply Haskus.Format.Binary.BitField.Extract (b, i) r instance (bs Data.Type.Equality.~ Haskus.Format.Binary.BitField.BitFields w lt, Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.BitField.Extract (bs, Haskus.Utils.HList.HList '[]) lt (bs, Haskus.Utils.HList.HList lt2), GHC.Classes.Eq (Haskus.Utils.HList.HList lt2), lt2 Data.Type.Equality.~ Haskus.Format.Binary.BitField.BitFieldTypes lt) => GHC.Classes.Eq (Haskus.Format.Binary.BitField.BitFields w lt) instance Haskus.Format.Binary.BitField.Field GHC.Types.Bool instance Haskus.Format.Binary.BitField.Field GHC.Types.Word instance Haskus.Format.Binary.BitField.Field GHC.Word.Word8 instance Haskus.Format.Binary.BitField.Field GHC.Word.Word16 instance Haskus.Format.Binary.BitField.Field GHC.Word.Word32 instance Haskus.Format.Binary.BitField.Field GHC.Word.Word64 instance Haskus.Format.Binary.BitField.Field GHC.Types.Int instance Haskus.Format.Binary.BitField.Field GHC.Int.Int8 instance Haskus.Format.Binary.BitField.Field GHC.Int.Int16 instance Haskus.Format.Binary.BitField.Field GHC.Int.Int32 instance Haskus.Format.Binary.BitField.Field GHC.Int.Int64 instance (Haskus.Format.Binary.Bits.Finite.FiniteBits b, GHC.Real.Integral b, Haskus.Format.Binary.BitSet.CBitSet a) => Haskus.Format.Binary.BitField.Field (Haskus.Format.Binary.BitSet.BitSet b a) instance (GHC.Real.Integral b, Haskus.Format.Binary.Enum.CEnum a) => Haskus.Format.Binary.BitField.Field (Haskus.Format.Binary.Enum.EnumField b a) module Haskus.Format.Binary.Unum -- | An Unum -- -- 0 (and its reciprocal) is always included. Numbers have to be >= 1 -- and sorted. -- -- e.g., Unum '[] => 0 .. 0 .. 0 Unum '[I 1] => 0 .. -1 -- .. 0 .. 1 .. 0 Unum '[I 1, I 2] => 0 .. -2 .. -1 .. -2 -- .. 0 .. 2 .. 1 .. 2 .. 0 Unum '[I 1, PI] => 0 .. -PI .. -- -1 .. -PI .. 0 .. PI .. 1 .. PI .. 0 data Unum (xs :: [Type]) class UnumNum a unumLabel :: UnumNum a => a -> String data I (n :: Nat) newtype U u U :: BackingWord u -> U u data Neg a data Rcp a type Infinite = Rcp (I 0) type family Log2 n -- | Compute the precise numbers set type family UnumNumbers x -- | Compute the number of bits required type family UnumSize x -- | Backing word for the unum type family BackingWord x -- | Uncertainty bit data UBit -- | Exact number ExactNumber :: UBit -- | OpenInterval above the exact number OpenInterval :: UBit -- | Size of an unum in bits unumSize :: forall u. KnownNat (UnumSize u) => Word -- | Zero unumZero :: forall u. (Num (BackingWord u), Bits (BackingWord u), Encodable (I 0) u) => U u -- | Infinite unumInfinite :: forall u. (Num (BackingWord u), Bits (BackingWord u), Encodable Infinite u) => U u -- | Encode a number unumEncode :: forall u x i. (i ~ IndexOf (Simplify x) (UnumIndexables u), KnownNat i, Num (BackingWord u), Bits (BackingWord u)) => UBit -> U u unumBits :: forall u. (Bits (BackingWord u), KnownNat (UnumSize u)) => U u -> String -- | Negate a number unumNegate :: forall u. (Bits (BackingWord u), Num (BackingWord u), KnownNat (UnumSize u)) => U u -> U u -- | Reciprocate a number unumReciprocate :: forall u. (Bits (BackingWord u), Num (BackingWord u), KnownNat (UnumSize u)) => U u -> U u -- | Unum labels unumLabels :: forall u v. (HFoldr' GetLabel [String] v [String], v ~ UnumMembers u) => [String] data Sign Positive :: Sign Negative :: Sign NoSign :: Sign -- | Get unum sign unumSign :: forall u. (Bits (BackingWord u), KnownNat (UnumSize u)) => U u -> Sign data SORN u type family SORNBackingWord u -- | Show SORN bits sornBits :: forall u s. (Bits (SORNBackingWord u), KnownNat (UnumSize u), s ~ SORNSize u, KnownNat s) => SORN u -> String -- | Size of a SORN in bits sornSize :: forall u s. (s ~ SORNSize u, KnownNat s) => Word -- | Empty SORN sornEmpty :: Bits (SORNBackingWord u) => SORN u -- | Full SORN sornFull :: forall u. (Bits (SORNBackingWord u), KnownNat (SORNSize u)) => SORN u -- | Full SORN without infinite sornNonInfinite :: forall u. (Bits (SORNBackingWord u), Integral (BackingWord u), Bits (BackingWord u), Encodable Infinite u) => SORN u -- | Full SORN without infinite sornNonZero :: (Bits (SORNBackingWord u), Integral (BackingWord u), Bits (BackingWord u), Encodable (I 0) u) => SORN u -- | SORN singleton sornSingle :: (Integral (BackingWord u), Bits (SORNBackingWord u)) => U u -> SORN u -- | Insert in a SORN sornInsert :: forall u. (Bits (SORNBackingWord u), Integral (BackingWord u)) => SORN u -> U u -> SORN u -- | Test membership in a SORN sornMember :: forall u. (Bits (SORNBackingWord u), Integral (BackingWord u)) => SORN u -> U u -> Bool -- | Remove in a SORN sornRemove :: forall u. (Bits (SORNBackingWord u), Integral (BackingWord u)) => SORN u -> U u -> SORN u -- | Union of two SORNs sornUnion :: forall u. Bits (SORNBackingWord u) => SORN u -> SORN u -> SORN u -- | Intersection of two SORNs sornIntersect :: forall u. Bits (SORNBackingWord u) => SORN u -> SORN u -> SORN u -- | Complement the SORN sornComplement :: Bits (SORNBackingWord u) => SORN u -> SORN u -- | Negate a SORN sornNegate :: forall u. (Bits (SORNBackingWord u), Bits (BackingWord u), Integral (BackingWord u), KnownNat (SORNSize u), KnownNat (UnumSize u)) => SORN u -> SORN u -- | Elements in the SORN sornElems :: forall u s. (s ~ SORNSize u, KnownNat s, Bits (SORNBackingWord u), Num (BackingWord u)) => SORN u -> [U u] -- | Create a SORN from its elements sornFromElems :: (Integral (BackingWord u), Bits (SORNBackingWord u)) => [U u] -> SORN u -- | Create a contiguous SORN from two elements sornFromTo :: forall u. (Integral (BackingWord u), Bits (SORNBackingWord u), Bits (BackingWord u), KnownNat (UnumSize u)) => U u -> U u -> SORN u class SornAdd u -- | Add two Unums sornAddU :: SornAdd u => U u -> U u -> SORN u -- | Add two SORNs sornAdd :: (SornAdd u, KnownNat (SORNSize u), Bits (SORNBackingWord u), Num (BackingWord u)) => SORN u -> SORN u -> SORN u -- | Add a SORN with itself sornAddDep :: (SornAdd u, KnownNat (SORNSize u), Bits (SORNBackingWord u), Num (BackingWord u)) => SORN u -> SORN u -- | Subtract two Unums sornSubU :: (SornAdd u, Bits (BackingWord u), Num (BackingWord u), KnownNat (UnumSize u)) => U u -> U u -> SORN u -- | Subtract two SORNS sornSub :: (SornAdd u, KnownNat (SORNSize u), Bits (SORNBackingWord u), Bits (BackingWord u), Num (BackingWord u), KnownNat (UnumSize u)) => SORN u -> SORN u -> SORN u -- | Subtract a SORN with itself sornSubDep :: (SornAdd u, KnownNat (SORNSize u), Bits (SORNBackingWord u), Bits (BackingWord u), Num (BackingWord u), KnownNat (UnumSize u)) => SORN u -> SORN u newtype CSORN u CSORN :: BitFields (CSORNBackingWord u) '[BitField (UnumSize u) "start" (BackingWord u), BitField (UnumSize u) "count" (BackingWord u)] -> CSORN u -- | Size of a contiguous SORN in bits csornSize :: forall u s. (s ~ CSORNSize u, KnownNat s) => Word -- | Show contiguous SORN bits csornBits :: forall u s. (Bits (CSORNBackingWord u), KnownNat (UnumSize u), s ~ CSORNSize u, KnownNat s) => CSORN u -> String -- | Convert a contiguous SORN into a SORN csornToSorn :: forall u. (KnownNat (UnumSize u), Num (BackingWord u), Integral (BackingWord u), Integral (CSORNBackingWord u), Bits (CSORNBackingWord u), Bits (BackingWord u), Bits (SORNBackingWord u), Field (BackingWord u), KnownNat (SORNSize u), Bits (SORNBackingWord u)) => CSORN u -> SORN u -- | Empty contigiuous SORN csornEmpty :: forall u. Bits (CSORNBackingWord u) => CSORN u -- | Test if a contigiuous SORN is empty csornIsEmpty :: forall u. Bits (CSORNBackingWord u) => CSORN u -> Bool -- | Contiguous SORN build csornFromTo :: forall u. (Num (BackingWord u), Bits (BackingWord u), KnownNat (UnumSize u), KnownNat (SORNSize u), Bits (BackingWord u), Integral (CSORNBackingWord u), Bits (CSORNBackingWord u), Field (BackingWord u), Integral (BackingWord u)) => U u -> U u -> CSORN u -- | Full contiguous SORN csornFull :: forall u. (Bits (CSORNBackingWord u), Integral (CSORNBackingWord u), Integral (BackingWord u), KnownNat (UnumSize u), Field (BackingWord u)) => CSORN u -- | Contiguous SORN singleton csornSingle :: forall u. (Bits (CSORNBackingWord u), Integral (CSORNBackingWord u), Integral (BackingWord u), KnownNat (UnumSize u), Field (BackingWord u)) => U u -> CSORN u instance GHC.Classes.Eq Haskus.Format.Binary.Unum.Sign instance GHC.Show.Show Haskus.Format.Binary.Unum.Sign instance GHC.Classes.Eq Haskus.Format.Binary.Unum.UBit instance GHC.Show.Show Haskus.Format.Binary.Unum.UBit instance (GHC.TypeNats.KnownNat (Haskus.Format.Binary.Unum.SORNSize u), GHC.TypeNats.KnownNat (Haskus.Format.Binary.Unum.UnumSize u), Haskus.Format.Binary.Bits.Bits (Haskus.Format.Binary.Unum.BackingWord u), Haskus.Format.Binary.Bits.Bits (Haskus.Format.Binary.Unum.CSORNBackingWord u), GHC.Real.Integral (Haskus.Format.Binary.Unum.CSORNBackingWord u), GHC.Num.Num (Haskus.Format.Binary.Unum.BackingWord u), GHC.Real.Integral (Haskus.Format.Binary.Unum.BackingWord u), Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Unum.GetLabel [GHC.Base.String] v [GHC.Base.String], Haskus.Format.Binary.BitField.Field (Haskus.Format.Binary.Unum.BackingWord u), Haskus.Format.Binary.Bits.Bits (Haskus.Format.Binary.Unum.SORNBackingWord u), Haskus.Format.Binary.Bits.Bits (Haskus.Format.Binary.Unum.SORNBackingWord u), v Data.Type.Equality.~ Haskus.Format.Binary.Unum.UnumMembers u) => GHC.Show.Show (Haskus.Format.Binary.Unum.CSORN u) instance (GHC.TypeNats.KnownNat (Haskus.Format.Binary.Unum.SORNSize u), Haskus.Format.Binary.Bits.Bits (Haskus.Format.Binary.Unum.SORNBackingWord u), GHC.Num.Num (Haskus.Format.Binary.Unum.BackingWord u), GHC.Real.Integral (Haskus.Format.Binary.Unum.BackingWord u), Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Unum.GetLabel [GHC.Base.String] v [GHC.Base.String], v Data.Type.Equality.~ Haskus.Format.Binary.Unum.UnumMembers u) => GHC.Show.Show (Haskus.Format.Binary.Unum.SORN u) instance GHC.Classes.Eq (Haskus.Format.Binary.Unum.BackingWord u) => GHC.Classes.Eq (Haskus.Format.Binary.Unum.U u) instance (Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Unum.GetLabel [GHC.Base.String] v [GHC.Base.String], v Data.Type.Equality.~ Haskus.Format.Binary.Unum.UnumMembers u, GHC.Real.Integral (Haskus.Format.Binary.Unum.BackingWord u)) => GHC.Show.Show (Haskus.Format.Binary.Unum.U u) instance (Haskus.Format.Binary.Unum.UnumNum a, r Data.Type.Equality.~ [GHC.Base.String]) => Haskus.Utils.HList.Apply Haskus.Format.Binary.Unum.GetLabel (a, [GHC.Base.String]) r instance Haskus.Format.Binary.Unum.UnumNum x => Haskus.Format.Binary.Unum.UnumNum (Haskus.Format.Binary.Unum.Uncertain x) instance Haskus.Format.Binary.Unum.UnumNum x => Haskus.Format.Binary.Unum.UnumNum (Haskus.Format.Binary.Unum.Rcp x) instance Haskus.Format.Binary.Unum.UnumNum x => Haskus.Format.Binary.Unum.UnumNum (Haskus.Format.Binary.Unum.Neg x) instance GHC.TypeNats.KnownNat n => Haskus.Format.Binary.Unum.UnumNum (Haskus.Format.Binary.Unum.I n) -- | Fixed-point numbers module Haskus.Format.Binary.FixedPoint -- | Fixed-point number * w is the backing type * i is -- the number of bits for the integer part (before the radix point) * -- f is the number of bits for the fractional part (after the -- radix point) data FixedPoint w (i :: Nat) (f :: Nat) -- | Convert to a fixed point value toFixedPoint :: forall a w (n :: Nat) (d :: Nat). (RealFrac a, BitSize w ~ (n + d), KnownNat n, KnownNat d, Bits w, Field w, Num w, Integral w) => a -> FixedPoint w n d -- | Convert from a fixed-point value fromFixedPoint :: forall a w (n :: Nat) (d :: Nat). (RealFrac a, BitSize w ~ (n + d), KnownNat n, KnownNat d, Bits w, Field w, Num w, Integral w) => FixedPoint w n d -> a instance Haskus.Format.Binary.Storable.Storable w => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.FixedPoint.FixedPoint w i f) instance (GHC.Real.Integral w, Haskus.Format.Binary.Bits.Bits w, Haskus.Format.Binary.BitField.Field w, Haskus.Format.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ (n GHC.TypeNats.+ d), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat d) => GHC.Classes.Eq (Haskus.Format.Binary.FixedPoint.FixedPoint w n d) instance (GHC.Real.Integral w, Haskus.Format.Binary.Bits.Bits w, Haskus.Format.Binary.BitField.Field w, Haskus.Format.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ (n GHC.TypeNats.+ d), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat d, GHC.Show.Show w) => GHC.Show.Show (Haskus.Format.Binary.FixedPoint.FixedPoint w n d) -- | Bit putter module Haskus.Format.Binary.Bits.Put -- | BitPut state data BitPutState BitPutState :: !BufferBuilder -> !Word8 -> !Word -> !BitOrder -> BitPutState -- | Builder [bitPutStateBuilder] :: BitPutState -> !BufferBuilder -- | Current byte [bitPutStateCurrent] :: BitPutState -> !Word8 -- | Current offset [bitPutStateOffset] :: BitPutState -> !Word -- | Bit order [bitPutStateBitOrder] :: BitPutState -> !BitOrder -- | Create a new BitPut state newBitPutState :: BitOrder -> BitPutState -- | Put bits putBits :: (Integral a, Bits a, ReversableBits a) => Word -> a -> BitPutState -> BitPutState -- | Put a Buffer -- -- Examples: 3 bits are already written in the current byte BB: -- ABCDEFGH IJKLMNOP -> xxxABCDE FGHIJKLM NOPxxxxx LL: -- ABCDEFGH IJKLMNOP -> LMNOPxxx DEFGHIJK xxxxxABC BL: -- ABCDEFGH IJKLMNOP -> xxxPONML KJIHGFED CBAxxxxx LB: -- ABCDEFGH IJKLMNOP -> EDCBAxxx MLKJIHGF xxxxxPON putBitsBuffer :: Buffer -> BitPutState -> BitPutState -- | Get a Buffer getBitPutBuffer :: BitPutState -> Buffer -- | Get a buffer list getBitPutBufferList :: BitPutState -> BufferList -- | BitPut monad type BitPut a = BitPutT Identity a -- | BitPut monad transformer type BitPutT m a = StateT BitPutState m a -- | Evaluate a BitPut monad runBitPut :: BitOrder -> BitPut a -> Buffer -- | Evaluate a BitPut monad runBitPutT :: Monad m => BitOrder -> BitPutT m a -> m Buffer -- | Put bits (monadic) putBitsM :: (Monad m, Integral a, Bits a, ReversableBits a) => Word -> a -> BitPutT m () -- | Put a single bit (monadic) putBitBoolM :: Monad m => Bool -> BitPutT m () -- | Put a Buffer (monadic) putBitsBufferM :: Monad m => Buffer -> BitPutT m () -- | Change the current bit ordering -- -- Be careful to change the outer bit ordering (B* to L* or the inverse) -- only on bytes boundaries! Otherwise, you will write the same bits more -- than once. changeBitPutOrder :: Monad m => BitOrder -> BitPutT m () -- | Change the bit ordering for the wrapped BitPut -- -- Be careful, this function uses changeBitPutOrder internally. withBitPutOrder :: Monad m => BitOrder -> BitPutT m a -> BitPutT m a -- | Bit getter module Haskus.Format.Binary.Bits.Get -- | BitGet state data BitGetState BitGetState :: {-# UNPACK #-} !Buffer -> {-# UNPACK #-} !Word -> !BitOrder -> BitGetState -- | Input [bitGetStateInput] :: BitGetState -> {-# UNPACK #-} !Buffer -- | Bit offset (0-7) [bitGetStateBitOffset] :: BitGetState -> {-# UNPACK #-} !Word -- | Bit order [bitGetStateBitOrder] :: BitGetState -> !BitOrder -- | Create a new BitGetState newBitGetState :: BitOrder -> Buffer -> BitGetState -- | Indicate that the source is empty isEmpty :: BitGetState -> Bool -- | Skip the given number of bits from the input skipBits :: Word -> BitGetState -> BitGetState -- | Skip the required number of bits to be aligned on 8-bits skipBitsToAlignOnWord8 :: BitGetState -> BitGetState -- | Read the given number of bits and put the result in a word getBits :: (Integral a, Bits a) => Word -> BitGetState -> a -- | Perform some checks before calling getBits -- -- Check that the number of bits to read is not greater than the first -- parameter getBitsChecked :: (Integral a, Bits a, ReversableBits a) => Word -> Word -> BitGetState -> a -- | Read the given number of Word8 and return them in a Buffer -- -- Examples: BB: xxxABCDE FGHIJKLM NOPxxxxx -> ABCDEFGH IJKLMNOP -- LL: LMNOPxxx DEFGHIJK xxxxxABC -> ABCDEFGH IJKLMNOP -- BL: xxxPONML KJIHGFED CBAxxxxx -> ABCDEFGH IJKLMNOP -- LB: EDCBAxxx MLKJIHGF xxxxxPON -> ABCDEFGH IJKLMNOP -- getBitsBuffer :: Word -> BitGetState -> Buffer -- | BitGet monad type BitGet a = BitGetT Identity a -- | BitGet monad transformer type BitGetT m a = StateT BitGetState m a -- | Evaluate a BitGet monad runBitGet :: BitOrder -> BitGet a -> Buffer -> a -- | Evaluate a BitGet monad runBitGetT :: Monad m => BitOrder -> BitGetT m a -> Buffer -> m a -- | Evaluate a BitGet monad, return the remaining state runBitGetPartialT :: BitOrder -> BitGetT m a -> Buffer -> m (a, BitGetState) -- | Evaluate a BitGet monad, return the remaining state runBitGetPartial :: BitOrder -> BitGet a -> Buffer -> (a, BitGetState) -- | Resume a BitGet evaluation resumeBitGetPartialT :: BitGetT m a -> BitGetState -> m (a, BitGetState) -- | Resume a BitGet evaluation resumeBitGetPartial :: BitGet a -> BitGetState -> (a, BitGetState) -- | Indicate if all bits have been read isEmptyM :: Monad m => BitGetT m Bool -- | Skip the given number of bits from the input (monadic version) skipBitsM :: Monad m => Word -> BitGetT m () -- | Skip the required number of bits to be aligned on 8-bits (monadic -- version) skipBitsToAlignOnWord8M :: Monad m => BitGetT m () -- | Read the given number of bits and put the result in a word getBitsM :: (Integral a, Bits a, Monad m) => Word -> BitGetT m a -- | Perform some checks before calling getBitsM getBitsCheckedM :: (Integral a, Bits a, ReversableBits a, Monad m) => Word -> Word -> BitGetT m a -- | Get a bit and convert it into a Bool getBitBoolM :: Monad m => BitGetT m Bool -- | Get the given number of Word8 getBitsBSM :: Monad m => Word -> BitGetT m Buffer -- | Change the current bit ordering -- -- Be careful to change the outer bit ordering (B* to L* or the inverse) -- only on bytes boundaries! Otherwise, you will read the same bits more -- than once. changeBitGetOrder :: Monad m => BitOrder -> BitGetT m () -- | Change the bit ordering for the wrapped BitGet -- -- Be careful, this function uses changeBitGetOrder internally. withBitGetOrder :: Monad m => BitOrder -> BitGetT m a -> BitGetT m a instance GHC.Show.Show Haskus.Format.Binary.Bits.Get.BitGetState -- | Get utilities module Haskus.Format.Binary.Get -- | The Get monad is an Exception and State monad. data Get a -- | Run the Get monad runGet :: Get a -> Buffer -> Either String a -- | Run a getter and throw an exception on error runGetOrFail :: Get a -> Buffer -> a -- | Test whether all input *in the current chunk* has been consumed isEmpty :: Get Bool -- | Get the number of remaining unparsed bytes *in the current chunk* remaining :: Get Word -- | Skip ahead n bytes. Fails if fewer than n bytes are available. skip :: Word -> Get () -- | Skip ahead n bytes. No error if there isn't enough bytes. uncheckedSkip :: Word -> Get () -- | Skip to align n to al. Fails if fewer than n bytes are available. skipAlign :: Word -> Word -> Get () -- | Skip to align n to al. Fails if fewer than n bytes are available. uncheckedSkipAlign :: Word -> Word -> Get () -- | Count the number of bytes consumed by a getter countBytes :: Get a -> Get (Word, a) -- | Execute the getter and align on the given number of Word8 alignAfter :: Word -> Get a -> Get a -- | Require an action to consume exactly the given number of bytes, fail -- otherwise consumeExactly :: Word -> Get a -> Get a -- | Require an action to consume at most the given number of bytes, fail -- otherwise consumeAtMost :: Word -> Get a -> Get a -- | Run the getter without consuming its input. Fails if it fails lookAhead :: Get a -> Get a -- | Run the getter. Consume its input if Just _ returned. Fails if it -- fails lookAheadM :: Get (Maybe a) -> Get (Maybe a) -- | Run the getter. Consume its input if Right _ returned. Fails if it -- fails lookAheadE :: Get (Either a b) -> Get (Either a b) -- | Get remaining bytes getRemaining :: Get Buffer -- | Pull n bytes from the input, as a Buffer getBuffer :: Word -> Get Buffer -- | Get Buffer terminated with 0 (consume 0) getBufferNul :: Get Buffer -- | Get Word8 getWord8 :: Get Word8 -- | Get Word16 little-endian getWord16le :: Get Word16 -- | Get Word16 big-endian getWord16be :: Get Word16 -- | Get Word32 little-endian getWord32le :: Get Word32 -- | Get Word32 big-endian getWord32be :: Get Word32 -- | Get Word64 little-endian getWord64le :: Get Word64 -- | Get Word64 big-endian getWord64be :: Get Word64 -- | Get while True (read and discard the ending element) getWhile :: (a -> Bool) -> Get a -> Get [a] -- | Repeat the getter to read the whole bytestring getWhole :: Get a -> Get [a] -- | Get bits from a BitGet. -- -- Discard last bits to align on a Word8 boundary -- -- FIXME: we use a continuation because Data.Serialize.Get doesn't export -- "put" getBitGet :: BitOrder -> BitGet a -> (a -> Get b) -> Get b -- | Apply the getter at most max times getManyAtMost :: Word -> Get (Maybe a) -> Get [a] -- | Apply the getter at least min times and at most max -- times getManyBounded :: Maybe Word -> Maybe Word -> Get (Maybe a) -> Get (Maybe [a]) -- | Variable length encodings module Haskus.Format.Binary.VariableLength -- | Get an unsigned word in Little Endian Base 128 getULEB128 :: (Integral a, Bits a) => Get a -- | Put an unsigned word in Little Endian Base 128 putULEB128 :: (Integral a, Bits a) => a -> Put -- | Get a signed int in Little Endian Base 128 getSLEB128 :: (Integral a, Bits a) => Get a -- | Put a signed int in Little Endian Base 128 putSLEB128 :: (Integral a, Bits a) => a -> Put -- | Get a bytestring containing a decoded LEB128 string getLEB128Buffer :: BitOrder -> Get Buffer -- | Byte order ("endianness") -- -- Indicate in which order bytes are stored in memory for multi-bytes -- types. Big-endian means that most-significant bytes come first. -- Little-endian means that least-significant bytes come first. module Haskus.Format.Binary.Endianness -- | Endianness data Endianness -- | Less significant bytes first LittleEndian :: Endianness -- | Most significant bytes first BigEndian :: Endianness -- | Word getter data WordGetters WordGetters :: Get Word8 -> Get Word16 -> Get Word32 -> Get Word64 -> WordGetters -- | Read a Word8 [wordGetter8] :: WordGetters -> Get Word8 -- | Read a Word16 [wordGetter16] :: WordGetters -> Get Word16 -- | Read a Word32 [wordGetter32] :: WordGetters -> Get Word32 -- | Read a Word64 [wordGetter64] :: WordGetters -> Get Word64 -- | Word putters data WordPutters WordPutters :: (Word8 -> Put) -> (Word16 -> Put) -> (Word32 -> Put) -> (Word64 -> Put) -> WordPutters -- | Write a Word8 [wordPutter8] :: WordPutters -> Word8 -> Put -- | Write a Word16 [wordPutter16] :: WordPutters -> Word16 -> Put -- | Write a Word32 [wordPutter32] :: WordPutters -> Word32 -> Put -- | Write a Word64 [wordPutter64] :: WordPutters -> Word64 -> Put -- | Get getters for the given endianness getWordGetters :: Endianness -> WordGetters -- | Get putters for the given endianness getWordPutters :: Endianness -> WordPutters -- | Size of a machine word data WordSize -- | 32-bit WordSize32 :: WordSize -- | 64-bit WordSize64 :: WordSize -- | Extended word getters data ExtendedWordGetters ExtendedWordGetters :: Get Word8 -> Get Word16 -> Get Word32 -> Get Word64 -> Get Word64 -> ExtendedWordGetters -- | Read a Word8 [extwordGetter8] :: ExtendedWordGetters -> Get Word8 -- | Read a Word16 [extwordGetter16] :: ExtendedWordGetters -> Get Word16 -- | Read a Word32 [extwordGetter32] :: ExtendedWordGetters -> Get Word32 -- | Read a Word64 [extwordGetter64] :: ExtendedWordGetters -> Get Word64 -- | Read a native size word into a Word64 [extwordGetterN] :: ExtendedWordGetters -> Get Word64 -- | Extended word putters data ExtendedWordPutters ExtendedWordPutters :: (Word8 -> Put) -> (Word16 -> Put) -> (Word32 -> Put) -> (Word64 -> Put) -> (Word64 -> Put) -> ExtendedWordPutters -- | Write a Word8 [extwordPutter8] :: ExtendedWordPutters -> Word8 -> Put -- | Write a Word16 [extwordPutter16] :: ExtendedWordPutters -> Word16 -> Put -- | Write a Word32 [extwordPutter32] :: ExtendedWordPutters -> Word32 -> Put -- | Write a Word64 [extwordPutter64] :: ExtendedWordPutters -> Word64 -> Put -- | Write a Word64 into a native size word [extwordPutterN] :: ExtendedWordPutters -> Word64 -> Put -- | Return extended getters getExtendedWordGetters :: Endianness -> WordSize -> ExtendedWordGetters -- | Return extended putters getExtendedWordPutters :: Endianness -> WordSize -> ExtendedWordPutters -- | Detect the endianness of the host memory getHostEndianness :: IO Endianness -- | Detected host endianness -- -- TODO: use targetByteOrder in GHC.ByteOrder (should be introduced in -- GHC 8.4) hostEndianness :: Endianness -- | Reverse bytes in a word class ByteReversable w reverseBytes :: ByteReversable w => w -> w hostToBigEndian :: ByteReversable w => w -> w bigEndianToHost :: ByteReversable w => w -> w hostToLittleEndian :: ByteReversable w => w -> w littleEndianToHost :: ByteReversable w => w -> w -- | Force a data to be read/stored as big-endian newtype AsBigEndian a AsBigEndian :: a -> AsBigEndian a -- | Force a data to be read/stored as little-endian newtype AsLittleEndian a AsLittleEndian :: a -> AsLittleEndian a instance Haskus.Format.Binary.Bits.Index.IndexableBits a => Haskus.Format.Binary.Bits.Index.IndexableBits (Haskus.Format.Binary.Endianness.AsLittleEndian a) instance Haskus.Format.Binary.Bits.Shift.ShiftableBits a => Haskus.Format.Binary.Bits.Shift.ShiftableBits (Haskus.Format.Binary.Endianness.AsLittleEndian a) instance Haskus.Format.Binary.Bits.Rotate.RotatableBits a => Haskus.Format.Binary.Bits.Rotate.RotatableBits (Haskus.Format.Binary.Endianness.AsLittleEndian a) instance Haskus.Format.Binary.Bits.Reverse.ReversableBits a => Haskus.Format.Binary.Bits.Reverse.ReversableBits (Haskus.Format.Binary.Endianness.AsLittleEndian a) instance Haskus.Format.Binary.Bits.Finite.FiniteBits a => Haskus.Format.Binary.Bits.Finite.FiniteBits (Haskus.Format.Binary.Endianness.AsLittleEndian a) instance Haskus.Format.Binary.Bits.Bitwise.Bitwise a => Haskus.Format.Binary.Bits.Bitwise.Bitwise (Haskus.Format.Binary.Endianness.AsLittleEndian a) instance GHC.Real.Real a => GHC.Real.Real (Haskus.Format.Binary.Endianness.AsLittleEndian a) instance GHC.Real.Integral a => GHC.Real.Integral (Haskus.Format.Binary.Endianness.AsLittleEndian a) instance GHC.Num.Num a => GHC.Num.Num (Haskus.Format.Binary.Endianness.AsLittleEndian a) instance GHC.Enum.Enum a => GHC.Enum.Enum (Haskus.Format.Binary.Endianness.AsLittleEndian a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Haskus.Format.Binary.Endianness.AsLittleEndian a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Haskus.Format.Binary.Endianness.AsLittleEndian a) instance Haskus.Format.Binary.Bits.Index.IndexableBits a => Haskus.Format.Binary.Bits.Index.IndexableBits (Haskus.Format.Binary.Endianness.AsBigEndian a) instance Haskus.Format.Binary.Bits.Shift.ShiftableBits a => Haskus.Format.Binary.Bits.Shift.ShiftableBits (Haskus.Format.Binary.Endianness.AsBigEndian a) instance Haskus.Format.Binary.Bits.Rotate.RotatableBits a => Haskus.Format.Binary.Bits.Rotate.RotatableBits (Haskus.Format.Binary.Endianness.AsBigEndian a) instance Haskus.Format.Binary.Bits.Reverse.ReversableBits a => Haskus.Format.Binary.Bits.Reverse.ReversableBits (Haskus.Format.Binary.Endianness.AsBigEndian a) instance Haskus.Format.Binary.Bits.Finite.FiniteBits a => Haskus.Format.Binary.Bits.Finite.FiniteBits (Haskus.Format.Binary.Endianness.AsBigEndian a) instance Haskus.Format.Binary.Bits.Bitwise.Bitwise a => Haskus.Format.Binary.Bits.Bitwise.Bitwise (Haskus.Format.Binary.Endianness.AsBigEndian a) instance GHC.Real.Real a => GHC.Real.Real (Haskus.Format.Binary.Endianness.AsBigEndian a) instance GHC.Real.Integral a => GHC.Real.Integral (Haskus.Format.Binary.Endianness.AsBigEndian a) instance GHC.Num.Num a => GHC.Num.Num (Haskus.Format.Binary.Endianness.AsBigEndian a) instance GHC.Enum.Enum a => GHC.Enum.Enum (Haskus.Format.Binary.Endianness.AsBigEndian a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Haskus.Format.Binary.Endianness.AsBigEndian a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Haskus.Format.Binary.Endianness.AsBigEndian a) instance GHC.Classes.Eq Haskus.Format.Binary.Endianness.WordSize instance GHC.Show.Show Haskus.Format.Binary.Endianness.WordSize instance GHC.Enum.Enum Haskus.Format.Binary.Endianness.Endianness instance GHC.Show.Show Haskus.Format.Binary.Endianness.Endianness instance GHC.Classes.Eq Haskus.Format.Binary.Endianness.Endianness instance GHC.Show.Show a => GHC.Show.Show (Haskus.Format.Binary.Endianness.AsLittleEndian a) instance (Haskus.Format.Binary.Endianness.ByteReversable a, Haskus.Format.Binary.Storable.StaticStorable a) => Haskus.Format.Binary.Storable.StaticStorable (Haskus.Format.Binary.Endianness.AsLittleEndian a) instance (Haskus.Format.Binary.Endianness.ByteReversable a, Haskus.Format.Binary.Storable.Storable a) => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.Endianness.AsLittleEndian a) instance GHC.Show.Show a => GHC.Show.Show (Haskus.Format.Binary.Endianness.AsBigEndian a) instance (Haskus.Format.Binary.Endianness.ByteReversable a, Haskus.Format.Binary.Storable.StaticStorable a) => Haskus.Format.Binary.Storable.StaticStorable (Haskus.Format.Binary.Endianness.AsBigEndian a) instance (Haskus.Format.Binary.Endianness.ByteReversable a, Haskus.Format.Binary.Storable.Storable a) => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.Endianness.AsBigEndian a) instance Haskus.Format.Binary.Endianness.ByteReversable GHC.Word.Word8 instance Haskus.Format.Binary.Endianness.ByteReversable GHC.Word.Word16 instance Haskus.Format.Binary.Endianness.ByteReversable GHC.Word.Word32 instance Haskus.Format.Binary.Endianness.ByteReversable GHC.Word.Word64 instance Haskus.Format.Binary.Enum.CEnum Haskus.Format.Binary.Endianness.Endianness