-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Bytestring builder with zero intermediate allocation -- -- Please see README.md. @package bytezap @version 1.1.0 module Bytezap -- | Missing byteSwap functions for signed integers. -- -- We have them for unsigned integers, but not for signed. They should -- probably be provided, so I'm considering this a compatibility module -- for the future when we have them. module Raehik.Compat.Data.Int.ByteSwap byteSwapI16 :: Int16 -> Int16 byteSwapI32 :: Int32 -> Int32 byteSwapI64 :: Int64 -> Int64 byteSwapI :: Int -> Int -- | Missing byteSwap functions for unsigned integers. -- -- Don't know why this one is missing. module Raehik.Compat.Data.Word.ByteSwap byteSwap :: Word -> Word module Raehik.Compat.GHC.Exts.GHC908MemcpyPrimops copyAddrToAddrNonOverlapping# :: Addr# -> Addr# -> Int# -> State# RealWorld -> State# RealWorld setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld module Raehik.Compat.GHC.Exts.GHC910UnalignedAddrPrimops indexWord8OffAddrAsWord16# :: Addr# -> Int# -> Word16# readWord8OffAddrAsWord16# :: Addr# -> Int# -> State# d -> (# State# d, Word16# #) writeWord8OffAddrAsWord16# :: Addr# -> Int# -> Word16# -> State# d -> State# d indexWord8OffAddrAsWord32# :: Addr# -> Int# -> Word32# readWord8OffAddrAsWord32# :: Addr# -> Int# -> State# d -> (# State# d, Word32# #) writeWord8OffAddrAsWord32# :: Addr# -> Int# -> Word32# -> State# d -> State# d indexWord8OffAddrAsWord64# :: Addr# -> Int# -> Word64# readWord8OffAddrAsWord64# :: Addr# -> Int# -> State# d -> (# State# d, Word64# #) writeWord8OffAddrAsWord64# :: Addr# -> Int# -> Word64# -> State# d -> State# d indexWord8OffAddrAsWord# :: Addr# -> Int# -> Word# readWord8OffAddrAsWord# :: Addr# -> Int# -> State# d -> (# State# d, Word# #) writeWord8OffAddrAsWord# :: Addr# -> Int# -> Word# -> State# d -> State# d indexWord8OffAddrAsInt16# :: Addr# -> Int# -> Int16# readWord8OffAddrAsInt16# :: Addr# -> Int# -> State# d -> (# State# d, Int16# #) writeWord8OffAddrAsInt16# :: Addr# -> Int# -> Int16# -> State# d -> State# d indexWord8OffAddrAsInt32# :: Addr# -> Int# -> Int32# readWord8OffAddrAsInt32# :: Addr# -> Int# -> State# d -> (# State# d, Int32# #) writeWord8OffAddrAsInt32# :: Addr# -> Int# -> Int32# -> State# d -> State# d indexWord8OffAddrAsInt64# :: Addr# -> Int# -> Int64# readWord8OffAddrAsInt64# :: Addr# -> Int# -> State# d -> (# State# d, Int64# #) writeWord8OffAddrAsInt64# :: Addr# -> Int# -> Int64# -> State# d -> State# d indexWord8OffAddrAsInt# :: Addr# -> Int# -> Int# readWord8OffAddrAsInt# :: Addr# -> Int# -> State# d -> (# State# d, Int# #) writeWord8OffAddrAsInt# :: Addr# -> Int# -> Int# -> State# d -> State# d module Raehik.Compat.Data.Primitive.Types -- | Prim extension class providing unaligned accesses -- -- hoping to get this merged in -- https://github.com/haskell/primitive/issues/409 -- -- (also includes Addr# primops which that issue/PR may not) -- -- Also includes an associated type for size in bytes. Another thing that -- maybe primitive could provide. (Wouldn't be hard!) class Prim a => Prim' a where { type SizeOf a :: Natural; } -- | Read a value from the array. The offset is in bytes. indexWord8ByteArrayAs# :: Prim' a => ByteArray# -> Int# -> a readWord8ByteArrayAs# :: Prim' a => MutableByteArray# s -> Int# -> State# s -> (# State# s, a #) writeWord8ByteArrayAs# :: Prim' a => MutableByteArray# s -> Int# -> a -> State# s -> State# s indexWord8OffAddrAs# :: Prim' a => Addr# -> Int# -> a readWord8OffAddrAs# :: Prim' a => Addr# -> Int# -> State# s -> (# State# s, a #) writeWord8OffAddrAs# :: Prim' a => Addr# -> Int# -> a -> State# s -> State# s -- | Class of types supporting primitive array operations. This includes -- interfacing with GC-managed memory (functions suffixed with -- ByteArray#) and interfacing with unmanaged memory (functions -- suffixed with Addr#). Endianness is platform-dependent. class () => Prim a -- | Size of values of type a. The argument is not used. sizeOf# :: Prim a => a -> Int# -- | Alignment of values of type a. The argument is not used. alignment# :: Prim a => a -> Int# -- | Read a value from the array. The offset is in elements of type -- a rather than in bytes. indexByteArray# :: Prim a => ByteArray# -> Int# -> a -- | Read a value from the mutable array. The offset is in elements of type -- a rather than in bytes. readByteArray# :: Prim a => MutableByteArray# s -> Int# -> State# s -> (# State# s, a #) -- | Write a value to the mutable array. The offset is in elements of type -- a rather than in bytes. writeByteArray# :: Prim a => MutableByteArray# s -> Int# -> a -> State# s -> State# s -- | Fill a slice of the mutable array with a value. The offset and length -- of the chunk are in elements of type a rather than in bytes. setByteArray# :: Prim a => MutableByteArray# s -> Int# -> Int# -> a -> State# s -> State# s -- | Read a value from a memory position given by an address and an offset. -- The memory block the address refers to must be immutable. The offset -- is in elements of type a rather than in bytes. indexOffAddr# :: Prim a => Addr# -> Int# -> a -- | Read a value from a memory position given by an address and an offset. -- The offset is in elements of type a rather than in bytes. readOffAddr# :: Prim a => Addr# -> Int# -> State# s -> (# State# s, a #) -- | Write a value to a memory position given by an address and an offset. -- The offset is in elements of type a rather than in bytes. writeOffAddr# :: Prim a => Addr# -> Int# -> a -> State# s -> State# s -- | Fill a memory block given by an address, an offset and a length. The -- offset and length are in elements of type a rather than in -- bytes. setOffAddr# :: Prim a => Addr# -> Int# -> Int# -> a -> State# s -> State# s -- | Size of values of type a. The argument is not used. -- -- This function has existed since 0.1, but was moved from -- Primitive to Types in version 0.6.3.0. sizeOf :: Prim a => a -> Int instance Raehik.Compat.Data.Primitive.Types.Prim' GHC.Word.Word8 instance Raehik.Compat.Data.Primitive.Types.Prim' GHC.Word.Word16 instance Raehik.Compat.Data.Primitive.Types.Prim' GHC.Word.Word32 instance Raehik.Compat.Data.Primitive.Types.Prim' GHC.Word.Word64 instance Raehik.Compat.Data.Primitive.Types.Prim' GHC.Int.Int8 instance Raehik.Compat.Data.Primitive.Types.Prim' GHC.Int.Int16 instance Raehik.Compat.Data.Primitive.Types.Prim' GHC.Int.Int32 instance Raehik.Compat.Data.Primitive.Types.Prim' GHC.Int.Int64 instance Raehik.Compat.Data.Primitive.Types.Prim' GHC.Types.Word instance Raehik.Compat.Data.Primitive.Types.Prim' GHC.Types.Int -- | I think this should be in primitive. module Raehik.Compat.Data.Primitive.Types.Endian -- | Boxed types which permit reversing byte order ("byte swapping"). class ByteSwap a byteSwap :: ByteSwap a => a -> a newtype ByteOrdered (end :: ByteOrder) a ByteOrdered :: a -> ByteOrdered (end :: ByteOrder) a [unByteOrdered] :: ByteOrdered (end :: ByteOrder) a -> a -- | Newtype for easier instance derivation. newtype PrimByteSwapped a PrimByteSwapped :: a -> PrimByteSwapped a [unPrimByteSwapped] :: PrimByteSwapped a -> a instance GHC.Num.Num a => GHC.Num.Num (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end a) instance GHC.Show.Show a => GHC.Show.Show (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end a) instance Data.Primitive.Types.Prim a => Data.Primitive.Types.Prim (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered 'GHC.ByteOrder.LittleEndian a) instance Raehik.Compat.Data.Primitive.Types.Prim' a => Raehik.Compat.Data.Primitive.Types.Prim' (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered 'GHC.ByteOrder.LittleEndian a) instance (Data.Primitive.Types.Prim a, Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap a) => Data.Primitive.Types.Prim (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered 'GHC.ByteOrder.BigEndian a) instance (Raehik.Compat.Data.Primitive.Types.Prim' a, Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap a) => Raehik.Compat.Data.Primitive.Types.Prim' (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered 'GHC.ByteOrder.BigEndian a) instance (Data.Primitive.Types.Prim a, Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap a) => Data.Primitive.Types.Prim (Raehik.Compat.Data.Primitive.Types.Endian.PrimByteSwapped a) instance (Raehik.Compat.Data.Primitive.Types.Prim' a, Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap a) => Raehik.Compat.Data.Primitive.Types.Prim' (Raehik.Compat.Data.Primitive.Types.Endian.PrimByteSwapped a) instance Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap GHC.Word.Word16 instance Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap GHC.Word.Word32 instance Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap GHC.Word.Word64 instance Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap GHC.Types.Word instance Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap GHC.Int.Int16 instance Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap GHC.Int.Int32 instance Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap GHC.Int.Int64 instance Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap GHC.Types.Int instance Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap GHC.Types.Float instance Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap GHC.Types.Double -- | Struct serializer: serialize fields of known length. -- -- In Haskell-ish terminology, one may consider a C struct to be a -- product type where each field is of known length. Thus, fields may be -- accessed by a fixed offset from the struct start. This is convenient -- for efficient access, since those offsets may be turned into -- immediates on a register in a MOV instruction. -- -- Given a struct-like type, we don't need to track "bytes serialized so -- far" like the general case. We can serialize fields in any order we -- like, since we know where they will sit in the resulting bytestring. -- -- This module provides a serializer specifically for these struct-like -- types. Maybe GHC can write more efficient code for these super-simple -- types! I have no idea. So I'm trying it, and will compare performance. -- -- Notably, this serializer is much less flexible. No monoid! I don't -- really expect anyone to write manual stuff with it-- you should just -- use the generics. That reminds me, TODO could easily provide some TH -- too, and again compare. module Bytezap.Struct -- | A struct poker: base address (constant), byte offset, state token. -- -- We could combine base address and byte offset, but we're aiming for -- code that stores the address in a register and uses immediates to -- access fields (like a good C compiler will do for its structs). So by -- keeping them separate, I'm hoping that we can nudge GHC towards such -- behaviour. type Poke# s = Addr# -> Int# -> State# s -> State# s -- | Poke newtype wrapper. newtype Poke s Poke :: Poke# s -> Poke s [unPoke] :: Poke s -> Poke# s -- | Execute a Poke at a fresh ByteString of the given -- length. unsafeRunPokeBS :: Int -> Poke RealWorld -> ByteString -- | Execute a Poke at a pointer. Returns the number of bytes -- written. -- -- The pointer must be a mutable buffer with enough space to hold the -- poke. Absolutely none of this is checked. Use with caution. Sensible -- uses: -- -- unsafeRunPoke :: MonadPrim s m => Poke s -> Ptr Word8 -> m () -- | Poke a type via its Prim' instance. prim :: forall a s. Prim' a => a -> Poke s -- | The empty poke. Provided here as we can't provide it via empty. emptyPoke :: Poke s -- | Sequence two Pokes. We only require the length of the left -- poke. sequencePokes :: Poke s -> Int -> Poke s -> Poke s -- | essentially memset replicateByte :: Int -> Word8 -> Poke RealWorld -- | Generics for bytezap's struct serializer. -- -- We can't use my generic-data-functions library, because we're doing -- more than just basic monoidal composition. But I still want the same -- pluggable generics, where the user provides the class to use for base -- cases. So I do that. However, unlike g-d-f, the class info can't be -- provided via the user-selected monoid, because you don't select that. -- Instead, we take a simple "index" type. It's pretty much the same -- idea, surprisingly. This way, we can provide a few sensible "versions" -- like in g-f-d, while primarily designing for DIY. module Bytezap.Struct.Generic type family UnwrapGenericS1 a -- | Class for holding info on class to use for poking base cases. -- -- The type is just used to map to class info. It is never instantiated. -- By packing KnownSizeOf into here, we don't need to enforce a -- type-level solution! Now it's up to you how you want to track your -- constant lengths. -- -- We stay unboxed here because the internals are unboxed, just for -- convenience. Maybe this is bad, let me know. class GPokeBase idx where { -- | The state token of our poker. type GPokeBaseSt idx; -- | The type class that provides base case poking. -- -- The type class should provide a function that looks like -- gPokeBase. type GPokeBaseC idx a :: Constraint; -- | The type class that provides poked length (known at compile time). type KnownSizeOf' idx a :: Constraint; } gPokeBase :: (GPokeBase idx, GPokeBaseC idx a) => a -> Poke# (GPokeBaseSt idx) -- | Get the poked length of the given type. Unboxed because I felt like -- it. -- -- I think we have to pass a proxy, because of forall limitations on -- instance signatures. This would be much better with explicit type -- variables (GHC 9.10 or 9.12). sizeOf' :: forall a. (GPokeBase idx, KnownSizeOf' idx a) => Proxy# a -> Int# class GPoke idx f gPoke :: GPoke idx f => f p -> Poke# (GPokeBaseSt idx) instance forall k1 k2 (idx :: k1) (f :: k2 -> GHC.Types.Type) (c :: GHC.Generics.Meta). Bytezap.Struct.Generic.GPoke idx f => Bytezap.Struct.Generic.GPoke idx (GHC.Generics.D1 c f) instance forall k1 k2 (idx :: k1) (f :: k2 -> GHC.Types.Type) (c :: GHC.Generics.Meta). Bytezap.Struct.Generic.GPoke idx f => Bytezap.Struct.Generic.GPoke idx (GHC.Generics.C1 c f) instance forall k1 k2 (idx :: k1) (l :: k2 -> GHC.Types.Type) (r :: k2 -> GHC.Types.Type). (Bytezap.Struct.Generic.GPoke idx l, Bytezap.Struct.Generic.GPoke idx r, Bytezap.Struct.Generic.GPokeBase idx, Bytezap.Struct.Generic.KnownSizeOf' idx (Bytezap.Struct.Generic.UnwrapGenericS1 l)) => Bytezap.Struct.Generic.GPoke idx (l GHC.Generics.:*: r) instance forall k1 k2 (idx :: k1) a (c :: GHC.Generics.Meta). (Bytezap.Struct.Generic.GPokeBase idx, Bytezap.Struct.Generic.GPokeBaseC idx a) => Bytezap.Struct.Generic.GPoke idx (GHC.Generics.S1 c (GHC.Generics.Rec0 a)) instance forall k1 k2 (idx :: k1). Bytezap.Struct.Generic.GPoke idx GHC.Generics.U1 module Bytezap.Poke type Poke# s = Addr# -> Int# -> State# s -> (# State# s, Int# #) -- | Poke newtype wrapper. newtype Poke s Poke :: Poke# s -> Poke s [unPoke] :: Poke s -> Poke# s -- | Execute a Poke at a fresh ByteString of the given -- length. unsafeRunPokeBS :: Int -> Poke RealWorld -> ByteString -- | Execute a Poke at a fresh ByteString of the given -- maximum length. Does not reallocate if final size is less than -- estimated. unsafeRunPokeBSUptoN :: Int -> Poke RealWorld -> ByteString -- | Execute a Poke at a pointer. Returns the number of bytes -- written. -- -- The pointer must be a mutable buffer with enough space to hold the -- poke. Absolutely none of this is checked. Use with caution. Sensible -- uses: -- -- unsafeRunPoke :: MonadPrim s m => Poke s -> Ptr Word8 -> m Int -- | Poke a type via its Prim' instance. prim :: forall a s. Prim' a => a -> Poke s byteString :: ByteString -> Poke RealWorld byteArray# :: ByteArray# -> Int# -> Int# -> Poke s -- | essentially memset replicateByte :: Int -> Word8 -> Poke RealWorld -- | Use a struct poke as a regular poke. -- -- To do this, we must associate a constant byte length with an existing -- poker. Note that pokers don't expose the type of the data they are -- serializing, so this is a very clumsy operation by itself. You should -- only be using this when you have such types in scope, and the constant -- length should be obtained in a sensible manner (e.g. -- KnownSizeOf for generic struct pokers, or your own constant -- size class if you're doing funky stuff). fromStructPoke :: Int -> Poke s -> Poke s instance GHC.Base.Semigroup (Bytezap.Poke.Poke s) instance GHC.Base.Monoid (Bytezap.Poke.Poke s) module Bytezap.Write.Internal -- | A Poke with the associated size it pokes. data Write s Write :: Int -> Poke s -> Write s [size] :: Write s -> Int [poke] :: Write s -> Poke s instance GHC.Base.Semigroup (Bytezap.Write.Internal.Write s) instance GHC.Base.Monoid (Bytezap.Write.Internal.Write s) module Bytezap.Write -- | A Poke with the associated size it pokes. data Write s runWriteBS :: Write RealWorld -> ByteString runWriteBSUptoN :: Write RealWorld -> ByteString prim :: forall a s. Prim' a => a -> Write s byteString :: ByteString -> Write RealWorld byteArray# :: ByteArray# -> Int# -> Int# -> Write s -- | essentially memset replicateByte :: Int -> Word8 -> Write RealWorld module Bytezap.Poke.Derived.Endian w16le :: Word16 -> Poke s w16be :: Word16 -> Poke s w32le :: Word32 -> Poke s w32be :: Word32 -> Poke s w64le :: Word64 -> Poke s w64be :: Word64 -> Poke s i16le :: Int16 -> Poke s i16be :: Int16 -> Poke s i32le :: Int32 -> Poke s i32be :: Int32 -> Poke s i64le :: Int64 -> Poke s i64be :: Int64 -> Poke s module Bytezap.Poke.Derived -- | Poke a ShortByteString. shortByteString :: ShortByteString -> Poke s -- | Poke a Text. text :: Text -> Poke s -- | Poke a Char. -- -- Adapted from utf8-string. char :: Char -> Poke s -- | unsafePokeIndexed pokeAt off n performs n indexed -- pokes starting from off. -- -- Does not check bounds. Largely intended for bytewise pokes where some -- work needs to be performed for each byte (e.g. escaping text and -- poking inline). unsafePokeIndexed :: (Int -> Poke s) -> Int -> Int -> Poke s module Bytezap.Write.Derived -- | Write a ShortByteString. shortByteString :: ShortByteString -> Write s -- | Write a Text. text :: Text -> Write s -- | Write a Char. -- -- Adapted from utf8-string. char :: Char -> Write s module Bytezap.Poke.Json escapedLength8 :: Text -> Int escapeW8 :: Word8 -> Int pokeEscapedTextUnquoted :: Text -> Poke s pokeEscapeW8 :: Word8 -> Poke s w8AsciiHex :: Word8 -> Poke s c_lower_hex_table :: Ptr CChar -- | Utilities for using Naturals as type-level bytes. module Raehik.TypeLevelBytes -- | Reify 8 type-level bytes to a Word64. reifyW64 :: forall n1 n2 n3 n4 n5 n6 n7 n8. (ReifyW8 n1, ReifyW8 n2, ReifyW8 n3, ReifyW8 n4, ReifyW8 n5, ReifyW8 n6, ReifyW8 n7, ReifyW8 n8) => Word64 -- | Reify 4 type-level bytes to a Word32. reifyW32 :: forall n1 n2 n3 n4. (ReifyW8 n1, ReifyW8 n2, ReifyW8 n3, ReifyW8 n4) => Word32 -- | Reify 2 type-level bytes to a Word16. reifyW16 :: forall n1 n2. (ReifyW8 n1, ReifyW8 n2) => Word16 -- | Reify a type-level byte (stored in a type-level Natural) to its -- Word8. -- -- Attempting to reify a Natural larger than 255 results in a type -- error. class ReifyW8 (n :: Natural) reifyW8 :: ReifyW8 n => Word8 instance Raehik.TypeLevelBytes.ReifyW8 0 instance Raehik.TypeLevelBytes.ReifyW8 1 instance Raehik.TypeLevelBytes.ReifyW8 2 instance Raehik.TypeLevelBytes.ReifyW8 3 instance Raehik.TypeLevelBytes.ReifyW8 4 instance Raehik.TypeLevelBytes.ReifyW8 5 instance Raehik.TypeLevelBytes.ReifyW8 6 instance Raehik.TypeLevelBytes.ReifyW8 7 instance Raehik.TypeLevelBytes.ReifyW8 8 instance Raehik.TypeLevelBytes.ReifyW8 9 instance Raehik.TypeLevelBytes.ReifyW8 10 instance Raehik.TypeLevelBytes.ReifyW8 11 instance Raehik.TypeLevelBytes.ReifyW8 12 instance Raehik.TypeLevelBytes.ReifyW8 13 instance Raehik.TypeLevelBytes.ReifyW8 14 instance Raehik.TypeLevelBytes.ReifyW8 15 instance Raehik.TypeLevelBytes.ReifyW8 16 instance Raehik.TypeLevelBytes.ReifyW8 17 instance Raehik.TypeLevelBytes.ReifyW8 18 instance Raehik.TypeLevelBytes.ReifyW8 19 instance Raehik.TypeLevelBytes.ReifyW8 20 instance Raehik.TypeLevelBytes.ReifyW8 21 instance Raehik.TypeLevelBytes.ReifyW8 22 instance Raehik.TypeLevelBytes.ReifyW8 23 instance Raehik.TypeLevelBytes.ReifyW8 24 instance Raehik.TypeLevelBytes.ReifyW8 25 instance Raehik.TypeLevelBytes.ReifyW8 26 instance Raehik.TypeLevelBytes.ReifyW8 27 instance Raehik.TypeLevelBytes.ReifyW8 28 instance Raehik.TypeLevelBytes.ReifyW8 29 instance Raehik.TypeLevelBytes.ReifyW8 30 instance Raehik.TypeLevelBytes.ReifyW8 31 instance Raehik.TypeLevelBytes.ReifyW8 32 instance Raehik.TypeLevelBytes.ReifyW8 33 instance Raehik.TypeLevelBytes.ReifyW8 34 instance Raehik.TypeLevelBytes.ReifyW8 35 instance Raehik.TypeLevelBytes.ReifyW8 36 instance Raehik.TypeLevelBytes.ReifyW8 37 instance Raehik.TypeLevelBytes.ReifyW8 38 instance Raehik.TypeLevelBytes.ReifyW8 39 instance Raehik.TypeLevelBytes.ReifyW8 40 instance Raehik.TypeLevelBytes.ReifyW8 41 instance Raehik.TypeLevelBytes.ReifyW8 42 instance Raehik.TypeLevelBytes.ReifyW8 43 instance Raehik.TypeLevelBytes.ReifyW8 44 instance Raehik.TypeLevelBytes.ReifyW8 45 instance Raehik.TypeLevelBytes.ReifyW8 46 instance Raehik.TypeLevelBytes.ReifyW8 47 instance Raehik.TypeLevelBytes.ReifyW8 48 instance Raehik.TypeLevelBytes.ReifyW8 49 instance Raehik.TypeLevelBytes.ReifyW8 50 instance Raehik.TypeLevelBytes.ReifyW8 51 instance Raehik.TypeLevelBytes.ReifyW8 52 instance Raehik.TypeLevelBytes.ReifyW8 53 instance Raehik.TypeLevelBytes.ReifyW8 54 instance Raehik.TypeLevelBytes.ReifyW8 55 instance Raehik.TypeLevelBytes.ReifyW8 56 instance Raehik.TypeLevelBytes.ReifyW8 57 instance Raehik.TypeLevelBytes.ReifyW8 58 instance Raehik.TypeLevelBytes.ReifyW8 59 instance Raehik.TypeLevelBytes.ReifyW8 60 instance Raehik.TypeLevelBytes.ReifyW8 61 instance Raehik.TypeLevelBytes.ReifyW8 62 instance Raehik.TypeLevelBytes.ReifyW8 63 instance Raehik.TypeLevelBytes.ReifyW8 64 instance Raehik.TypeLevelBytes.ReifyW8 65 instance Raehik.TypeLevelBytes.ReifyW8 66 instance Raehik.TypeLevelBytes.ReifyW8 67 instance Raehik.TypeLevelBytes.ReifyW8 68 instance Raehik.TypeLevelBytes.ReifyW8 69 instance Raehik.TypeLevelBytes.ReifyW8 70 instance Raehik.TypeLevelBytes.ReifyW8 71 instance Raehik.TypeLevelBytes.ReifyW8 72 instance Raehik.TypeLevelBytes.ReifyW8 73 instance Raehik.TypeLevelBytes.ReifyW8 74 instance Raehik.TypeLevelBytes.ReifyW8 75 instance Raehik.TypeLevelBytes.ReifyW8 76 instance Raehik.TypeLevelBytes.ReifyW8 77 instance Raehik.TypeLevelBytes.ReifyW8 78 instance Raehik.TypeLevelBytes.ReifyW8 79 instance Raehik.TypeLevelBytes.ReifyW8 80 instance Raehik.TypeLevelBytes.ReifyW8 81 instance Raehik.TypeLevelBytes.ReifyW8 82 instance Raehik.TypeLevelBytes.ReifyW8 83 instance Raehik.TypeLevelBytes.ReifyW8 84 instance Raehik.TypeLevelBytes.ReifyW8 85 instance Raehik.TypeLevelBytes.ReifyW8 86 instance Raehik.TypeLevelBytes.ReifyW8 87 instance Raehik.TypeLevelBytes.ReifyW8 88 instance Raehik.TypeLevelBytes.ReifyW8 89 instance Raehik.TypeLevelBytes.ReifyW8 90 instance Raehik.TypeLevelBytes.ReifyW8 91 instance Raehik.TypeLevelBytes.ReifyW8 92 instance Raehik.TypeLevelBytes.ReifyW8 93 instance Raehik.TypeLevelBytes.ReifyW8 94 instance Raehik.TypeLevelBytes.ReifyW8 95 instance Raehik.TypeLevelBytes.ReifyW8 96 instance Raehik.TypeLevelBytes.ReifyW8 97 instance Raehik.TypeLevelBytes.ReifyW8 98 instance Raehik.TypeLevelBytes.ReifyW8 99 instance Raehik.TypeLevelBytes.ReifyW8 100 instance Raehik.TypeLevelBytes.ReifyW8 101 instance Raehik.TypeLevelBytes.ReifyW8 102 instance Raehik.TypeLevelBytes.ReifyW8 103 instance Raehik.TypeLevelBytes.ReifyW8 104 instance Raehik.TypeLevelBytes.ReifyW8 105 instance Raehik.TypeLevelBytes.ReifyW8 106 instance Raehik.TypeLevelBytes.ReifyW8 107 instance Raehik.TypeLevelBytes.ReifyW8 108 instance Raehik.TypeLevelBytes.ReifyW8 109 instance Raehik.TypeLevelBytes.ReifyW8 110 instance Raehik.TypeLevelBytes.ReifyW8 111 instance Raehik.TypeLevelBytes.ReifyW8 112 instance Raehik.TypeLevelBytes.ReifyW8 113 instance Raehik.TypeLevelBytes.ReifyW8 114 instance Raehik.TypeLevelBytes.ReifyW8 115 instance Raehik.TypeLevelBytes.ReifyW8 116 instance Raehik.TypeLevelBytes.ReifyW8 117 instance Raehik.TypeLevelBytes.ReifyW8 118 instance Raehik.TypeLevelBytes.ReifyW8 119 instance Raehik.TypeLevelBytes.ReifyW8 120 instance Raehik.TypeLevelBytes.ReifyW8 121 instance Raehik.TypeLevelBytes.ReifyW8 122 instance Raehik.TypeLevelBytes.ReifyW8 123 instance Raehik.TypeLevelBytes.ReifyW8 124 instance Raehik.TypeLevelBytes.ReifyW8 125 instance Raehik.TypeLevelBytes.ReifyW8 126 instance Raehik.TypeLevelBytes.ReifyW8 127 instance Raehik.TypeLevelBytes.ReifyW8 128 instance Raehik.TypeLevelBytes.ReifyW8 129 instance Raehik.TypeLevelBytes.ReifyW8 130 instance Raehik.TypeLevelBytes.ReifyW8 131 instance Raehik.TypeLevelBytes.ReifyW8 132 instance Raehik.TypeLevelBytes.ReifyW8 133 instance Raehik.TypeLevelBytes.ReifyW8 134 instance Raehik.TypeLevelBytes.ReifyW8 135 instance Raehik.TypeLevelBytes.ReifyW8 136 instance Raehik.TypeLevelBytes.ReifyW8 137 instance Raehik.TypeLevelBytes.ReifyW8 138 instance Raehik.TypeLevelBytes.ReifyW8 139 instance Raehik.TypeLevelBytes.ReifyW8 140 instance Raehik.TypeLevelBytes.ReifyW8 141 instance Raehik.TypeLevelBytes.ReifyW8 142 instance Raehik.TypeLevelBytes.ReifyW8 143 instance Raehik.TypeLevelBytes.ReifyW8 144 instance Raehik.TypeLevelBytes.ReifyW8 145 instance Raehik.TypeLevelBytes.ReifyW8 146 instance Raehik.TypeLevelBytes.ReifyW8 147 instance Raehik.TypeLevelBytes.ReifyW8 148 instance Raehik.TypeLevelBytes.ReifyW8 149 instance Raehik.TypeLevelBytes.ReifyW8 150 instance Raehik.TypeLevelBytes.ReifyW8 151 instance Raehik.TypeLevelBytes.ReifyW8 152 instance Raehik.TypeLevelBytes.ReifyW8 153 instance Raehik.TypeLevelBytes.ReifyW8 154 instance Raehik.TypeLevelBytes.ReifyW8 155 instance Raehik.TypeLevelBytes.ReifyW8 156 instance Raehik.TypeLevelBytes.ReifyW8 157 instance Raehik.TypeLevelBytes.ReifyW8 158 instance Raehik.TypeLevelBytes.ReifyW8 159 instance Raehik.TypeLevelBytes.ReifyW8 160 instance Raehik.TypeLevelBytes.ReifyW8 161 instance Raehik.TypeLevelBytes.ReifyW8 162 instance Raehik.TypeLevelBytes.ReifyW8 163 instance Raehik.TypeLevelBytes.ReifyW8 164 instance Raehik.TypeLevelBytes.ReifyW8 165 instance Raehik.TypeLevelBytes.ReifyW8 166 instance Raehik.TypeLevelBytes.ReifyW8 167 instance Raehik.TypeLevelBytes.ReifyW8 168 instance Raehik.TypeLevelBytes.ReifyW8 169 instance Raehik.TypeLevelBytes.ReifyW8 170 instance Raehik.TypeLevelBytes.ReifyW8 171 instance Raehik.TypeLevelBytes.ReifyW8 172 instance Raehik.TypeLevelBytes.ReifyW8 173 instance Raehik.TypeLevelBytes.ReifyW8 174 instance Raehik.TypeLevelBytes.ReifyW8 175 instance Raehik.TypeLevelBytes.ReifyW8 176 instance Raehik.TypeLevelBytes.ReifyW8 177 instance Raehik.TypeLevelBytes.ReifyW8 178 instance Raehik.TypeLevelBytes.ReifyW8 179 instance Raehik.TypeLevelBytes.ReifyW8 180 instance Raehik.TypeLevelBytes.ReifyW8 181 instance Raehik.TypeLevelBytes.ReifyW8 182 instance Raehik.TypeLevelBytes.ReifyW8 183 instance Raehik.TypeLevelBytes.ReifyW8 184 instance Raehik.TypeLevelBytes.ReifyW8 185 instance Raehik.TypeLevelBytes.ReifyW8 186 instance Raehik.TypeLevelBytes.ReifyW8 187 instance Raehik.TypeLevelBytes.ReifyW8 188 instance Raehik.TypeLevelBytes.ReifyW8 189 instance Raehik.TypeLevelBytes.ReifyW8 190 instance Raehik.TypeLevelBytes.ReifyW8 191 instance Raehik.TypeLevelBytes.ReifyW8 192 instance Raehik.TypeLevelBytes.ReifyW8 193 instance Raehik.TypeLevelBytes.ReifyW8 194 instance Raehik.TypeLevelBytes.ReifyW8 195 instance Raehik.TypeLevelBytes.ReifyW8 196 instance Raehik.TypeLevelBytes.ReifyW8 197 instance Raehik.TypeLevelBytes.ReifyW8 198 instance Raehik.TypeLevelBytes.ReifyW8 199 instance Raehik.TypeLevelBytes.ReifyW8 200 instance Raehik.TypeLevelBytes.ReifyW8 201 instance Raehik.TypeLevelBytes.ReifyW8 202 instance Raehik.TypeLevelBytes.ReifyW8 203 instance Raehik.TypeLevelBytes.ReifyW8 204 instance Raehik.TypeLevelBytes.ReifyW8 205 instance Raehik.TypeLevelBytes.ReifyW8 206 instance Raehik.TypeLevelBytes.ReifyW8 207 instance Raehik.TypeLevelBytes.ReifyW8 208 instance Raehik.TypeLevelBytes.ReifyW8 209 instance Raehik.TypeLevelBytes.ReifyW8 210 instance Raehik.TypeLevelBytes.ReifyW8 211 instance Raehik.TypeLevelBytes.ReifyW8 212 instance Raehik.TypeLevelBytes.ReifyW8 213 instance Raehik.TypeLevelBytes.ReifyW8 214 instance Raehik.TypeLevelBytes.ReifyW8 215 instance Raehik.TypeLevelBytes.ReifyW8 216 instance Raehik.TypeLevelBytes.ReifyW8 217 instance Raehik.TypeLevelBytes.ReifyW8 218 instance Raehik.TypeLevelBytes.ReifyW8 219 instance Raehik.TypeLevelBytes.ReifyW8 220 instance Raehik.TypeLevelBytes.ReifyW8 221 instance Raehik.TypeLevelBytes.ReifyW8 222 instance Raehik.TypeLevelBytes.ReifyW8 223 instance Raehik.TypeLevelBytes.ReifyW8 224 instance Raehik.TypeLevelBytes.ReifyW8 225 instance Raehik.TypeLevelBytes.ReifyW8 226 instance Raehik.TypeLevelBytes.ReifyW8 227 instance Raehik.TypeLevelBytes.ReifyW8 228 instance Raehik.TypeLevelBytes.ReifyW8 229 instance Raehik.TypeLevelBytes.ReifyW8 230 instance Raehik.TypeLevelBytes.ReifyW8 231 instance Raehik.TypeLevelBytes.ReifyW8 232 instance Raehik.TypeLevelBytes.ReifyW8 233 instance Raehik.TypeLevelBytes.ReifyW8 234 instance Raehik.TypeLevelBytes.ReifyW8 235 instance Raehik.TypeLevelBytes.ReifyW8 236 instance Raehik.TypeLevelBytes.ReifyW8 237 instance Raehik.TypeLevelBytes.ReifyW8 238 instance Raehik.TypeLevelBytes.ReifyW8 239 instance Raehik.TypeLevelBytes.ReifyW8 240 instance Raehik.TypeLevelBytes.ReifyW8 241 instance Raehik.TypeLevelBytes.ReifyW8 242 instance Raehik.TypeLevelBytes.ReifyW8 243 instance Raehik.TypeLevelBytes.ReifyW8 244 instance Raehik.TypeLevelBytes.ReifyW8 245 instance Raehik.TypeLevelBytes.ReifyW8 246 instance Raehik.TypeLevelBytes.ReifyW8 247 instance Raehik.TypeLevelBytes.ReifyW8 248 instance Raehik.TypeLevelBytes.ReifyW8 249 instance Raehik.TypeLevelBytes.ReifyW8 250 instance Raehik.TypeLevelBytes.ReifyW8 251 instance Raehik.TypeLevelBytes.ReifyW8 252 instance Raehik.TypeLevelBytes.ReifyW8 253 instance Raehik.TypeLevelBytes.ReifyW8 254 instance Raehik.TypeLevelBytes.ReifyW8 255 -- | Efficient type-level bytestring serialization. -- -- [Natural]s have a convenient syntax, and we can use -- them as a type-level bytestring by asserting that each Natural -- is <=255 when reifying. This module provides type classes which -- give you a serializer for a given [Natural]. -- -- We maximize efficiency by grouping bytes into machine words. We have -- to be pretty verbose to achieve this. Each type class attempts to -- group bytes into its machine word type, and if it can't (i.e. not -- enough bytes remain), it hands off to the next type class which -- handles the next smaller machine word. -- -- I did a quick Core check and found that GHC seems to successfully -- generate minimal code for this e.g. for an 8-byte magic, GHC will do -- one writeWord64OffAddr# of a constant. Great! module Bytezap.Struct.TypeLits -- | Serialize a type-level bytestring, largest grouping Word64. class ReifyBytesW64 (ns :: [Natural]) reifyBytesW64 :: ReifyBytesW64 ns => Poke n -- | Serialize a type-level bytestring, largest grouping Word32. class ReifyBytesW32 (ns :: [Natural]) reifyBytesW32 :: ReifyBytesW32 ns => Poke s -- | Serialize a type-level bytestring, largest grouping Word32. class ReifyBytesW16 (ns :: [Natural]) reifyBytesW16 :: ReifyBytesW16 ns => Poke s -- | Serialize a type-level bytestring, byte-by-byte. class ReifyBytesW8 (ns :: [Natural]) reifyBytesW8 :: ReifyBytesW8 ns => Poke s instance Bytezap.Struct.TypeLits.ReifyBytesW8 ns => Bytezap.Struct.TypeLits.ReifyBytesW16 ns instance (Raehik.TypeLevelBytes.ReifyW8 n1, Bytezap.Struct.TypeLits.ReifyBytesW8 ns) => Bytezap.Struct.TypeLits.ReifyBytesW8 (n1 : ns) instance Bytezap.Struct.TypeLits.ReifyBytesW8 '[] instance Bytezap.Struct.TypeLits.ReifyBytesW16 ns => Bytezap.Struct.TypeLits.ReifyBytesW32 ns instance (Raehik.TypeLevelBytes.ReifyW8 n1, Raehik.TypeLevelBytes.ReifyW8 n2, Bytezap.Struct.TypeLits.ReifyBytesW16 ns) => Bytezap.Struct.TypeLits.ReifyBytesW16 (n1 : n2 : ns) instance Bytezap.Struct.TypeLits.ReifyBytesW32 ns => Bytezap.Struct.TypeLits.ReifyBytesW64 ns instance (Raehik.TypeLevelBytes.ReifyW8 n1, Raehik.TypeLevelBytes.ReifyW8 n2, Raehik.TypeLevelBytes.ReifyW8 n3, Raehik.TypeLevelBytes.ReifyW8 n4, Bytezap.Struct.TypeLits.ReifyBytesW32 ns) => Bytezap.Struct.TypeLits.ReifyBytesW32 (n1 : n2 : n3 : n4 : ns) instance (Raehik.TypeLevelBytes.ReifyW8 n1, Raehik.TypeLevelBytes.ReifyW8 n2, Raehik.TypeLevelBytes.ReifyW8 n3, Raehik.TypeLevelBytes.ReifyW8 n4, Raehik.TypeLevelBytes.ReifyW8 n5, Raehik.TypeLevelBytes.ReifyW8 n6, Raehik.TypeLevelBytes.ReifyW8 n7, Raehik.TypeLevelBytes.ReifyW8 n8, Bytezap.Struct.TypeLits.ReifyBytesW64 ns) => Bytezap.Struct.TypeLits.ReifyBytesW64 (n1 : n2 : n3 : n4 : n5 : n6 : n7 : n8 : ns) -- | Handy typenat utils. module Util.TypeNats natVal'' :: forall n. KnownNat n => Natural natValInt :: forall n. KnownNat n => Int -- | Pokes with type-level poke length. module Bytezap.Poke.KnownLen newtype PokeKnownLen (len :: Natural) s PokeKnownLen :: Poke s -> PokeKnownLen (len :: Natural) s [unPokeKnownLen] :: PokeKnownLen (len :: Natural) s -> Poke s mappend' :: PokeKnownLen n s -> PokeKnownLen m s -> PokeKnownLen (n + m) s mempty' :: PokeKnownLen 0 s runPokeKnownLenBS :: forall n. KnownNat n => PokeKnownLen n RealWorld -> ByteString prim :: Prim' a => a -> PokeKnownLen (SizeOf a) s