-- 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.5 -- | Bit orderings module Haskus.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.Binary.Bits.Order.BitOrder instance GHC.Show.Show Haskus.Binary.Bits.Order.BitOrder -- | Some C types module Haskus.Binary.CTypes -- | 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 -- | Memory layout -- -- Describe a memory region module Haskus.Memory.Layout -- | Path in a layout data LPath (path :: [PathElem]) LPath :: LPath -- | Layout path element data PathElem -- | Addressing via a numeric index LIndex :: Nat -> PathElem -- | Addressing via a symbol LSymbol :: Symbol -> PathElem -- | Index in the layout path -- -- Helper for ``ptr --> lPath @p`` until lPath :: forall e. LPath '[e] -- | Type obtained when following path p type family LPathType p l :: Type -- | Offset obtained when following path p type family LPathOffset p l :: Nat -- | Layout path root type LRoot = LPath '[] type family (:->) p (s :: Symbol) type family (:#>) p (n :: Nat) -- | Primitives -- --
--   >>> :kind! CSizeOf (CPrimitive 8 1)
--   CSizeOf (CPrimitive 8 1) :: Nat
--   = 8
--   
-- --
--   >>> :kind! CAlignment (CPrimitive 8 2)
--   CAlignment (CPrimitive 8 2) :: Nat
--   = 2
--   
data CPrimitive (size :: Nat) (align :: Nat) CPrimitive :: CPrimitive -- | Array -- --
--   >>> type S = CArray 10 (CPrimitive 8 8)
--   
--   >>> :kind! CSizeOf S
--   CSizeOf S :: Nat
--   = 80
--   
-- --
--   >>> :kind! CAlignment S
--   CAlignment S :: Nat
--   = 8
--   
data CArray (n :: Nat) (a :: k) CArray :: CArray -- | Unbounded array -- --
--   >>> type S = CUArray (CPrimitive 8 8)
--   
--   >>> :kind! CSizeOf S
--   CSizeOf S :: Nat
--   = (TypeError ...)
--   
-- --
--   >>> :kind! CAlignment S
--   CAlignment S :: Nat
--   = 8
--   
data CUArray (a :: k) CUArray :: CUArray -- | Struct -- --
--   >>> type S = CStruct ['Field "i8" (CPrimitive 1 1), 'Field "i32" (CPrimitive 4 4)]
--   
--   >>> :kind! CSizeOf S
--   CSizeOf S :: Nat
--   = 8
--   
-- --
--   >>> :kind! CAlignment S
--   CAlignment S :: Nat
--   = 4
--   
data CStruct (fs :: [Field]) CStruct :: CStruct -- | Union -- --
--   >>> type S = CUnion ['Field "i8" (CPrimitive 1 1), 'Field "i32" (CPrimitive 4 4)]
--   
--   >>> :kind! CSizeOf S
--   CSizeOf S :: Nat
--   = 4
--   
-- --
--   >>> :kind! CAlignment S
--   CAlignment S :: Nat
--   = 4
--   
data CUnion (fs :: [Field]) CUnion :: CUnion -- | Memory properties module Haskus.Memory.Property -- | Is the memory 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 -- | 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 memory automatically garbage collected? data Finalization -- | Automatically collected by the garbage-collector Collected :: Finalization -- | Finalizers are run just before the garbage collector collects the -- referencing entity (buffer, pointer...). The memory used by the entity -- may be collected too (Internal heap), explicitly freed by a finalizer -- or not freed at all. Finalized :: Finalization -- | The memory is not automatically freed and we can't attach finalizers -- to the buffer. NotFinalized :: Finalization instance GHC.Classes.Eq Haskus.Memory.Property.Finalization instance GHC.Show.Show Haskus.Memory.Property.Finalization instance GHC.Classes.Eq Haskus.Memory.Property.Pinning instance GHC.Show.Show Haskus.Memory.Property.Pinning instance GHC.Classes.Eq Haskus.Memory.Property.Mutability instance GHC.Show.Show Haskus.Memory.Property.Mutability -- | 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.Memory.Ptr -- | A pointer in memory data Pointer (mut :: Mutability) (fin :: Finalization) [PtrI] :: {-# UNPACK #-} !RawPtr -> PtrI [PtrM] :: {-# UNPACK #-} !RawPtr -> PtrM [PtrIF] :: {-# UNPACK #-} !FinPtr -> {-# UNPACK #-} !Int -> PtrIF [PtrMF] :: {-# UNPACK #-} !FinPtr -> {-# UNPACK #-} !Int -> PtrMF -- | Wrapper containing any kind of buffer newtype AnyPointer AnyPointer :: (forall mut fin. Pointer mut fin) -> AnyPointer type RawPtr = Ptr () type FinPtr = ForeignPtr () type PtrI = Pointer 'Immutable 'NotFinalized type PtrM = Pointer 'Mutable 'NotFinalized type PtrIF = Pointer 'Immutable 'Finalized type PtrMF = Pointer 'Mutable 'Finalized -- | Test if a pointer is Null isNullPtr :: Pointer mut fin -> Bool -- | Null pointer nullPtrI :: PtrI -- | Null pointer nullPtrM :: PtrM -- | Index a pointer indexPtr :: Pointer mut fin -> Int -> Pointer mut fin -- | Distance between two pointers distancePtr :: Pointer mut0 fin0 -> Pointer mut1 fin1 -> Int -- | Use a pointer (finalized or not) as a non finalized pointer withPtr :: MonadInIO m => Pointer mut fin -> (Pointer mut 'NotFinalized -> m b) -> m b -- | Use a finalized pointer as a non finalized pointer withFinalizedPtr :: MonadInIO m => Pointer mut 'Finalized -> (Pointer mut 'NotFinalized -> m b) -> m b -- | Alloc mutable finalized memory allocFinalizedPtr :: MonadIO m => Word -> m PtrMF -- | Alloc mutable non-finalized memory allocPtr :: MonadIO m => Word -> m PtrM -- | Free a non-finalized memory freePtr :: MonadIO m => Pointer mut 'NotFinalized -> m () -- | 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.Memory.Ptr.Pointer mut fin) -- | Signed primitive integers module Haskus.Number.Int -- | Return a Int with at least n bits type family IntAtLeast (n :: Nat) -- | Return a Int with exactly n bits type family IntN (n :: Nat) data Int# :: TYPE IntRep (+#) :: 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 <=# -- | Alias for tagToEnum#. Returns True if its parameter is 1# and -- False if it is 0#. isTrue# :: Int# -> Bool -- | Unsigned primitive words module Haskus.Number.Word -- | Return a Word with at least n bits type family WordAtLeast (n :: Nat) -- | Return a Word with exactly n bits type family WordN (n :: Nat) data Word# :: TYPE WordRep plusWord# :: Word# -> Word# -> Word# minusWord# :: Word# -> Word# -> Word# ltWord# :: Word# -> Word# -> Int# leWord# :: Word# -> Word# -> Int# gtWord# :: Word# -> Word# -> Int# geWord# :: Word# -> Word# -> Int# eqWord# :: Word# -> Word# -> Int# -- | IEEE754 floating-point numbers module Haskus.Number.Float type Float32 = Float type Float64 = Double -- | Convert a Float32 into a Word32 float32ToWord32 :: Float32 -> Word32 -- | Convert a Word64 into a Float64 float64ToWord64 :: Float64 -> Word64 -- | Convert a Word32 into a Float32 word32ToFloat32 :: Word32 -> Float32 -- | Convert a Word64 into a Float64 word64ToFloat64 :: Word64 -> Float64 -- | Storable class module Haskus.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 () -- | 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 () -- | 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) instance Haskus.Binary.Storable.Storable a => Haskus.Binary.Storable.GStorable (GHC.Generics.K1 i a) instance Haskus.Binary.Storable.Storable GHC.Word.Word8 instance Haskus.Binary.Storable.Storable GHC.Word.Word16 instance Haskus.Binary.Storable.Storable GHC.Word.Word32 instance Haskus.Binary.Storable.Storable GHC.Word.Word64 instance Haskus.Binary.Storable.Storable GHC.Int.Int8 instance Haskus.Binary.Storable.Storable GHC.Int.Int16 instance Haskus.Binary.Storable.Storable GHC.Int.Int32 instance Haskus.Binary.Storable.Storable GHC.Int.Int64 instance Haskus.Binary.Storable.Storable GHC.Types.Float instance Haskus.Binary.Storable.Storable GHC.Types.Double instance Haskus.Binary.Storable.Storable GHC.Types.Char instance Haskus.Binary.Storable.Storable GHC.Types.Word instance Haskus.Binary.Storable.Storable GHC.Types.Int instance Haskus.Binary.Storable.Storable (GHC.Ptr.Ptr a) instance Haskus.Binary.Storable.Storable Foreign.C.Types.CSize instance Haskus.Binary.Storable.Storable Foreign.C.Types.CChar instance Haskus.Binary.Storable.Storable Foreign.C.Types.CULong instance Haskus.Binary.Storable.Storable Foreign.C.Types.CLong instance Haskus.Binary.Storable.Storable Foreign.C.Types.CUInt instance Haskus.Binary.Storable.Storable Foreign.C.Types.CInt instance Haskus.Binary.Storable.Storable Foreign.C.Types.CUShort instance Haskus.Binary.Storable.Storable Foreign.C.Types.CShort instance Haskus.Binary.Storable.Storable Foreign.Ptr.WordPtr instance Haskus.Binary.Storable.GStorable GHC.Generics.U1 instance (Haskus.Binary.Storable.GStorable a, Haskus.Binary.Storable.GStorable b) => Haskus.Binary.Storable.GStorable (a GHC.Generics.:*: b) instance Haskus.Binary.Storable.GStorable a => Haskus.Binary.Storable.GStorable (GHC.Generics.M1 i c a) instance Haskus.Binary.Storable.StaticStorable GHC.Word.Word8 instance Haskus.Binary.Storable.StaticStorable GHC.Word.Word16 instance Haskus.Binary.Storable.StaticStorable GHC.Word.Word32 instance Haskus.Binary.Storable.StaticStorable GHC.Word.Word64 instance Haskus.Binary.Storable.StaticStorable GHC.Int.Int8 instance Haskus.Binary.Storable.StaticStorable GHC.Int.Int16 instance Haskus.Binary.Storable.StaticStorable GHC.Int.Int32 instance Haskus.Binary.Storable.StaticStorable GHC.Int.Int64 -- | Memory utilities module Haskus.Memory.Utils -- | 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 -- | memcpy memcpy# :: Addr# -> Addr# -> Int# -> IO () -- | A buffer in memory module Haskus.Memory.Buffer -- | A memory buffer data Buffer (mut :: Mutability) (pin :: Pinning) (fin :: Finalization) (heap :: Heap) [Buffer] :: !ByteArray# -> BufferI [BufferP] :: !ByteArray# -> BufferP [BufferM] :: !MutableByteArray# RealWorld -> BufferM [BufferMP] :: !MutableByteArray# RealWorld -> BufferMP [BufferME] :: Addr# -> {-# UNPACK #-} !Word -> BufferME [BufferE] :: Addr# -> {-# UNPACK #-} !Word -> BufferE [BufferF] :: !ByteArray# -> {-# UNPACK #-} !Finalizers -> BufferF [BufferPF] :: !ByteArray# -> {-# UNPACK #-} !Finalizers -> BufferPF [BufferMF] :: !MutableByteArray# RealWorld -> {-# UNPACK #-} !Finalizers -> BufferMF [BufferMPF] :: !MutableByteArray# RealWorld -> {-# UNPACK #-} !Finalizers -> BufferMPF [BufferMEF] :: Addr# -> {-# UNPACK #-} !Word -> {-# UNPACK #-} !Finalizers -> BufferMEF [BufferEF] :: Addr# -> {-# UNPACK #-} !Word -> {-# UNPACK #-} !Finalizers -> BufferEF -- | 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 memory automatically garbage collected? data Finalization -- | Automatically collected by the garbage-collector Collected :: Finalization -- | Finalizers are run just before the garbage collector collects the -- referencing entity (buffer, pointer...). The memory used by the entity -- may be collected too (Internal heap), explicitly freed by a finalizer -- or not freed at all. Finalized :: Finalization -- | The memory is not automatically freed and we can't attach finalizers -- to the buffer. NotFinalized :: Finalization -- | Is the memory 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 () -- | Touch a data touch :: MonadIO m => a -> 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 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.Property.Immutable pin 'Haskus.Memory.Property.Collected heap) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Mutable pin 'Haskus.Memory.Property.Collected heap) instance Haskus.Memory.Buffer.Thawable (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Immutable pin 'Haskus.Memory.Property.NotFinalized heap) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Mutable pin 'Haskus.Memory.Property.NotFinalized heap) instance Haskus.Memory.Buffer.Freezable (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Mutable pin 'Haskus.Memory.Property.Collected heap) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Immutable pin 'Haskus.Memory.Property.Collected heap) instance Haskus.Memory.Buffer.Freezable (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Mutable pin fin 'Haskus.Memory.Property.External) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Immutable pin fin 'Haskus.Memory.Property.External) instance GHC.Exts.IsList Haskus.Memory.Buffer.BufferI -- | 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 -- | Typed memory -- -- Pointer-like datatypes with an additional phantom type indicating -- their memory layout module Haskus.Memory.Typed -- | Typed buffer newtype BufferT (t :: k) mut pin fin heap BufferT :: Buffer mut pin fin heap -> BufferT mut pin fin heap -- | Typed pointer newtype PointerT (t :: k) mut fin PointerT :: Pointer mut fin -> PointerT mut fin -- | Typed raw pointer newtype PtrT (t :: k) PtrT :: Ptr () -> PtrT -- | 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 -- | 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 () -- | 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.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.Binary.Union.Union x) instance (r Data.Type.Equality.~ GHC.Types.Word, Haskus.Binary.Storable.Storable a) => Haskus.Utils.HList.Apply Haskus.Binary.Union.FoldAlignment (a, GHC.Types.Word) r instance (Haskus.Utils.HList.HFoldr' Haskus.Binary.Union.FoldSizeOf GHC.Types.Word l GHC.Types.Word, Haskus.Utils.HList.HFoldr' Haskus.Binary.Union.FoldAlignment GHC.Types.Word l GHC.Types.Word) => Haskus.Binary.Storable.Storable (Haskus.Binary.Union.Union l) instance (Haskus.Utils.HList.HFoldr' Haskus.Binary.Union.FoldSizeOf GHC.Types.Word l GHC.Types.Word, Haskus.Utils.HList.HFoldr' Haskus.Binary.Union.FoldAlignment GHC.Types.Word l GHC.Types.Word) => Foreign.Storable.Storable (Haskus.Binary.Union.Union l) instance (r Data.Type.Equality.~ GHC.Types.Word, Haskus.Binary.Storable.Storable a) => Haskus.Utils.HList.Apply Haskus.Binary.Union.FoldSizeOf (a, GHC.Types.Word) r instance (GHC.TypeNats.KnownNat (Haskus.Utils.Types.List.ListMax (Haskus.Binary.Union.MapSizeOf fs)), GHC.TypeNats.KnownNat (Haskus.Utils.Types.List.ListMax (Haskus.Binary.Union.MapAlignment fs))) => Haskus.Binary.Storable.StaticStorable (Haskus.Binary.Union.Union fs) -- | Record (similar to C struct) module Haskus.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 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.Binary.Record.Record fs, b Data.Type.Equality.~ Haskus.Binary.Record.Field name typ, i Data.Type.Equality.~ (rec, Haskus.Utils.HList.HList l2), typ Data.Type.Equality.~ Haskus.Binary.Record.FieldType name fs, GHC.TypeNats.KnownNat (Haskus.Binary.Record.FieldOffset name fs 0), Haskus.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.Binary.Record.Extract (b, i) r instance (Haskus.Utils.HList.HFoldr' Haskus.Binary.Record.Extract (Haskus.Binary.Record.Record fs, Haskus.Utils.HList.HList '[]) fs (Haskus.Binary.Record.Record fs, Haskus.Utils.HList.HList fs), GHC.Show.Show (Haskus.Utils.HList.HList fs)) => GHC.Show.Show (Haskus.Binary.Record.Record fs) instance (s Data.Type.Equality.~ Haskus.Binary.Record.FullRecordSize fs, GHC.TypeNats.KnownNat s) => Haskus.Binary.Storable.StaticStorable (Haskus.Binary.Record.Record fs) -- | Store an Enum in the given backing word type module Haskus.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.Binary.Storable.Storable b => Haskus.Binary.Storable.Storable (Haskus.Binary.Enum.EnumField b a) instance GHC.Classes.Eq b => GHC.Classes.Eq (Haskus.Binary.Enum.EnumField b a) instance GHC.Show.Show b => GHC.Show.Show (Haskus.Binary.Enum.EnumField b a) instance (GHC.Real.Integral b, Haskus.Binary.Storable.StaticStorable b, Haskus.Binary.Enum.CEnum a) => Haskus.Binary.Storable.StaticStorable (Haskus.Binary.Enum.EnumField b a) -- | Character module Haskus.Binary.Char -- | 8-bit character (ASCII, etc.) newtype Char8 Char8 :: Word8 -> Char8 instance Haskus.Binary.Storable.Storable Haskus.Binary.Char.Char8 instance GHC.Classes.Ord Haskus.Binary.Char.Char8 instance GHC.Classes.Eq Haskus.Binary.Char.Char8 instance GHC.Show.Show Haskus.Binary.Char.Char8 -- | Bit shifts module Haskus.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.Binary.Bits.Shift.SignedShiftableBits GHC.Types.Int instance Haskus.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int8 instance Haskus.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int16 instance Haskus.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int32 instance Haskus.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int64 instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Types.Word instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Word.Word8 instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Word.Word16 instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Word.Word32 instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Word.Word64 instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Types.Int instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Int.Int8 instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Int.Int16 instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Int.Int32 instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Int.Int64 instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Integer.Type.Integer instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Natural.Natural -- | Types with finite bit count module Haskus.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 -- | 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 -- | Complement complement :: FiniteBits a => a -> a instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Types.Word instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Word.Word8 instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Word.Word16 instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Word.Word32 instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Word.Word64 instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Types.Int instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Int.Int8 instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Int.Int16 instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Int.Int32 instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Int.Int64 -- | Bitwise bit operations module Haskus.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 instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Types.Word instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Word.Word8 instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Word.Word16 instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Word.Word32 instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Word.Word64 instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Types.Int instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Int.Int8 instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Int.Int16 instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Int.Int32 instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Int.Int64 instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Integer.Type.Integer instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Natural.Natural -- | Bit rotations module Haskus.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.Binary.Bits.Rotate.RotatableBits GHC.Types.Word instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Word.Word8 instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Word.Word16 instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Word.Word32 instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Word.Word64 instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Types.Int instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Int.Int8 instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Int.Int16 instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Int.Int32 instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Int.Int64 module Haskus.Binary.Bits.Mask class MaskBits a -- | Make a mask dynamically makeMaskDyn :: MaskBits a => Word -> a -- | makeMaskFinite 3 = 00000111 makeMaskFinite :: forall a. (ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => Word -> a -- | Make a mask statically makeMask :: forall n a. (KnownNat n, MaskBits a) => a -- | Keep only the n least-significant bits of the given value maskDyn :: (MaskBits a, Bitwise a) => Word -> a -> a type Maskable n a = (MaskBits a, Bitwise a, KnownNat n) -- | Keep only the n least-significant bits of the given value mask :: forall n a. Maskable n a => a -> a instance Haskus.Binary.Bits.Mask.MaskBits GHC.Natural.Natural instance Haskus.Binary.Bits.Mask.MaskBits GHC.Types.Word instance Haskus.Binary.Bits.Mask.MaskBits GHC.Word.Word8 instance Haskus.Binary.Bits.Mask.MaskBits GHC.Word.Word16 instance Haskus.Binary.Bits.Mask.MaskBits GHC.Word.Word32 instance Haskus.Binary.Bits.Mask.MaskBits GHC.Word.Word64 instance Haskus.Binary.Bits.Mask.MaskBits GHC.Types.Int instance Haskus.Binary.Bits.Mask.MaskBits GHC.Int.Int8 instance Haskus.Binary.Bits.Mask.MaskBits GHC.Int.Int16 instance Haskus.Binary.Bits.Mask.MaskBits GHC.Int.Int32 instance Haskus.Binary.Bits.Mask.MaskBits GHC.Int.Int64 module Haskus.Binary.Bits.Helper -- | 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 -- | Bit indexable types module Haskus.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, FiniteBits 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.Binary.Bits.Index.IndexableBits GHC.Types.Word instance Haskus.Binary.Bits.Index.IndexableBits GHC.Word.Word8 instance Haskus.Binary.Bits.Index.IndexableBits GHC.Word.Word16 instance Haskus.Binary.Bits.Index.IndexableBits GHC.Word.Word32 instance Haskus.Binary.Bits.Index.IndexableBits GHC.Word.Word64 instance Haskus.Binary.Bits.Index.IndexableBits GHC.Types.Int instance Haskus.Binary.Bits.Index.IndexableBits GHC.Int.Int8 instance Haskus.Binary.Bits.Index.IndexableBits GHC.Int.Int16 instance Haskus.Binary.Bits.Index.IndexableBits GHC.Int.Int32 instance Haskus.Binary.Bits.Index.IndexableBits GHC.Int.Int64 instance Haskus.Binary.Bits.Index.IndexableBits GHC.Integer.Type.Integer instance Haskus.Binary.Bits.Index.IndexableBits GHC.Natural.Natural -- | A memory buffer with a fixed address -- -- A buffer is a strict ByteString but with: -- -- module Haskus.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.Binary.Buffer.Buffer instance GHC.Classes.Eq Haskus.Binary.Buffer.Buffer instance GHC.Show.Show Haskus.Binary.Buffer.Buffer instance Haskus.Binary.Bits.Bitwise.Bitwise Haskus.Binary.Buffer.Buffer instance Haskus.Binary.Bits.Index.IndexableBits Haskus.Binary.Buffer.Buffer -- | Put monad -- -- FIXME: PutM uses slow ByteString builder... We need to replace it with -- a fast one module Haskus.Binary.Put -- | Put merely lifts Builder into a Writer monad, applied to (). type Put = PutM () -- | The PutM type. A Writer monad over the efficient Builder monoid. data PutM a -- | Execute Put runPut :: Put -> Buffer -- | Execute PutM runPutM :: PutM a -> (a, 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.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.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.Binary.BufferBuilder.BufferBuilder instance GHC.Base.Semigroup Haskus.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.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.Binary.Bits.Reverse.ReversableBits GHC.Word.Word8 instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Word.Word16 instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Word.Word32 instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Word.Word64 instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Types.Word instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Int.Int8 instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Int.Int16 instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Int.Int32 instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Int.Int64 instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Types.Int -- | Operations on bits module Haskus.Binary.Bits type Bits a = (Eq a, FiniteBits a, IndexableBits a, ShiftableBits a, Bitwise a, RotatableBits a, KnownNat (BitSize a), MaskBits 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 -- | 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 -- | Complement complement :: FiniteBits a => a -> a -- | 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, FiniteBits 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 -- | 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 class MaskBits a -- | Make a mask dynamically makeMaskDyn :: MaskBits a => Word -> a type Maskable n a = (MaskBits a, Bitwise a, KnownNat n) -- | Keep only the n least-significant bits of the given value maskDyn :: (MaskBits a, Bitwise a) => Word -> a -> a -- | Keep only the n least-significant bits of the given value mask :: forall n a. Maskable n a => 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, MaskBits 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 -- | Check if a number is a power of two (2^n) -- --
--   >>> isPowerOfTwo (10 :: Word)
--   False
--   
--   >>> isPowerOfTwo (16 :: Word)
--   True
--   
isPowerOfTwo :: IndexableBits a => a -> Bool -- | Check if a number is a power of four (4^n) -- --
--   >>> isPowerOfFour (10 :: Word)
--   False
--   
--   >>> isPowerOfFour (16 :: Word)
--   True
--   
isPowerOfFour :: (IndexableBits a, FiniteBits a) => a -> Bool -- | Check if a number is a power of two (2^n) and return n -- --
--   >>> getPowerOfTwo (10 :: Word)
--   Nothing
--   
--   >>> getPowerOfTwo (16 :: Word)
--   Just 4
--   
getPowerOfTwo :: (IndexableBits a, FiniteBits a) => a -> Maybe Word -- | Check if a number is a power of four (4^n) and return n -- --
--   >>> getPowerOfFour (10 :: Word)
--   Nothing
--   
--   >>> getPowerOfFour (16 :: Word)
--   Just 2
--   
getPowerOfFour :: (IndexableBits a, FiniteBits a) => a -> Maybe Word -- | Posit (type III unum) module Haskus.Number.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.Number.Posit.PositEncoding instance GHC.Show.Show Haskus.Number.Posit.PositFields instance GHC.Classes.Eq Haskus.Number.Posit.PositKind instance GHC.Show.Show Haskus.Number.Posit.PositKind instance (Haskus.Binary.Bits.Bits (Haskus.Number.Int.IntN n), Haskus.Binary.Bits.Finite.FiniteBits (Haskus.Number.Int.IntN n), GHC.Classes.Ord (Haskus.Number.Int.IntN n), GHC.Num.Num (Haskus.Number.Int.IntN n), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat es, GHC.Real.Integral (Haskus.Number.Int.IntN n)) => GHC.Show.Show (Haskus.Number.Posit.Posit n es) -- | Natural numbers module Haskus.Number.BitNat -- | A natural value Proxy data NatVal (t :: Nat) NatVal :: NatVal type Widen a b = (Assert (a <=? b) (() :: Constraint) ( 'Text "Can't widen a natural of " :<>: 'ShowType a :<>: 'Text " bits into a natural of " :<>: 'ShowType b :<>: 'Text " bits"), Integral (BitNatWord a), Integral (BitNatWord b)) -- | Widen a natural -- --
--   >>> widen @7 (BitNat @5 25)
--   BitNat @7 25
--   
widen :: forall b a. Widen a b => BitNat a -> BitNat b type Narrow a b = (Assert (b <=? a) (() :: Constraint) ( 'Text "Can't narrow a natural of " :<>: 'ShowType a :<>: 'Text " bits into a natural of " :<>: 'ShowType b :<>: 'Text " bits"), Integral (BitNatWord a), Integral (BitNatWord b), Maskable b (BitNatWord b)) -- | Narrow a natural -- --
--   >>> narrow @3 (BitNat @5 25)
--   BitNat @3 1
--   
narrow :: forall b a. Narrow a b => BitNat a -> BitNat b type IsBitNat b = (Num (BitNatWord b), Integral (BitNatWord b), Bitwise (BitNatWord b), IndexableBits (BitNatWord b)) -- | A natural on b bits data BitNat (b :: Nat) pattern BitNat :: forall (n :: Nat). (Integral (BitNatWord n), MakeBitNat n) => Natural -> BitNat n -- | Create a natural unsafeMakeBitNat :: forall a. Maskable a (BitNatWord a) => BitNatWord a -> BitNat a -- | Create a natural (check overflow) safeMakeBitNat :: forall a. MakeBitNat a => Natural -> Maybe (BitNat a) -- | Create a natural number with the minimal number of bits required to -- store it -- --
--   >>> bitNat @5
--   BitNat @3 5
--   
-- --
--   >>> bitNat @0
--   BitNat @1 0
--   
-- --
--   >>> bitNat @158748521123465897456465
--   BitNat @78 158748521123465897456465
--   
bitNat :: forall (v :: Nat) (n :: Nat). (n ~ NatBitCount v, Integral (BitNatWord n), MakeBitNat n, KnownNat v) => BitNat n -- | Zero natural bitNatZero :: Num (BitNatWord a) => BitNat a -- | One natural bitNatOne :: Num (BitNatWord a) => BitNat a -- | Extract the primitive value extractW :: BitNat a -> BitNatWord a -- | Compare two naturals compareW :: forall a b. (Ord (BitNatWord (Max a b)), Widen a (Max a b), Widen b (Max a b)) => BitNat a -> BitNat b -> Ordering -- | Add two Naturals -- --
--   >>> BitNat @5 25 .+. BitNat @2 3
--   BitNat @6 28
--   
(.+.) :: forall a b m. (m ~ (Max a b + 1), Widen a m, Widen b m, Num (BitNatWord m)) => BitNat a -> BitNat b -> BitNat m -- | Sub two Naturals -- --
--   >>> BitNat @5 25 .-. BitNat @2 3
--   Just (BitNat @5 22)
--   
-- --
--   >>> BitNat @5 2 .-. BitNat @2 3
--   Nothing
--   
(.-.) :: forall a b m. (m ~ Max a b, Widen a m, Widen b m, Num (BitNatWord m)) => BitNat a -> BitNat b -> Maybe (BitNat m) -- | Multiply two Naturals -- --
--   >>> BitNat @5 25 .*. BitNat @2 3
--   BitNat @7 75
--   
(.*.) :: forall a b m. (m ~ (a + b), Widen a m, Widen b m, Num (BitNatWord m)) => BitNat a -> BitNat b -> BitNat m -- | Divide two Naturals, return (factor,rest) -- --
--   >>> BitNat @5 25 ./. BitNat @2 3
--   Just (BitNat @5 8,BitNat @2 1)
--   
-- --
--   >>> BitNat @5 25 ./. BitNat @2 0
--   Nothing
--   
-- --
--   BitNat @2 3 ./. BitNat @5 25
--   
-- -- Just (BitNat 2 0,BitNat 5 3) (./.) :: forall a b m. (m ~ Max a b, Widen a m, Widen b m, Num (BitNatWord (Min a b))) => BitNat a -> BitNat b -> Maybe (BitNat a, BitNat (Min a b)) type BitNatShiftLeft a s = (ShiftableBits (BitNatWord (a + s)), KnownNat s, Widen a (a + s)) type BitNatShiftRight a s = (ShiftableBits (BitNatWord a), KnownNat s, Narrow a (a - s)) -- | Shift-left naturals -- --
--   >>> let x = BitNat @5 25
--   
--   >>> x .<<. NatVal @2
--   BitNat @7 100
--   
-- --
--   >>> show (x .<<. NatVal @2) == show (x .*. BitNat @3 4)
--   False
--   
-- --
--   >>> x .<<. NatVal @2 == narrow (x .*. BitNat @3 4)
--   True
--   
(.<<.) :: forall (s :: Nat) a. BitNatShiftLeft a s => BitNat a -> NatVal s -> BitNat (a + s) -- | Shift-right naturals -- --
--   >>> BitNat @5 25 .>>. NatVal @2
--   BitNat @3 6
--   
(.>>.) :: forall (s :: Nat) a. BitNatShiftRight a s => BitNat a -> NatVal s -> BitNat (a - s) -- | Test a bit bitNatTestBit :: IndexableBits (BitNatWord a) => BitNat a -> Word -> Bool -- | Xor bitNatXor :: forall a. IsBitNat a => BitNat a -> BitNat a -> BitNat a -- | And bitNatAnd :: forall a. IsBitNat a => BitNat a -> BitNat a -> BitNat a -- | Or bitNatOr :: forall a. IsBitNat a => BitNat a -> BitNat a -> BitNat a -- | BitNat backing type type family BitNatWord b type MakeBitNat a = (Maskable a (BitNatWord a), ShiftableBits (BitNatWord a), Show (BitNatWord a), Eq (BitNatWord a), Num (BitNatWord a)) -- | Convert a BitNat into a Natural bitNatToNatural :: Integral (BitNatWord a) => BitNat a -> Natural instance (GHC.TypeNats.KnownNat b, GHC.Real.Integral (Haskus.Number.BitNat.BitNatWord b)) => GHC.Show.Show (Haskus.Number.BitNat.BitNat b) instance GHC.Classes.Eq (Haskus.Number.BitNat.BitNatWord a) => GHC.Classes.Eq (Haskus.Number.BitNat.BitNat a) instance GHC.Classes.Ord (Haskus.Number.BitNat.BitNatWord a) => GHC.Classes.Ord (Haskus.Number.BitNat.BitNat a) -- | Signed safe numbers module Haskus.Number.SignedSafe -- | A signed number (not in two-complement form) -- -- newtype Signed (b :: Nat) Signed :: BitNat (b + 1) -> Signed -- | Test for zero -- --
--   >>> signedIsZero (signedNeg @5)
--   False
--   
--   >>> signedIsZero (signedNeg @0)
--   True
--   
signedIsZero :: (Num (BitNatWord (b + 1)), Eq (BitNatWord (b + 1))) => Signed b -> Bool -- | Test for NaN -- --
--   >>> signedIsNaN (signedPos @5)
--   False
--   
--   >>> signedIsNaN (signedPos @0)
--   False
--   
signedIsNaN :: (Num (BitNatWord (b + 1)), Eq (BitNatWord (b + 1))) => Signed b -> Bool -- | Create from a BitNat -- --
--   >>> signedFromBitNat (bitNat @18)
--   18
--   
signedFromBitNat :: (ShiftableBits (BitNatWord (b + 1)), Widen b (b + 1)) => BitNat b -> Signed b -- | Negate a signed number -- --
--   >>> signedNegate (signedPos @5)
--   -5
--   
--   >>> signedNegate (signedNeg @5)
--   5
--   
signedNegate :: IsBitNat (b + 1) => Signed b -> Signed b -- | Positive signed literal -- --
--   >>> signedPos @5
--   5
--   
--   >>> signedPos @0
--   0
--   
signedPos :: forall (v :: Nat) b. (b ~ NatBitCount v, MakeBitNat b, Bitwise (BitNatWord b), Integral (BitNatWord (b + 1)), KnownNat v, ShiftableBits (BitNatWord (b + 1)), Widen b (b + 1)) => Signed b -- | Negative signed literal -- --
--   >>> signedNeg @5
--   -5
--   
--   >>> signedNeg @0
--   0
--   
signedNeg :: forall (v :: Nat) b. (b ~ NatBitCount v, MakeBitNat b, Bitwise (BitNatWord b), KnownNat v, Widen b (b + 1), ShiftableBits (BitNatWord (b + 1)), IsBitNat (b + 1)) => Signed b instance (GHC.TypeNats.KnownNat b, GHC.Real.Integral (Haskus.Number.BitNat.BitNatWord b), Haskus.Binary.Bits.Index.IndexableBits (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), GHC.Num.Num (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), GHC.Classes.Eq (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), GHC.Real.Integral (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), Haskus.Binary.Bits.Shift.ShiftableBits (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), Haskus.Number.BitNat.Narrow (b GHC.TypeNats.+ 1) ((b GHC.TypeNats.+ 1) GHC.TypeNats.- 1)) => GHC.Show.Show (Haskus.Number.SignedSafe.Signed b) -- | Signed numbers module Haskus.Number.Signed -- | A signed number (not in two-complement form) -- -- newtype Signed (b :: Nat) Signed :: BitNat (b + 1) -> Signed type SignedIsZero b = (BitNatShiftRight (b + 1) 1) -- | Test for zero -- --
--   >>> signedIsZero (signedNeg @5)
--   False
--   
--   >>> signedIsZero (signedNeg @0)
--   True
--   
signedIsZero :: forall b. SignedIsZero b => Signed b -> Bool type SignedFromBitNat b = (ShiftableBits (BitNatWord (b + 1)), Widen b (b + 1)) -- | Create from a BitNat -- --
--   >>> signedFromBitNat (bitNat @18)
--   18
--   
signedFromBitNat :: forall b. SignedFromBitNat b => BitNat b -> Signed b type SignedNegate b = (IsBitNat (b + 1)) -- | Negate a signed number -- --
--   >>> signedNegate (signedPos @5)
--   -5
--   
--   >>> signedNegate (signedNeg @5)
--   5
--   
signedNegate :: SignedNegate b => Signed b -> Signed b type SignedPos b v = (b ~ NatBitCount v, MakeBitNat b, KnownNat v, BitNatShiftLeft b 1) -- | Positive signed literal -- --
--   >>> signedPos @5
--   5
--   
--   >>> signedPos @0
--   0
--   
signedPos :: forall (v :: Nat) b. SignedPos b v => Signed b type SignedNeg b v = (SignedPos b v, SignedNegate b) -- | Negative signed literal -- --
--   >>> signedNeg @5
--   -5
--   
--   >>> signedNeg @0
--   0
--   
signedNeg :: forall (v :: Nat) b. SignedNeg b v => Signed b instance (GHC.TypeNats.KnownNat b, GHC.Real.Integral (Haskus.Number.BitNat.BitNatWord b), Haskus.Binary.Bits.Index.IndexableBits (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), GHC.Num.Num (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), GHC.Classes.Eq (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), GHC.Real.Integral (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), Haskus.Binary.Bits.Shift.ShiftableBits (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), Haskus.Number.BitNat.Narrow (b GHC.TypeNats.+ 1) ((b GHC.TypeNats.+ 1) GHC.TypeNats.- 1)) => GHC.Show.Show (Haskus.Number.Signed.Signed b) -- | A natural number in a specified range (fixed and checked at -- compile-time) module Haskus.Number.NaturalRange -- | A natural number in the specified range data NatRange (f :: Nat) (t :: Nat) -- | Natural range pattern -- --
--   >>> NatRange @10 @12 11
--   NatRange @10 @12 11
--   
pattern NatRange :: forall (f :: Nat) (t :: Nat). MakeNatRange f t => Natural -> NatRange f t -- | Create a value in a Natural range natRange :: forall (n :: Nat) f t. (MakeNatRange f t, CheckInRange f t n, KnownNat n) => NatRange f t -- | Create a value in a Natural range (check validity) safeMakeNatRange :: forall f t. MakeNatRange f t => Natural -> Maybe (NatRange f t) -- | Create a value in a Natural range (check validity and throw on error) makeNatRange :: forall f t. MakeNatRange f t => Natural -> NatRange f t -- | Create a value in a Natural range unsafeMakeNatRange :: forall f t. MakeNatRange f t => Natural -> NatRange f t -- | Widen a natural -- --
--   >>> let a = NatRange @18 @100 25
--   
--   >>> widenNatRange @16 @200 a
--   NatRange @16 @200 25
--   
widenNatRange :: forall f2 t2 f1 t1. WidenNatRange f1 t1 f2 t2 => NatRange f1 t1 -> NatRange f2 t2 -- | Add two natural ranges -- --
--   >>> NatRange @2 @4 3 .++. NatRange @7 @17 13
--   NatRange @9 @21 16
--   
(.++.) :: (MakeNatRange f1 t1, MakeNatRange f2 t2, MakeNatRange (f1 + f2) (t1 + t2)) => NatRange f1 t1 -> NatRange f2 t2 -> NatRange (f1 + f2) (t1 + t2) instance (GHC.TypeNats.KnownNat (t GHC.TypeNats.- f), GHC.TypeNats.KnownNat t, GHC.TypeNats.KnownNat f, GHC.Num.Num (Haskus.Number.BitNat.BitNatWord (Haskus.Utils.Types.Nat.NatBitCount ((t GHC.TypeNats.- f) GHC.TypeNats.+ 1))), GHC.Real.Integral (Haskus.Number.BitNat.BitNatWord (Haskus.Utils.Types.Nat.NatBitCount ((t GHC.TypeNats.- f) GHC.TypeNats.+ 1)))) => GHC.Show.Show (Haskus.Number.NaturalRange.NatRange f t) -- | Numbers module Haskus.Number -- | Vector with size in the type module Haskus.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.Binary.Vector.Vector n a, r Data.Type.Equality.~ GHC.Types.IO (GHC.Ptr.Ptr a), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat (Haskus.Binary.Storable.SizeOf a), Haskus.Binary.Storable.StaticStorable a, Haskus.Binary.Storable.Storable a) => Haskus.Utils.HList.Apply Haskus.Binary.Vector.StoreVector (v, GHC.Types.IO (GHC.Ptr.Ptr a)) r instance (Haskus.Binary.Storable.Storable a, GHC.Show.Show a, GHC.TypeNats.KnownNat n) => GHC.Show.Show (Haskus.Binary.Vector.Vector n a) instance GHC.TypeNats.KnownNat (Haskus.Binary.Storable.SizeOf a GHC.TypeNats.* n) => Haskus.Binary.Storable.StaticStorable (Haskus.Binary.Vector.Vector n a) instance (GHC.TypeNats.KnownNat n, Haskus.Binary.Storable.Storable a) => Haskus.Binary.Storable.Storable (Haskus.Binary.Vector.Vector n a) instance (GHC.TypeNats.KnownNat n, Haskus.Binary.Storable.Storable a, GHC.Classes.Eq a) => GHC.Classes.Eq (Haskus.Binary.Vector.Vector n a) instance (GHC.TypeNats.KnownNat n, Haskus.Binary.Bits.Bitwise.Bitwise a, Haskus.Binary.Storable.Storable a) => Haskus.Binary.Bits.Bitwise.Bitwise (Haskus.Binary.Vector.Vector n a) instance (GHC.TypeNats.KnownNat (Haskus.Binary.Bits.Finite.BitSize a), Haskus.Binary.Bits.Finite.FiniteBits a, GHC.TypeNats.KnownNat n, Haskus.Binary.Storable.Storable a) => Haskus.Binary.Bits.Finite.FiniteBits (Haskus.Binary.Vector.Vector n a) instance (Haskus.Binary.Storable.Storable a, Haskus.Binary.Bits.Shift.ShiftableBits a, Haskus.Binary.Bits.Bitwise.Bitwise a, Haskus.Binary.Bits.Finite.FiniteBits a, GHC.TypeNats.KnownNat (Haskus.Binary.Bits.Finite.BitSize a), GHC.TypeNats.KnownNat (n GHC.TypeNats.* Haskus.Binary.Bits.Finite.BitSize a), GHC.TypeNats.KnownNat n) => Haskus.Binary.Bits.Shift.ShiftableBits (Haskus.Binary.Vector.Vector n a) instance (Haskus.Binary.Storable.Storable a, Haskus.Binary.Bits.Index.IndexableBits a, Haskus.Binary.Bits.Finite.FiniteBits a, GHC.TypeNats.KnownNat (Haskus.Binary.Bits.Finite.BitSize a), GHC.TypeNats.KnownNat n, Haskus.Binary.Bits.Bitwise.Bitwise a) => Haskus.Binary.Bits.Index.IndexableBits (Haskus.Binary.Vector.Vector n a) instance (Haskus.Binary.Storable.Storable a, Haskus.Binary.Bits.Bits a, GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat (n GHC.TypeNats.* Haskus.Binary.Bits.Finite.BitSize a)) => Haskus.Binary.Bits.Rotate.RotatableBits (Haskus.Binary.Vector.Vector n a) -- | Bit putter module Haskus.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.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.Binary.Bits.Get.BitGetState -- | Get utilities module Haskus.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 -- -- -- -- The word is splitted in chunks of 7 bits, starting from least -- significant bits. Each chunk is put in a Word8. The highest bit -- indicates if there is a following byte (0 false, 1 true) module Haskus.Number.VariableLength -- | Convert a stream of ULEB 128 bytes into an Integral -- --
--   >>> :set -XBinaryLiterals
--   
--   >>> import Control.Monad.Trans.State
--   
--   >>> getNext = do { ~(x:xs) <- get; put xs; pure x }
--   
--   >>> let x = evalState (fromULEB128 getNext) [0b10000001, 0b01111111] :: Word64
--   
--   >>> x == 0b11111110000001
--   True
--   
fromULEB128 :: (Bits a, Monad m, Integral a) => m Word8 -> m a -- | Convert an Integral into a stream of ULEB128 bytes -- --
--   >>> :set -XBinaryLiterals
--   
--   >>> :set -XFlexibleContexts
--   
--   >>> let f = toULEB128 (putStr . (++ " ") . bitsToString)
--   
--   >>> f (0b1001001010101010 :: Word64)
--   10101010 10100101 00000010
--   
toULEB128 :: (Bits a, Monad m, Integral a) => (Word8 -> m ()) -> a -> m () -- | 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.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.Binary.Bits.Index.IndexableBits a => Haskus.Binary.Bits.Index.IndexableBits (Haskus.Binary.Endianness.AsLittleEndian a) instance Haskus.Binary.Bits.Shift.ShiftableBits a => Haskus.Binary.Bits.Shift.ShiftableBits (Haskus.Binary.Endianness.AsLittleEndian a) instance Haskus.Binary.Bits.Rotate.RotatableBits a => Haskus.Binary.Bits.Rotate.RotatableBits (Haskus.Binary.Endianness.AsLittleEndian a) instance Haskus.Binary.Bits.Reverse.ReversableBits a => Haskus.Binary.Bits.Reverse.ReversableBits (Haskus.Binary.Endianness.AsLittleEndian a) instance Haskus.Binary.Bits.Finite.FiniteBits a => Haskus.Binary.Bits.Finite.FiniteBits (Haskus.Binary.Endianness.AsLittleEndian a) instance Haskus.Binary.Bits.Bitwise.Bitwise a => Haskus.Binary.Bits.Bitwise.Bitwise (Haskus.Binary.Endianness.AsLittleEndian a) instance GHC.Real.Real a => GHC.Real.Real (Haskus.Binary.Endianness.AsLittleEndian a) instance GHC.Real.Integral a => GHC.Real.Integral (Haskus.Binary.Endianness.AsLittleEndian a) instance GHC.Num.Num a => GHC.Num.Num (Haskus.Binary.Endianness.AsLittleEndian a) instance GHC.Enum.Enum a => GHC.Enum.Enum (Haskus.Binary.Endianness.AsLittleEndian a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Haskus.Binary.Endianness.AsLittleEndian a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Haskus.Binary.Endianness.AsLittleEndian a) instance Haskus.Binary.Bits.Index.IndexableBits a => Haskus.Binary.Bits.Index.IndexableBits (Haskus.Binary.Endianness.AsBigEndian a) instance Haskus.Binary.Bits.Shift.ShiftableBits a => Haskus.Binary.Bits.Shift.ShiftableBits (Haskus.Binary.Endianness.AsBigEndian a) instance Haskus.Binary.Bits.Rotate.RotatableBits a => Haskus.Binary.Bits.Rotate.RotatableBits (Haskus.Binary.Endianness.AsBigEndian a) instance Haskus.Binary.Bits.Reverse.ReversableBits a => Haskus.Binary.Bits.Reverse.ReversableBits (Haskus.Binary.Endianness.AsBigEndian a) instance Haskus.Binary.Bits.Finite.FiniteBits a => Haskus.Binary.Bits.Finite.FiniteBits (Haskus.Binary.Endianness.AsBigEndian a) instance Haskus.Binary.Bits.Bitwise.Bitwise a => Haskus.Binary.Bits.Bitwise.Bitwise (Haskus.Binary.Endianness.AsBigEndian a) instance GHC.Real.Real a => GHC.Real.Real (Haskus.Binary.Endianness.AsBigEndian a) instance GHC.Real.Integral a => GHC.Real.Integral (Haskus.Binary.Endianness.AsBigEndian a) instance GHC.Num.Num a => GHC.Num.Num (Haskus.Binary.Endianness.AsBigEndian a) instance GHC.Enum.Enum a => GHC.Enum.Enum (Haskus.Binary.Endianness.AsBigEndian a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Haskus.Binary.Endianness.AsBigEndian a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Haskus.Binary.Endianness.AsBigEndian a) instance GHC.Classes.Eq Haskus.Binary.Endianness.WordSize instance GHC.Show.Show Haskus.Binary.Endianness.WordSize instance GHC.Enum.Enum Haskus.Binary.Endianness.Endianness instance GHC.Show.Show Haskus.Binary.Endianness.Endianness instance GHC.Classes.Eq Haskus.Binary.Endianness.Endianness instance GHC.Show.Show a => GHC.Show.Show (Haskus.Binary.Endianness.AsLittleEndian a) instance (Haskus.Binary.Endianness.ByteReversable a, Haskus.Binary.Storable.StaticStorable a) => Haskus.Binary.Storable.StaticStorable (Haskus.Binary.Endianness.AsLittleEndian a) instance (Haskus.Binary.Endianness.ByteReversable a, Haskus.Binary.Storable.Storable a) => Haskus.Binary.Storable.Storable (Haskus.Binary.Endianness.AsLittleEndian a) instance GHC.Show.Show a => GHC.Show.Show (Haskus.Binary.Endianness.AsBigEndian a) instance (Haskus.Binary.Endianness.ByteReversable a, Haskus.Binary.Storable.StaticStorable a) => Haskus.Binary.Storable.StaticStorable (Haskus.Binary.Endianness.AsBigEndian a) instance (Haskus.Binary.Endianness.ByteReversable a, Haskus.Binary.Storable.Storable a) => Haskus.Binary.Storable.Storable (Haskus.Binary.Endianness.AsBigEndian a) instance Haskus.Binary.Endianness.ByteReversable GHC.Word.Word8 instance Haskus.Binary.Endianness.ByteReversable GHC.Word.Word16 instance Haskus.Binary.Endianness.ByteReversable GHC.Word.Word32 instance Haskus.Binary.Endianness.ByteReversable GHC.Word.Word64 instance Haskus.Binary.Enum.CEnum Haskus.Binary.Endianness.Endianness -- | Binary serialization of Haskell values module Haskus.Binary.Serialize.Put -- | 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, BufferSize (Buffer Immutable pin gc heap)) => Buffer Immutable 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 () -- | Write a Float32 with host order putFloat32 :: PutMonad m => Float32 -> m () -- | Write a Float32 with little-endian order putFloat32LE :: PutMonad m => Float32 -> m () -- | Write a Float32 with big-endian order putFloat32BE :: PutMonad m => Float32 -> m () -- | Write a Float64 with host order putFloat64 :: PutMonad m => Float64 -> m () -- | Write a Float64 with little-endian order putFloat64LE :: PutMonad m => Float64 -> m () -- | Write a Float64 with big-endian order putFloat64BE :: PutMonad m => Float64 -> m () -- | 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 () module Haskus.Binary.Serialize.Size newtype GetSize a GetSize :: State Word a -> GetSize a -- | Get the total size runGetSize :: GetSize a -> Word instance GHC.Base.Monad Haskus.Binary.Serialize.Size.GetSize instance GHC.Base.Applicative Haskus.Binary.Serialize.Size.GetSize instance GHC.Base.Functor Haskus.Binary.Serialize.Size.GetSize instance Haskus.Binary.Serialize.Put.PutMonad Haskus.Binary.Serialize.Size.GetSize -- | Binary deserialization of Haskell values module Haskus.Binary.Serialize.Get -- | 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 at the -- optionally specified offset getBufferInto :: GetMonad m => Word -> Buffer 'Mutable pin gc heap -> Maybe Word -> m () -- | Skip the given amount of bytes getSkipBytes :: GetMonad m => Word -> m () -- | Get a Float32 with host order getFloat32 :: GetMonad m => m Float32 -- | Get a Float32 with little-endian order getFloat32LE :: GetMonad m => m Float32 -- | Get a Float32 with big-endian order getFloat32BE :: GetMonad m => m Float32 -- | Get a Float64 with host order getFloat64 :: GetMonad m => m Float64 -- | Get a Float64 with little-endian order getFloat64LE :: GetMonad m => m Float64 -- | Get a Float64 with big-endian order getFloat64BE :: GetMonad m => m Float64 -- | 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] module Haskus.Binary.Serialize.File -- | FileGetT state data FileGetState FileGetState :: !Handle -> FileGetState [fileGetHandle] :: FileGetState -> !Handle -- | A Get monad over a File newtype FileGetT m a FileGetT :: StateT FileGetState m a -> FileGetT m a -- | Run a getter on a file runFileGet :: Handle -> FileGetT IO a -> IO a -- | Run a getter on a file runFilePathGet :: FilePath -> FileGetT IO a -> IO a instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Haskus.Binary.Serialize.File.FileGetT m) instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Haskus.Binary.Serialize.File.FileGetT m) instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Haskus.Binary.Serialize.File.FileGetT m) instance GHC.Base.Monad m => GHC.Base.Monad (Haskus.Binary.Serialize.File.FileGetT m) instance GHC.Base.Monad m => GHC.Base.Applicative (Haskus.Binary.Serialize.File.FileGetT m) instance GHC.Base.Functor m => GHC.Base.Functor (Haskus.Binary.Serialize.File.FileGetT m) instance Control.Monad.IO.Class.MonadIO m => Haskus.Binary.Serialize.Get.GetMonad (Haskus.Binary.Serialize.File.FileGetT m) -- | Serializer into a mutable buffer -- --
--   >>> let w = do putWord8 0x01 ; putWord32BE 0x23456789 ; putWord32BE 0xAABBCCDD
--   
--   >>> b <- newBuffer 10
--   
--   >>> void $ runBufferPut b 0 overflowBufferFail w
--   
--   >>> xs <- forM [0..4] (bufferReadWord8IO b)
--   
--   >>> xs == [0x01,0x23,0x45,0x67,0x89]
--   True
--   
-- --
--   >>> b <- newBuffer 2 -- small buffer
--   
--   >>> (_,b',_) <- runBufferPut b 0 overflowBufferDouble w
--   
--   >>> xs <- forM [0..4] (bufferReadWord8IO b')
--   
--   >>> xs == [0x01,0x23,0x45,0x67,0x89]
--   True
--   
--   >>> bufferSizeIO b'
--   16
--   
module Haskus.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 m 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 -> OverflowStrategy m b -> BufferPutT b m a -> m (a, b, Word) -- | Lift into BufferPutT liftBufferPut :: Monad m => m a -> BufferPutT b m a -- | A Get monad over a Buffer newtype BufferGetT b m a BufferGetT :: StateT (BufferGetState m b) m a -> BufferGetT b m a type BufferGet b a = BufferGetT b Identity a -- | Get current offset getGetOffset :: Monad m => BufferGetT b m Word -- | Get buffer getGetBuffer :: Monad m => BufferGetT b m b -- | Get current offset setGetOffset :: Monad m => Word -> BufferGetT b m () -- | Run a buffer get runBufferGet :: Monad m => b -> Word -> OverflowStrategy m b -> BufferGetT b m a -> m (a, b, Word) -- | Lift into BufferGetT liftBufferGet :: Monad m => m a -> BufferGetT b m a -- | Action to perform when the buffer isn't large enough to contain the -- required data (extend the buffer, flush the data, etc.) -- -- The returned buffer and offset replace the current ones. newtype OverflowStrategy m b OverflowStrategy :: (BufferOverflow b -> m (b, Word)) -> OverflowStrategy m b -- | Buffer extension information data BufferOverflow b BufferOverflow :: b -> Word -> Word -> BufferOverflow b -- | Current buffer [overflowBuffer] :: BufferOverflow b -> b -- | Current offset in buffer [overflowOffset] :: BufferOverflow b -> Word -- | Required size in bytes (don't take into account leftover bytes in the -- current buffer) [overflowRequired] :: BufferOverflow b -> Word -- | Get extend strategy getPutOverflowStrategy :: Monad m => BufferPutT b m (OverflowStrategy m b) -- | Get extend strategy getGetOverflowStrategy :: Monad m => BufferGetT b m (OverflowStrategy m b) -- | Buffer overflow strategy: fails when there isn't enough space left overflowBufferFail :: MonadFail m => OverflowStrategy m b -- | Buffer extend strategy: double the buffer size each time and copy the -- original contents in it overflowBufferDouble :: MonadIO m => OverflowStrategy m BufferM -- | Buffer extend strategy: double the buffer size each time and copy the -- original contents in it overflowBufferDoublePinned :: MonadIO m => Maybe Word -> OverflowStrategy m BufferMP -- | Buffer extend strategy: add the given size each time and copy the -- original contents in it overflowBufferAdd :: MonadIO m => Word -> OverflowStrategy m BufferM -- | Buffer extend strategy: add the given size each time and copy the -- original contents in it overflowBufferAddPinned :: MonadIO m => Maybe Word -> Word -> OverflowStrategy m BufferMP instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Haskus.Binary.Serialize.Buffer.BufferGetT b m) instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Haskus.Binary.Serialize.Buffer.BufferGetT b m) instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Haskus.Binary.Serialize.Buffer.BufferGetT b m) instance GHC.Base.Monad m => GHC.Base.Monad (Haskus.Binary.Serialize.Buffer.BufferGetT b m) instance GHC.Base.Monad m => GHC.Base.Applicative (Haskus.Binary.Serialize.Buffer.BufferGetT b m) instance GHC.Base.Functor m => GHC.Base.Functor (Haskus.Binary.Serialize.Buffer.BufferGetT b m) instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Haskus.Binary.Serialize.Buffer.BufferPutT b m) instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Haskus.Binary.Serialize.Buffer.BufferPutT b m) instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Haskus.Binary.Serialize.Buffer.BufferPutT b m) instance GHC.Base.Monad m => GHC.Base.Monad (Haskus.Binary.Serialize.Buffer.BufferPutT b m) instance GHC.Base.Monad m => GHC.Base.Applicative (Haskus.Binary.Serialize.Buffer.BufferPutT b m) instance GHC.Base.Functor m => GHC.Base.Functor (Haskus.Binary.Serialize.Buffer.BufferPutT b m) instance Control.Monad.IO.Class.MonadIO m => Haskus.Binary.Serialize.Get.GetMonad (Haskus.Binary.Serialize.Buffer.BufferGetT (Haskus.Memory.Buffer.Buffer mut pin gc heap) m) instance Control.Monad.IO.Class.MonadIO m => Haskus.Binary.Serialize.Put.PutMonad (Haskus.Binary.Serialize.Buffer.BufferPutT (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Mutable pin gc heap) m) -- | Binary serialization of Haskell values module Haskus.Binary.Serialize -- | 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 -- -- The default implementation execute the put method with a PutMonad that -- only stores the size in bytes. Overload this function if possible! 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 -> m a -- | Size in bytes data Size -- | Exactly the given size Exactly :: Nat -> Size -- | Dynamically known size (the size is stored with the object) Dynamic :: Size instance Haskus.Binary.Serialize.Serializable GHC.Word.Word8 instance Haskus.Binary.Serialize.Serializable GHC.Word.Word16 instance Haskus.Binary.Serialize.Serializable GHC.Word.Word32 instance Haskus.Binary.Serialize.Serializable GHC.Word.Word64 instance Haskus.Binary.Serialize.Serializable GHC.Int.Int8 instance Haskus.Binary.Serialize.Serializable GHC.Int.Int16 instance Haskus.Binary.Serialize.Serializable GHC.Int.Int32 instance Haskus.Binary.Serialize.Serializable GHC.Int.Int64 instance Haskus.Binary.Serialize.Serializable a => Haskus.Binary.Serialize.Serializable (Haskus.Binary.Endianness.AsBigEndian a) instance Haskus.Binary.Serialize.Serializable a => Haskus.Binary.Serialize.Serializable (Haskus.Binary.Endianness.AsLittleEndian a) -- | 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,BitOffset)
--   
--   -- 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.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 BitOffset a -- | Return the bit offset of an element toBitOffset :: BitOffset a => a -> Word -- | Return the bit offset of an element toBitOffset :: (BitOffset a, Enum a) => a -> Word -- | Return the value associated with a bit offset fromBitOffset :: BitOffset a => Word -> a -- | Return the value associated with a bit offset fromBitOffset :: (BitOffset 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, BitOffset a) => a -> BitSet b a -- | Insert an element in the set insert :: (IndexableBits b, BitOffset a) => BitSet b a -> a -> BitSet b a -- | Remove an element from the set delete :: (IndexableBits b, BitOffset a) => BitSet b a -> a -> BitSet b a -- | Unwrap the bitset toBits :: BitSet b a -> b -- | Wrap a bitset fromBits :: (BitOffset a, FiniteBits b) => b -> BitSet b a -- | Test if an element is in the set member :: (BitOffset a, FiniteBits b, IndexableBits b) => BitSet b a -> a -> Bool -- | Test if an element is in the set elem :: (BitOffset a, FiniteBits b, IndexableBits b) => a -> BitSet b a -> Bool -- | Test if an element is not in the set notMember :: (BitOffset a, FiniteBits b, IndexableBits b) => BitSet b a -> a -> Bool -- | Retrieve elements in the set elems :: (BitOffset 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 :: (BitOffset a, FiniteBits b, IndexableBits b, Foldable m) => m a -> b -- | Convert a bitset into a list of Enum elements toListFromBits :: (BitOffset 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 :: (BitOffset a, FiniteBits b, IndexableBits b, Eq b, Bounded a, Enum a) => b -> [a] -- | Convert a Foldable into a set fromList :: (BitOffset a, IndexableBits b, FiniteBits b, Foldable m) => m a -> BitSet b a -- | Convert a set into a list toList :: (BitOffset a, FiniteBits b, IndexableBits b, Eq b) => BitSet b a -> [a] instance Haskus.Binary.Storable.Storable b => Haskus.Binary.Storable.Storable (Haskus.Binary.BitSet.BitSet b a) instance GHC.Classes.Ord b => GHC.Classes.Ord (Haskus.Binary.BitSet.BitSet b a) instance GHC.Classes.Eq b => GHC.Classes.Eq (Haskus.Binary.BitSet.BitSet b a) instance (GHC.Show.Show a, Haskus.Binary.BitSet.BitOffset a, Haskus.Binary.Bits.Finite.FiniteBits b, Haskus.Binary.Bits.Index.IndexableBits b, GHC.Classes.Eq b) => GHC.Show.Show (Haskus.Binary.BitSet.BitSet b a) instance Haskus.Binary.BitSet.BitOffset GHC.Types.Int instance Haskus.Binary.BitSet.BitOffset GHC.Types.Word instance (Haskus.Binary.Bits.Finite.FiniteBits b, Haskus.Binary.Bits.Index.IndexableBits b, Haskus.Binary.BitSet.BitOffset a, GHC.Classes.Eq b) => GHC.Exts.IsList (Haskus.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,BitOffset)
--   
--   w :: BitFields Word16 '[ BitField 5 X (EnumField Word8 A)
--                          , BitField 9 Y Word16
--                          , BitField 2 Z (BitSet Word8 B)
--                          ]
--   w = BitFields 0x0102
--   
module Haskus.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 ~ Tuple l2) => 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 ~ Tuple lnv) => bs -> t class Field f instance Haskus.Binary.Storable.Storable s => Haskus.Binary.Storable.Storable (Haskus.Binary.BitField.BitField n name s) instance Haskus.Binary.Storable.Storable b => Haskus.Binary.Storable.Storable (Haskus.Binary.BitField.BitFields b f) instance (bs Data.Type.Equality.~ Haskus.Binary.BitField.BitFields w l, b Data.Type.Equality.~ Haskus.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.Binary.BitField.Name (b, i) r instance (bs Data.Type.Equality.~ Haskus.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.Binary.BitField.Extract (bs, Haskus.Utils.HList.HList '[]) lt (bs, Haskus.Utils.HList.HList (Haskus.Binary.BitField.BitFieldTypes lt)), Haskus.Utils.HList.HFoldr' Haskus.Binary.BitField.Name (Haskus.Utils.HList.HList '[]) lt (Haskus.Utils.HList.HList ln), Haskus.Utils.HList.HZipList ln (Haskus.Binary.BitField.BitFieldTypes lt) lnv, GHC.Show.Show (Haskus.Utils.HList.HList lnv)) => GHC.Show.Show (Haskus.Binary.BitField.BitFields w lt) instance (bs Data.Type.Equality.~ Haskus.Binary.BitField.BitFields w l, b Data.Type.Equality.~ Haskus.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.Binary.BitField.Output name l : l2)), Haskus.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ Haskus.Binary.BitField.WholeSize l, GHC.Real.Integral w, Haskus.Binary.Bits.Bits w, GHC.TypeNats.KnownNat (Haskus.Binary.BitField.Offset name l), GHC.TypeNats.KnownNat (Haskus.Binary.BitField.Size name l), Haskus.Binary.BitField.Field (Haskus.Binary.BitField.Output name l)) => Haskus.Utils.HList.Apply Haskus.Binary.BitField.Extract (b, i) r instance (bs Data.Type.Equality.~ Haskus.Binary.BitField.BitFields w lt, Haskus.Utils.HList.HFoldr' Haskus.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.Binary.BitField.BitFieldTypes lt) => GHC.Classes.Eq (Haskus.Binary.BitField.BitFields w lt) instance Haskus.Binary.BitField.Field GHC.Types.Bool instance Haskus.Binary.BitField.Field GHC.Types.Word instance Haskus.Binary.BitField.Field GHC.Word.Word8 instance Haskus.Binary.BitField.Field GHC.Word.Word16 instance Haskus.Binary.BitField.Field GHC.Word.Word32 instance Haskus.Binary.BitField.Field GHC.Word.Word64 instance Haskus.Binary.BitField.Field GHC.Types.Int instance Haskus.Binary.BitField.Field GHC.Int.Int8 instance Haskus.Binary.BitField.Field GHC.Int.Int16 instance Haskus.Binary.BitField.Field GHC.Int.Int32 instance Haskus.Binary.BitField.Field GHC.Int.Int64 instance (Haskus.Binary.Bits.Finite.FiniteBits b, GHC.Real.Integral b, Haskus.Binary.BitSet.BitOffset a) => Haskus.Binary.BitField.Field (Haskus.Binary.BitSet.BitSet b a) instance (GHC.Real.Integral b, Haskus.Binary.Enum.CEnum a) => Haskus.Binary.BitField.Field (Haskus.Binary.Enum.EnumField b a) -- | Fixed-point numbers module Haskus.Number.FixedPoint -- | Unsigned 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) -- --
--   >>> :set -XDataKinds
--   
--   >>> import Data.Word
--   
--   >>> fromIntegral 0 :: FixedPoint Word32 16 16
--   0 % 1
--   
-- --
--   >>> fromIntegral 10 :: FixedPoint Word32 16 16
--   10 % 1
--   
newtype FixedPoint w (i :: Nat) (f :: Nat) FixedPoint :: BitFields w '[BitField i "integer" w, BitField f "fractional" w] -> FixedPoint w -- | Get base value getFixedPointBase :: FixedPoint w i f -> w -- | Set base value fromFixedPointBase :: forall w i f. w -> FixedPoint w i f -- | 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.Binary.Storable.Storable w => Haskus.Binary.Storable.Storable (Haskus.Number.FixedPoint.FixedPoint w i f) instance (GHC.Real.Integral w, Haskus.Binary.Bits.Bits w, Haskus.Binary.BitField.Field w, Haskus.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ (n GHC.TypeNats.+ d), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat d) => GHC.Classes.Eq (Haskus.Number.FixedPoint.FixedPoint w n d) instance (Haskus.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ (i GHC.TypeNats.+ f), GHC.Num.Num w, Haskus.Binary.Bits.Finite.FiniteBits w, Haskus.Binary.Bits.Bits w, GHC.TypeNats.KnownNat i, GHC.TypeNats.KnownNat f, Haskus.Binary.BitField.Field w, GHC.Real.Integral w) => GHC.Num.Num (Haskus.Number.FixedPoint.FixedPoint w i f) instance (Haskus.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ (i GHC.TypeNats.+ f), GHC.Real.Integral w, Haskus.Binary.Bits.Finite.FiniteBits w, Haskus.Binary.Bits.Bits w, Haskus.Binary.BitField.Field w, GHC.TypeNats.KnownNat i, GHC.TypeNats.KnownNat f) => GHC.Real.Real (Haskus.Number.FixedPoint.FixedPoint w i f) instance (GHC.Real.Integral w, Haskus.Binary.Bits.Bits w, Haskus.Binary.BitField.Field w, Haskus.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ (n GHC.TypeNats.+ d), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat d) => GHC.Classes.Ord (Haskus.Number.FixedPoint.FixedPoint w n d) instance (GHC.Real.Integral w, Haskus.Binary.Bits.Bits w, Haskus.Binary.BitField.Field w, Haskus.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.Number.FixedPoint.FixedPoint w n d) module Haskus.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.Binary.Unum.Sign instance GHC.Show.Show Haskus.Binary.Unum.Sign instance GHC.Classes.Eq Haskus.Binary.Unum.UBit instance GHC.Show.Show Haskus.Binary.Unum.UBit instance (GHC.TypeNats.KnownNat (Haskus.Binary.Unum.SORNSize u), GHC.TypeNats.KnownNat (Haskus.Binary.Unum.UnumSize u), Haskus.Binary.Bits.Bits (Haskus.Binary.Unum.BackingWord u), Haskus.Binary.Bits.Bits (Haskus.Binary.Unum.CSORNBackingWord u), GHC.Real.Integral (Haskus.Binary.Unum.CSORNBackingWord u), GHC.Num.Num (Haskus.Binary.Unum.BackingWord u), GHC.Real.Integral (Haskus.Binary.Unum.BackingWord u), Haskus.Utils.HList.HFoldr' Haskus.Binary.Unum.GetLabel [GHC.Base.String] v [GHC.Base.String], Haskus.Binary.BitField.Field (Haskus.Binary.Unum.BackingWord u), Haskus.Binary.Bits.Bits (Haskus.Binary.Unum.SORNBackingWord u), Haskus.Binary.Bits.Bits (Haskus.Binary.Unum.SORNBackingWord u), v Data.Type.Equality.~ Haskus.Binary.Unum.UnumMembers u) => GHC.Show.Show (Haskus.Binary.Unum.CSORN u) instance (GHC.TypeNats.KnownNat (Haskus.Binary.Unum.SORNSize u), Haskus.Binary.Bits.Bits (Haskus.Binary.Unum.SORNBackingWord u), GHC.Num.Num (Haskus.Binary.Unum.BackingWord u), GHC.Real.Integral (Haskus.Binary.Unum.BackingWord u), Haskus.Utils.HList.HFoldr' Haskus.Binary.Unum.GetLabel [GHC.Base.String] v [GHC.Base.String], v Data.Type.Equality.~ Haskus.Binary.Unum.UnumMembers u) => GHC.Show.Show (Haskus.Binary.Unum.SORN u) instance GHC.Classes.Eq (Haskus.Binary.Unum.BackingWord u) => GHC.Classes.Eq (Haskus.Binary.Unum.U u) instance (Haskus.Utils.HList.HFoldr' Haskus.Binary.Unum.GetLabel [GHC.Base.String] v [GHC.Base.String], v Data.Type.Equality.~ Haskus.Binary.Unum.UnumMembers u, GHC.Real.Integral (Haskus.Binary.Unum.BackingWord u)) => GHC.Show.Show (Haskus.Binary.Unum.U u) instance (Haskus.Binary.Unum.UnumNum a, r Data.Type.Equality.~ [GHC.Base.String]) => Haskus.Utils.HList.Apply Haskus.Binary.Unum.GetLabel (a, [GHC.Base.String]) r instance Haskus.Binary.Unum.UnumNum x => Haskus.Binary.Unum.UnumNum (Haskus.Binary.Unum.Uncertain x) instance Haskus.Binary.Unum.UnumNum x => Haskus.Binary.Unum.UnumNum (Haskus.Binary.Unum.Rcp x) instance Haskus.Binary.Unum.UnumNum x => Haskus.Binary.Unum.UnumNum (Haskus.Binary.Unum.Neg x) instance GHC.TypeNats.KnownNat n => Haskus.Binary.Unum.UnumNum (Haskus.Binary.Unum.I n)