-- 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.3 -- | 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 dataToTag 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 . dataToTag class CEnum a fromCEnum :: (CEnum 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 -- | Retrieve data tag -- --
--   >>> data D = A | B | C
--   
--   >>> dataToTag B
--   1
--   
dataToTag :: a -> Int 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 -- | A buffer in memory module Haskus.Memory.Buffer data Buffer (mut :: Mutability) (pin :: Pinning) (fin :: Finalization) (heap :: Heap) [Buffer] :: {-# UNPACK #-} !ByteArray -> BufferI [BufferP] :: {-# UNPACK #-} !ByteArray -> BufferP [BufferM] :: {-# UNPACK #-} !MutableByteArray RealWorld -> BufferM [BufferMP] :: {-# UNPACK #-} !MutableByteArray RealWorld -> BufferMP [BufferME] :: Addr# -> {-# UNPACK #-} !Word -> BufferME [BufferE] :: Addr# -> {-# UNPACK #-} !Word -> BufferE [BufferF] :: {-# UNPACK #-} !ByteArray -> {-# UNPACK #-} !Finalizers -> BufferF [BufferPF] :: {-# UNPACK #-} !ByteArray -> {-# UNPACK #-} !Finalizers -> BufferPF [BufferMF] :: {-# UNPACK #-} !MutableByteArray RealWorld -> {-# UNPACK #-} !Finalizers -> BufferMF [BufferMPF] :: {-# UNPACK #-} !MutableByteArray RealWorld -> {-# UNPACK #-} !Finalizers -> BufferMPF [BufferMEF] :: Addr# -> {-# UNPACK #-} !Word -> {-# UNPACK #-} !Finalizers -> BufferMEF [BufferEF] :: Addr# -> {-# UNPACK #-} !Word -> {-# UNPACK #-} !Finalizers -> BufferEF -- | A buffer with an additional phantom type indicating its binary format newtype TypedBuffer (t :: k) mut pin fin heap TypedBuffer :: Buffer mut pin fin heap -> TypedBuffer mut pin fin heap -- | Wrapper containing any kind of buffer newtype AnyBuffer AnyBuffer :: (forall mut pin fin heap. Buffer mut pin fin heap) -> AnyBuffer -- | Is the buffer pinned into memory? data Pinning -- | The buffer has a fixed associated memory address Pinned :: Pinning -- | The buffer contents can be freely moved to another address NotPinned :: Pinning -- | Is the buffer automatically garbage collected? data Finalization -- | Automatically collected by the garbage-collector Collected :: Finalization -- | Finalizers are run just before the garbage collector collects the -- buffer entity. The memory used by the buffer may be collected too -- (Internal heap), explicitly freed by a finalizer or not freed at all. Finalized :: Finalization -- | The buffer contents is not automatically freed and we can't attach -- finalizers to the buffer. NotFinalized :: Finalization -- | Is the buffer mutable or not? data Mutability -- | Memory cells are mutable Mutable :: Mutability -- | Memory cells are immutable Immutable :: Mutability -- | Allocation heap data Heap -- | GHC heap Internal :: Heap -- | External heap External :: Heap type BufferI = Buffer 'Immutable 'NotPinned 'Collected 'Internal type BufferP = Buffer 'Immutable 'Pinned 'Collected 'Internal type BufferM = Buffer 'Mutable 'NotPinned 'Collected 'Internal type BufferMP = Buffer 'Mutable 'Pinned 'Collected 'Internal type BufferME = Buffer 'Mutable 'Pinned 'NotFinalized 'External type BufferE = Buffer 'Immutable 'Pinned 'NotFinalized 'External type BufferF = Buffer 'Immutable 'NotPinned 'Finalized 'Internal type BufferPF = Buffer 'Immutable 'Pinned 'Finalized 'Internal type BufferMF = Buffer 'Mutable 'NotPinned 'Finalized 'Internal type BufferMPF = Buffer 'Mutable 'Pinned 'Finalized 'Internal type BufferMEF = Buffer 'Mutable 'Pinned 'Finalized 'External type BufferEF = Buffer 'Immutable 'Pinned 'Finalized 'External -- | Allocate a buffer (mutable, unpinned) -- --
--   >>> b <- newBuffer 1024
--   
newBuffer :: MonadIO m => Word -> m BufferM -- | Allocate a buffer (mutable, pinned) newPinnedBuffer :: MonadIO m => Word -> m BufferMP -- | Allocate an aligned buffer (mutable, pinned) newAlignedPinnedBuffer :: MonadIO m => Word -> Word -> m BufferMP -- | Get buffer size bufferSizeIO :: MonadIO m => Buffer mut pin fin heap -> m Word class BufferSize a -- | Get buffer size bufferSize :: BufferSize a => a -> Word -- | Buffer that can be frozen (converted from mutable to immutable) class Freezable a b | a -> b -- | Convert a mutable buffer to an immutable one without copying. The -- buffer should not be modified after the conversion. unsafeBufferFreeze :: (Freezable a b, MonadIO m) => a -> m b -- | Buffer that can be thawed (converted from immutable to mutable) class Thawable a b | a -> b -- | Convert an immutable buffer to a mutable one without copying. The -- original buffer should not be used after the conversion. unsafeBufferThaw :: (Thawable a b, MonadIO m) => a -> m b -- | Some buffers managed by GHC can be pinned as an optimization. This -- function reports this. bufferIsDynamicallyPinned :: Buffer mut pin fin heap -> Bool -- | Transform type-level NotPinned buffers into type-level Pinned if the -- buffer is dynamically pinned (see bufferIsDynamicallyPinned). bufferDynamicallyPinned :: Buffer mut pin fin heap -> Either (Buffer mut 'NotPinned fin heap) (Buffer mut 'Pinned fin heap) -- | Do something with a buffer address withBufferAddr# :: MonadIO m => Buffer 'Mutable 'Pinned fin heap -> (Addr# -> m a) -> m a -- | Do something with a buffer pointer withBufferPtr :: MonadIO m => Buffer 'Mutable 'Pinned fin heap -> (Ptr b -> m a) -> m a -- | Do something with a buffer address -- -- Note: don't write into immutable buffer as it would break referential -- consistency unsafeWithBufferAddr# :: MonadIO m => Buffer mut 'Pinned fin heap -> (Addr# -> m a) -> m a -- | Do something with a buffer pointer -- -- Note: don't write into immutable buffer as it would break referential -- consistency unsafeWithBufferPtr :: MonadIO m => Buffer mut 'Pinned fin heap -> (Ptr b -> m a) -> m a -- | Read a Word8, offset in bytes -- -- We don't check that the offset is valid -- --
--   >>> let b = [25,26,27,28] :: BufferI
--   
--   >>> bufferReadWord8IO b 2
--   27
--   
bufferReadWord8IO :: MonadIO m => Buffer mut pin fin heap -> Word -> m Word8 -- | Read a Word8 in an immutable buffer, offset in bytes -- -- We don't check that the offset is valid -- --
--   >>> let b = [25,26,27,28] :: BufferI
--   
--   >>> putStrLn $ "Word8 at offset 2 is " ++ show (bufferReadWord8 b 2)
--   Word8 at offset 2 is 27
--   
bufferReadWord8 :: Buffer 'Immutable pin fin heap -> Word -> Word8 -- | Read a Word16, offset in bytes -- -- We don't check that the offset is valid -- --
--   >>> let b = [0x12,0x34,0x56,0x78] :: BufferI
--   
--   >>> x <- bufferReadWord16IO b 0
--   
--   >>> (x == 0x1234) || (x == 0x3412)
--   True
--   
bufferReadWord16IO :: MonadIO m => Buffer mut pin fin heap -> Word -> m Word16 -- | Read a Word16 in an immutable buffer, offset in bytes -- -- We don't check that the offset is valid bufferReadWord16 :: Buffer 'Immutable pin fin heap -> Word -> Word16 -- | Read a Word32, offset in bytes -- -- We don't check that the offset is valid -- --
--   >>> let b = [0x12,0x34,0x56,0x78] :: BufferI
--   
--   >>> x <- bufferReadWord32IO b 0
--   
--   >>> (x == 0x12345678) || (x == 0x78563412)
--   True
--   
bufferReadWord32IO :: MonadIO m => Buffer mut pin fin heap -> Word -> m Word32 -- | Read a Word32 in an immutable buffer, offset in bytes -- -- We don't check that the offset is valid bufferReadWord32 :: Buffer 'Immutable pin fin heap -> Word -> Word32 -- | Read a Word64, offset in bytes -- -- We don't check that the offset is valid -- --
--   >>> let b = [0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0] :: BufferI
--   
--   >>> x <- bufferReadWord64IO b 0
--   
--   >>> (x == 0x123456789ABCDEF0) || (x == 0xF0DEBC9A78563412)
--   True
--   
bufferReadWord64IO :: MonadIO m => Buffer mut pin fin heap -> Word -> m Word64 -- | Read a Word64 in an immutable buffer, offset in bytes -- -- We don't check that the offset is valid bufferReadWord64 :: Buffer 'Immutable pin fin heap -> Word -> Word64 -- | Write a Word8, offset in bytes -- -- We don't check that the offset is valid -- --
--   >>> b <- newBuffer 10
--   
--   >>> bufferWriteWord8IO b 1 123
--   
--   >>> bufferReadWord8IO b 1
--   123
--   
bufferWriteWord8IO :: MonadIO m => Buffer 'Mutable pin fin heap -> Word -> Word8 -> m () -- | Write a Word16, offset in bytes -- -- We don't check that the offset is valid -- --
--   >>> b <- newBuffer 10
--   
--   >>> let v = 1234 :: Word16
--   
--   >>> bufferWriteWord16IO b 1 v
--   
--   >>> bufferReadWord16IO b 1
--   1234
--   
-- --
--   >>> (x :: Word16) <- fromIntegral <$> bufferReadWord8IO b 1
--   
--   >>> (y :: Word16) <- fromIntegral <$> bufferReadWord8IO b 2
--   
--   >>> (((x `shiftL` 8) .|. y) == v)   ||   (((y `shiftL` 8) .|. x) == v)
--   True
--   
bufferWriteWord16IO :: MonadIO m => Buffer 'Mutable pin fin heap -> Word -> Word16 -> m () -- | Write a Word32, offset in bytes -- -- We don't check that the offset is valid -- --
--   >>> b <- newBuffer 10
--   
--   >>> let v = 1234 :: Word32
--   
--   >>> bufferWriteWord32IO b 1 v
--   
--   >>> bufferReadWord32IO b 1
--   1234
--   
bufferWriteWord32IO :: MonadIO m => Buffer 'Mutable pin fin heap -> Word -> Word32 -> m () -- | Write a Word64, offset in bytes -- -- We don't check that the offset is valid -- --
--   >>> b <- newBuffer 10
--   
--   >>> let v = 1234 :: Word64
--   
--   >>> bufferWriteWord64IO b 1 v
--   
--   >>> bufferReadWord64IO b 1
--   1234
--   
bufferWriteWord64IO :: MonadIO m => Buffer 'Mutable pin fin heap -> Word -> Word64 -> m () -- | Copy a buffer into another from/to the given offsets -- -- We don't check buffer limits. -- --
--   >>> let b = [0,1,2,3,4,5,6,7,8] :: BufferI
--   
--   >>> b2 <- newBuffer 8
--   
--   >>> copyBuffer b 4 b2 0 4
--   
--   >>> copyBuffer b 0 b2 4 4
--   
--   >>> forM [0..7] (bufferReadWord8IO b2)
--   [4,5,6,7,0,1,2,3]
--   
copyBuffer :: forall m mut pin0 fin0 heap0 pin1 fin1 heap1. MonadIO m => Buffer mut pin0 fin0 heap0 -> Word -> Buffer 'Mutable pin1 fin1 heap1 -> Word -> Word -> m () data Finalizers -- | Add a finalizer. -- -- The latest added finalizers are executed first. Finalizers are not -- guaranteed to run (e.g. if the program exits before the buffer is -- collected). addFinalizer :: MonadIO m => Buffer mut pin 'Finalized heap -> IO () -> m () -- | Make a buffer finalizable -- -- The new buffer liveness is used to trigger finalizers. makeFinalizable :: MonadIO m => Buffer mut pin f heap -> m (Buffer mut pin 'Finalized heap) -- | Touch a buffer touchBuffer :: MonadIO m => Buffer mut pin fin heap -> m () -- | Get contents as a list of bytes bufferToListIO :: MonadIO m => Buffer mut pin fin heap -> m [Word8] class BufferToList a -- | Get contents as a list of bytes bufferToList :: BufferToList a => a -> [Word8] instance GHC.Classes.Eq Haskus.Memory.Buffer.Mutability instance GHC.Show.Show Haskus.Memory.Buffer.Mutability instance GHC.Classes.Eq Haskus.Memory.Buffer.Finalization instance GHC.Show.Show Haskus.Memory.Buffer.Finalization instance GHC.Classes.Eq Haskus.Memory.Buffer.Pinning instance GHC.Show.Show Haskus.Memory.Buffer.Pinning instance Haskus.Memory.Buffer.BufferToList Haskus.Memory.Buffer.BufferI instance Haskus.Memory.Buffer.BufferToList Haskus.Memory.Buffer.BufferP instance Haskus.Memory.Buffer.BufferToList Haskus.Memory.Buffer.BufferF instance Haskus.Memory.Buffer.BufferToList Haskus.Memory.Buffer.BufferPF instance Haskus.Memory.Buffer.BufferSize Haskus.Memory.Buffer.BufferI instance Haskus.Memory.Buffer.BufferSize Haskus.Memory.Buffer.BufferP instance Haskus.Memory.Buffer.BufferSize Haskus.Memory.Buffer.BufferF instance Haskus.Memory.Buffer.BufferSize Haskus.Memory.Buffer.BufferPF instance Haskus.Memory.Buffer.BufferSize Haskus.Memory.Buffer.BufferME instance Haskus.Memory.Buffer.BufferSize Haskus.Memory.Buffer.BufferMEF instance Haskus.Memory.Buffer.BufferSize Haskus.Memory.Buffer.BufferE instance Haskus.Memory.Buffer.BufferSize Haskus.Memory.Buffer.BufferEF instance Haskus.Memory.Buffer.Thawable (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Immutable pin 'Haskus.Memory.Buffer.Collected heap) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Mutable pin 'Haskus.Memory.Buffer.Collected heap) instance Haskus.Memory.Buffer.Thawable (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Immutable pin 'Haskus.Memory.Buffer.NotFinalized heap) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Mutable pin 'Haskus.Memory.Buffer.NotFinalized heap) instance Haskus.Memory.Buffer.Freezable (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Mutable pin 'Haskus.Memory.Buffer.Collected heap) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Immutable pin 'Haskus.Memory.Buffer.Collected heap) instance Haskus.Memory.Buffer.Freezable (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Mutable pin fin 'Haskus.Memory.Buffer.External) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Immutable pin fin 'Haskus.Memory.Buffer.External) instance GHC.Exts.IsList Haskus.Memory.Buffer.BufferI -- | Malloc memory allocator module Haskus.Memory.Allocator.Malloc -- | Allocate a new Buffer using system `malloc` newBuffer :: MonadIO m => Word -> m (Maybe BufferME) -- | Allocate a new finalized buffer using system `malloc` and -- finalized with `free`. newFinalizedBuffer :: MonadIO m => Word -> m (Maybe BufferMEF) -- | Make a buffer finalized with `free` makeFinalized :: MonadIO m => BufferME -> m BufferMEF -- | Free a malloc-ed Buffer freeBuffer :: MonadIO m => BufferME -> m () module Haskus.Format.Text -- | Text buffer -- -- The buffer contains a text encoded according to phantom type t newtype TextBuffer (t :: k) b TextBuffer :: b -> TextBuffer b type TextI t = TextBuffer t BufferI type TextB t mut pin fin heap = TextBuffer t (Buffer mut pin fin heap) class ShowText t b -- | Show text in IO showTextIO :: (ShowText t b, MonadIO m) => TextBuffer t b -> m String -- | Pure show text showText :: (ShowText t b, BufferToList b) => TextBuffer t b -> String -- | ASCII character map and encoding module Haskus.Format.Text.ASCII -- | ASCII character map and encoding data ASCII ASCII :: ASCII instance Haskus.Format.Text.ShowText Haskus.Format.Text.ASCII.ASCII (Haskus.Memory.Buffer.Buffer mut pin gc heap) instance (GHC.Exts.IsList b, GHC.Exts.Item b Data.Type.Equality.~ GHC.Word.Word8) => Data.String.IsString (Haskus.Format.Text.TextBuffer Haskus.Format.Text.ASCII.ASCII b) -- | Embed buffers into the program module Haskus.Memory.Embed -- | Embed bytes at compile time using GHC's literal strings. -- --
--   >>> :set -XTemplateHaskell
--   
--   >>> let b = $$(embedBytes [72,69,76,76,79])
--   
--   >>> bufferSize b
--   5
--   
embedBytes :: [Word8] -> Q (TExp BufferE) -- | Embed a file in the executable. Return a BufferE embedFile :: FilePath -> Bool -> Maybe Word -> Maybe Word -> Maybe Word -> Q Exp -- | Embed a buffer in the executable. Return either a BufferE or a -- BufferME. embedBuffer :: Buffer mut pin fin heap -> Bool -> Maybe Word -> Maybe Word -> Maybe Word -> Q Exp -- | Embed a pinned buffer in the executable. Return either a BufferE or a -- BufferME. embedPinnedBuffer :: Buffer mut 'Pinned fin heap -> Bool -> Maybe Word -> Maybe Word -> Maybe Word -> Q Exp -- | Embed a unpinned buffer in the executable. Return either a BufferE or -- a BufferME. embedUnpinnedBuffer :: Buffer mut 'NotPinned fin heap -> Bool -> Maybe Word -> Maybe Word -> Maybe Word -> Q Exp -- | Load a buffer from a symbol. Return a BufferE -- -- Note: we can't use Typed TH because of #13587 -- --
--   > -- Test.c
--   > const char mydata[9] = {1,2,30,40,50,6,7,8,9};
--   
-- --
--   > let b = $(loadSymbol 9 "mydata")
--   > print (fmap (bufferReadWord8 b) [0..8])
--   
-- -- loadSymbol :: Word -> String -> Q Exp -- | Load a buffer from a symbol. Return a BufferME -- -- Note: we can't use Typed TH because of #13587 -- --
--   > -- Test.c
--   > const char mydata[9] = {1,2,30,40,50,6,7,8,9};
--   > char mywrtdata[9]    = {1,2,30,40,50,6,7,8,9};
--   
-- --
--   > let w = $(loadMutableSymbol 9 "mywrtdata")
--   > forM_ [0..8] (\i -> bufferWriteWord8IO w i (fromIntegral i))
--   > print =<< forM [0..8] (bufferReadWord8IO w)
--   
-- -- -- -- Trying to write into constant memory: >> let err = -- $(loadMutableSymbol 9 "mydata") >> bufferWriteWordIO err 0 10 -- SEGFAULT loadMutableSymbol :: Word -> String -> Q Exp toBufferE :: Ptr () -> Word# -> BufferE toBufferE' :: Addr# -> Word# -> BufferE toBufferME :: Ptr () -> Word# -> BufferME toBufferME' :: Addr# -> Word# -> BufferME -- | Create an assembler file for the given embedding entries makeEmbeddingFile :: FilePath -> [EmbedEntry] -> IO () -- | An embedding entry. Used to embed binary files into an executable data EmbedEntry EmbedEntry :: SectionType -> Word -> String -> FilePath -> Maybe Word -> Maybe Word -> EmbedEntry -- | Type of data access [embedEntryType] :: EmbedEntry -> SectionType -- | Alignement to respect [embedEntryAlignement] :: EmbedEntry -> Word -- | Symbol to associate to the data [embedEntrySymbol] :: EmbedEntry -> String -- | Input file path [embedEntryFilePath] :: EmbedEntry -> FilePath -- | Offset in the input file [embedEntryOffset] :: EmbedEntry -> Maybe Word -- | Size limit in the input file [embedEntrySize] :: EmbedEntry -> Maybe Word -- | Section type data SectionType -- | Read-only ReadOnlySection :: SectionType -- | Writable WriteableSection :: SectionType -- | Uninitialized UninitializedSection :: SectionType instance GHC.Classes.Ord Haskus.Memory.Embed.EmbedEntry instance GHC.Classes.Eq Haskus.Memory.Embed.EmbedEntry instance GHC.Show.Show Haskus.Memory.Embed.EmbedEntry instance GHC.Classes.Ord Haskus.Memory.Embed.SectionType instance GHC.Classes.Eq Haskus.Memory.Embed.SectionType instance GHC.Show.Show Haskus.Memory.Embed.SectionType -- | A view (e.g. a slice) of a buffer -- -- Suppose we have a big buffer B. -- -- We can have buffer views on B, say vb1 and vb2. -- -- B <----- vb1 ^------- vb2 -- -- These views don't duplicate B's contents and they keep B alive. If the -- views are much smaller than B, it may not be what we want: a lot of -- space is wasted and we would better duplicate B's data required by the -- views and free B. -- -- To support this, we can use "weak buffer views", say wvb1 and wvb2. -- -- B <~~~~~ wvb1 ^~~~~~~~ wvb2 -- -- If/when B is collected, new buffers are created from it for the views: -- -- B1 <----- wvb1 B2 <----- wvb2 -- -- We can also create "weak view views", say wvv1 and wvv2: -- -- B <~~~~~ wvb1 <~~~~~ wvv1 ^~~~~~~~~ wvv2 -- -- If/when B is collected before wvb1, the sharing is kept while the -- required contents of B is duplicated: -- -- B' <---- wvb1 <~~~~~ wvv1 ^~~~~~~~~ wvv2 -- -- When wvb1 is collected, we can be in one of the following state -- depending if B has been collected already or not: -- -- B <~~~~~~~~~~~~~~~~~ wvv1 ^~~~~~~~~~~~~~~~~~~~ wvv2 -- -- B' <~~~~~ wvv1 ^~~~~~~~~ wvv2 module Haskus.Memory.View -- | A view on a buffer newtype View View :: ViewIORef -> View -- | The source of a view -- -- Weak views are used so that the underlying buffer can be freed by the -- GC. When it happens and if the view is still alive the contents of the -- buffer used by the view is copied into a fresh (usually smaller) -- buffer. -- -- Weak views can also be used as sources: in this case, when the source -- view is GCed, the current view is updated to point to the source of -- the source. data ViewSource -- | The source is a buffer. The view keeps the buffer alive SourceBuffer :: Buffer 'Immutable pin fin heap -> ViewSource -- | The source is a weak buffer. If the buffer is collected, its contents -- is copied in to a new buffer and the view is updated to use it. SourceWeakBuffer :: Weak (Buffer 'Immutable pin fin heap) -> ViewSource -- | The source is a weak view. If the source view is collected, the -- current view is updated to use whatever the source view uses as a -- source (another view or a buffer). This mechanism makes buffer -- contents cascade into smaller views while preserving some sharing. SourceWeakView :: Weak ViewIORef -> ViewSource -- | A view pattern data ViewPattern -- | The whole buffer PatternFull :: ViewPattern -- | 1D slice Pattern1D :: {-# UNPACK #-} !Word -> {-# UNPACK #-} !Word -> ViewPattern -- | Offset of the first cell [pattern1DOffset] :: ViewPattern -> {-# UNPACK #-} !Word -- | Number of cells [pattern1DSize] :: ViewPattern -> {-# UNPACK #-} !Word -- | 2D slice Pattern2D :: {-# UNPACK #-} !Word -> {-# UNPACK #-} !Word -> {-# UNPACK #-} !Word -> {-# UNPACK #-} !Word -> ViewPattern -- | Offset of the first line [pattern2DOffset] :: ViewPattern -> {-# UNPACK #-} !Word -- | Width (line size) [pattern2DWidth] :: ViewPattern -> {-# UNPACK #-} !Word -- | Height (number of lines) [pattern2DHeight] :: ViewPattern -> {-# UNPACK #-} !Word -- | Stride (space between two lines) [pattern2DStride] :: ViewPattern -> {-# UNPACK #-} !Word -- | Composed pattern PatternOn :: ViewPattern -> ViewPattern -> ViewPattern -- | Read a Word8 from a view viewReadWord8 :: MonadIO m => View -> Word -> m Word8 -- | Create a view on a buffer newBufferView :: MonadIO m => Buffer 'Immutable pin fin heap -> ViewPattern -> m View -- | Create a weak view on a buffer -- -- The buffer is weakly referenced and can be GCed. When it happens, its -- contents is stored into a new buffer. -- -- You should only use this for views that are much smaller than the -- original buffer so that the copying cost is balanced by the memory -- occupation difference. newBufferWeakView :: MonadIO m => Buffer 'Immutable pin fin heap -> ViewPattern -> m View -- | Create a weak view on a view newViewWeakView :: MonadIO m => View -> ViewPattern -> m View -- | Allocate a new buffer initialized with the contents of the source -- buffer according to the given pattern copyBufferWithPattern :: Buffer mut pin fin heap -> ViewPattern -> IO BufferM -- | Convert a view into an actual buffer viewToBuffer :: View -> IO BufferM -- | Display the state of a View -- --
--   >>> :set -XOverloadedLists
--   
--   >>> import System.Mem
--   
--   >>> v <- newBufferWeakView ([10,11,12,13,14,15,16,17] :: BufferI) (Pattern1D 2 4)
--   
--   >>> v2 <- newViewWeakView v (Pattern1D 1 1)
--   
--   >>> putStr =<< showViewState v2
--   View source: weak view
--   Source size: 4
--   View pattern: Pattern1D {pattern1DOffset = 1, pattern1DSize = 1}
--   Wasted space: 75%
--   Source:
--      View source: weak buffer
--      Source size: 8
--      View pattern: Pattern1D {pattern1DOffset = 2, pattern1DSize = 4}
--      Wasted space: 50%
--   
--   >>> performGC
--   
--   >>> putStr =<< showViewState v2
--   View source: weak view
--   Source size: 4
--   View pattern: Pattern1D {pattern1DOffset = 1, pattern1DSize = 1}
--   Wasted space: 75%
--   Source:
--      View source: buffer
--      Source size: 4
--      View pattern: PatternFull
--      Wasted space: 0%
--   
showViewState :: MonadIO m => View -> m String -- | Compute the effective size occupied by a pattern patternSize :: ViewPattern -> Word -> Word -- | Compute the effective size occupied by a pattern unsafePatternSize :: ViewPattern -> Word instance GHC.Show.Show Haskus.Memory.View.ViewPattern -- | 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 -- | Unicode code-point module Haskus.Format.Text.Unicode.CodePoint -- | Code point -- -- Number from 0 to 0x10FFFF newtype CodePoint CodePoint :: Word32 -> CodePoint -- | Code point range data CodePointRange -- | Code-point range pattern CodePointRange :: CodePoint -> CodePoint -> CodePointRange instance Language.Haskell.TH.Syntax.Lift Haskus.Format.Text.Unicode.CodePoint.CodePointRange instance GHC.Classes.Eq Haskus.Format.Text.Unicode.CodePoint.CodePointRange instance Language.Haskell.TH.Syntax.Lift Haskus.Format.Text.Unicode.CodePoint.CodePoint instance GHC.Classes.Eq Haskus.Format.Text.Unicode.CodePoint.CodePoint instance GHC.Show.Show Haskus.Format.Text.Unicode.CodePoint.CodePointRange instance GHC.Show.Show Haskus.Format.Text.Unicode.CodePoint.CodePoint -- | Unicode character database parsers module Haskus.Format.Text.Unicode.UCDParser -- | Parse a code-point value without the "U+" prefix -- --
--   >>> runParser parseCodePointValue "" "1234"
--   Right U+1234
--   
parseCodePointValue :: Parser CodePoint -- | Parse a code-point value with the "U+" prefix -- --
--   >>> runParser parseCodePoint "" "U+1234"
--   Right U+1234
--   
parseCodePoint :: Parser CodePoint -- | Parse a range of code-points separated by ".." -- --
--   >>> runParser parseCodePointRange "" "1234..5678"
--   Right U+1234..U+5678
--   
parseCodePointRange :: Parser CodePointRange -- | Parse either a range of code-points or a single code-point -- --
--   >>> runParser parseCodePointValueOrRange "" "1234..5678"
--   Right (Right U+1234..U+5678)
--   
-- --
--   >>> runParser parseCodePointValueOrRange "" "1234"
--   Right (Left U+1234)
--   
parseCodePointValueOrRange :: Parser (Either CodePoint CodePointRange) -- | Parse a comment line ("^# ...eol") -- --
--   >>> runParser parseCommentLine "" "# comment"
--   Right " comment"
--   
parseCommentLine :: Parser String -- | Parse valid line with the given parser, skipping comment lines skipCommentLines :: Parser a -> Parser [a] -- | Parse a file and lift the result into a TH expression parseFile :: Lift a => FilePath -> Parser a -> ExpQ -- | Strip comments stripComments :: Parser [String] -- | Parse Blocks.txt file parseBlocks :: Parser [(CodePointRange, String)] -- | Parse DerivedName.txt file parseDerivedName :: Parser [(Either CodePoint CodePointRange, String)] -- | Unicode character database module Haskus.Format.Text.Unicode.UCD -- | Plane blocks -- --
--   >>> blocks !! 1
--   (U+0080..U+00FF,"Latin-1 Supplement")
--   
blocks :: [(CodePointRange, String)] -- | Unicode module Haskus.Format.Text.Unicode newtype Plane Plane :: Word -> Plane -- | Get the plan the code-point belongs to -- --
--   >>> codePointPlane (CodePoint 0x21234)
--   Plane 2
--   
codePointPlane :: CodePoint -> Plane -- | Basic Multilingual Plane (BMP) -- -- The Basic Multilingual Plane (BMP, or Plane 0) contains the common-use -- characters for all the modern scripts of the world as well as many -- historical and rare characters. By far the majority of all Unicode -- characters for almost all textual data can be found in the BMP. planeBMP :: Plane -- | Supplementary Multilingual Plane (SMP) -- -- Supplementary Multilingual Plane. The Supplementary Multilingual Plane -- (SMP, or Plane 1) is dedicated to the encoding of characters for -- scripts or symbols which either could not be fit into the BMP or see -- very infrequent usage. This includes many historic scripts, a number -- of lesser-used contemporary scripts, special-purpose invented scripts, -- notational systems or large pictographic symbol sets, and occasionally -- historic extensions of scripts whose core sets are encoded on the BMP. -- -- Examples include Gothic (historic), Shavian (special-purpose -- invented), Musical Symbols (notational system), Domino Tiles -- (pictographic), and Ancient Greek Numbers (historic extension for -- Greek). A number of scripts, whether of historic and contemporary use, -- do not yet have their characters encoded in the Unicode Standard. The -- majority of scripts currently identified for encoding will eventually -- be allocated in the SMP. As a result, some areas of the SMP will -- experience common, frequent usage. planeSMP :: Plane -- | Supplementary Ideographic Plane (SIP) -- -- The Supplementary Ideographic Plane (SIP, or Plane 2) is intended as -- an additional allocation area for those CJK characters that could not -- be fit in the blocks set aside for more common CJK characters in the -- BMP. While there are a small number of common-use CJK characters in -- the SIP (for example, for Cantonese usage), the vast majority of Plane -- 2 characters are extremely rare or of historical interest only. planeSIP :: Plane -- | Supplementary Special-purpose Plane (SSP) -- -- The Supplementary Special-purpose Plane (SSP, or Plane 14) is the -- spillover allocation area for format control characters that do not -- fit into the small allocation areas for format control characters in -- the BMP. planeSSP :: Plane -- | Private Use Planes -- -- The two Private Use Planes (Planes 15 and 16) are allocated, in their -- entirety, for private use. Those two planes contain a total of 131,068 -- characters to supple- ment the 6,400 private-use characters located in -- the BMP. planePrivates :: [Plane] data UTF8 UTF8 :: UTF8 data UTF16_BOM UTF16_BOM :: UTF16_BOM data UTF16_BE UTF16_BE :: UTF16_BE data UTF16_LE UTF16_LE :: UTF16_LE data UTF32_BOM UTF32_BOM :: UTF32_BOM data UTF32_BE UTF32_BE :: UTF32_BE data UTF32_LE UTF32_LE :: UTF32_LE instance GHC.Classes.Eq Haskus.Format.Text.Unicode.Plane instance GHC.Show.Show Haskus.Format.Text.Unicode.Plane instance Haskus.Format.Text.Unicode.Encoding Haskus.Format.Text.Unicode.UTF8 instance Haskus.Format.Text.Unicode.Encoding Haskus.Format.Text.Unicode.UTF16_BOM instance Haskus.Format.Text.Unicode.Encoding Haskus.Format.Text.Unicode.UTF16_BE instance Haskus.Format.Text.Unicode.Encoding Haskus.Format.Text.Unicode.UTF16_LE instance Haskus.Format.Text.Unicode.Encoding Haskus.Format.Text.Unicode.UTF32_BOM instance Haskus.Format.Text.Unicode.Encoding Haskus.Format.Text.Unicode.UTF32_BE instance Haskus.Format.Text.Unicode.Encoding Haskus.Format.Text.Unicode.UTF32_LE -- | 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 -- | Binary serialization of Haskell values module Haskus.Format.Binary.Serialize -- | Monad which can build a sequence of bytes class Monad m => PutMonad m -- | Write a Word8 putWord8 :: PutMonad m => Word8 -> m () -- | Write a Word16 putWord16 :: PutMonad m => Word16 -> m () -- | Write a Word32 putWord32 :: PutMonad m => Word32 -> m () -- | Write a Word64 putWord64 :: PutMonad m => Word64 -> m () -- | Write some Word8 putWord8s :: PutMonad m => [Word8] -> m () -- | Write some Word16 putWord16s :: PutMonad m => [Word16] -> m () -- | Write some Word32 putWord32s :: PutMonad m => [Word32] -> m () -- | Write some Word64 putWord64s :: PutMonad m => [Word64] -> m () -- | Write the contents of a buffer putBuffer :: PutMonad m => Buffer mut pin gc heap -> m () -- | Pre-allocate at least the given amount of bytes -- -- This is a hint for the putter to speed up the allocation of memory preAllocateAtLeast :: PutMonad m => Word -> m () -- | Monad which can read a sequence of bytes class Monad m => GetMonad m -- | Read a Word8 getWord8 :: GetMonad m => m Word8 -- | Read a Word16 with host endianness getWord16 :: GetMonad m => m Word16 -- | Read a Word32 with host endianness getWord32 :: GetMonad m => m Word32 -- | Read a Word64 with host endianness getWord64 :: GetMonad m => m Word64 -- | Read some Word8 getWord8s :: GetMonad m => Word -> m [Word8] -- | Read some Word16 with host endianness getWord16s :: GetMonad m => Word -> m [Word16] -- | Read some Word32 with host endianness getWord32s :: GetMonad m => Word -> m [Word32] -- | Read some Word64 with host endianness getWord64s :: GetMonad m => Word -> m [Word64] -- | Read the given amount of bytes into a new buffer getBuffer :: GetMonad m => Word -> m BufferI -- | Read the given amount of bytes into the specified buffer getBufferInto :: GetMonad m => Word -> Buffer 'Mutable pin gc heap -> m () -- | Binary serializable data class Serializable a where { -- | Size of the data in bytes type family SizeOf a :: Size; -- | Sensible to endianness type family Endian a :: Bool; } -- | Dynamic size of the data in bytes sizeOf :: Serializable a => a -> Word -- | Serialize a value put :: (Serializable a, PutMonad m) => Endianness -> a -> m () -- | Deserialize a value get :: (Serializable a, GetMonad m) => Endianness -> Word -> m a -- | Size in bytes data Size -- | Exactly the given size Exactly :: Nat -> Size -- | At least the given size AtLeast :: Nat -> Size -- | Dynamically known size Dynamic :: Size -- | Write a Word16 with big-endian order putWord16BE :: PutMonad m => Word16 -> m () -- | Write a Word32 with big-endian order putWord32BE :: PutMonad m => Word32 -> m () -- | Write a Word64 with big-endian order putWord64BE :: PutMonad m => Word64 -> m () -- | Write a Word16 with little-endian order putWord16LE :: PutMonad m => Word16 -> m () -- | Write a Word32 with little-endian order putWord32LE :: PutMonad m => Word32 -> m () -- | Write a Word64 with little-endian order putWord64LE :: PutMonad m => Word64 -> m () -- | Write some Word16 with big-endian order putWord16BEs :: PutMonad m => [Word16] -> m () -- | Write some Word32 with big-endian order putWord32BEs :: PutMonad m => [Word32] -> m () -- | Write some Word64 with big-endian order putWord64BEs :: PutMonad m => [Word64] -> m () -- | Write some Word16 with little-endian order putWord16LEs :: PutMonad m => [Word16] -> m () -- | Write some Word32 with little-endian order putWord32LEs :: PutMonad m => [Word32] -> m () -- | Write some Word64 with little-endian order putWord64LEs :: PutMonad m => [Word64] -> m () -- | Read a Word16 with big-endian order getWord16BE :: GetMonad m => m Word16 -- | Read a Word32 with big-endian order getWord32BE :: GetMonad m => m Word32 -- | Read a Word64 with big-endian order getWord64BE :: GetMonad m => m Word64 -- | Read a Word16 with little-endian order getWord16LE :: GetMonad m => m Word16 -- | Read a Word32 with little-endian order getWord32LE :: GetMonad m => m Word32 -- | Read a Word64 with little-endian order getWord64LE :: GetMonad m => m Word64 -- | Read some Word16 with big-endian order getWord16BEs :: GetMonad m => Word -> m [Word16] -- | Read some Word32 with big-endian order getWord32BEs :: GetMonad m => Word -> m [Word32] -- | Read some Word64 with big-endian order getWord64BEs :: GetMonad m => Word -> m [Word64] -- | Read some Word16 with little-endian order getWord16LEs :: GetMonad m => Word -> m [Word16] -- | Read some Word32 with little-endian order getWord32LEs :: GetMonad m => Word -> m [Word32] -- | Read some Word64 with little-endian order getWord64LEs :: GetMonad m => Word -> m [Word64] instance Haskus.Format.Binary.Serialize.Serializable GHC.Word.Word8 instance Haskus.Format.Binary.Serialize.Serializable GHC.Word.Word16 instance Haskus.Format.Binary.Serialize.Serializable GHC.Word.Word32 instance Haskus.Format.Binary.Serialize.Serializable GHC.Word.Word64 instance Haskus.Format.Binary.Serialize.Serializable GHC.Int.Int8 instance Haskus.Format.Binary.Serialize.Serializable GHC.Int.Int16 instance Haskus.Format.Binary.Serialize.Serializable GHC.Int.Int32 instance Haskus.Format.Binary.Serialize.Serializable GHC.Int.Int64 instance Haskus.Format.Binary.Serialize.Serializable Haskus.Memory.Buffer.BufferI instance Haskus.Format.Binary.Serialize.Serializable a => Haskus.Format.Binary.Serialize.Serializable (Haskus.Format.Binary.Endianness.AsBigEndian a) instance Haskus.Format.Binary.Serialize.Serializable a => Haskus.Format.Binary.Serialize.Serializable (Haskus.Format.Binary.Endianness.AsLittleEndian a) -- | Serializer into a mutable buffer -- --
--   >>> let w = do putWord8 0x01 ; putWord32BE 0x23456789
--   
--   >>> b <- newBuffer 10
--   
--   >>> void $ runBufferPut b 0 w
--   
--   >>> xs <- forM [0..4] (bufferReadWord8IO b)
--   
--   >>> xs == [0x01,0x23,0x45,0x67,0x89]
--   True
--   
module Haskus.Format.Binary.Serialize.Buffer -- | A Put monad than fails when there is not enough space in the target -- buffer newtype BufferPutT b m a BufferPutT :: StateT (BufferPutState b) m a -> BufferPutT b m a type BufferPut b a = BufferPutT b Identity a -- | Get current offset getPutOffset :: Monad m => BufferPutT b m Word -- | Get buffer getPutBuffer :: Monad m => BufferPutT b m b -- | Get current offset setPutOffset :: Monad m => Word -> BufferPutT b m () -- | Run a buffer put runBufferPut :: Monad m => b -> Word -> BufferPutT b m a -> m (a, Word) instance Control.Monad.Trans.Class.MonadTrans (Haskus.Format.Binary.Serialize.Buffer.BufferPutT b) instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Haskus.Format.Binary.Serialize.Buffer.BufferPutT b m) instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Haskus.Format.Binary.Serialize.Buffer.BufferPutT b m) instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Haskus.Format.Binary.Serialize.Buffer.BufferPutT b m) instance GHC.Base.Monad m => GHC.Base.Monad (Haskus.Format.Binary.Serialize.Buffer.BufferPutT b m) instance GHC.Base.Monad m => GHC.Base.Applicative (Haskus.Format.Binary.Serialize.Buffer.BufferPutT b m) instance GHC.Base.Functor m => GHC.Base.Functor (Haskus.Format.Binary.Serialize.Buffer.BufferPutT b m) instance (Control.Monad.IO.Class.MonadIO m, Control.Monad.Fail.MonadFail m) => Haskus.Format.Binary.Serialize.PutMonad (Haskus.Format.Binary.Serialize.Buffer.BufferPutT (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Mutable pin gc heap) m)