-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Encode precise binary representations directly in types -- -- Please see README.md. @package binrep @version 0.3.0 -- | Pretty bytestrings via printing each byte as two hex digits. -- -- This is primarily for aeson and when we want better showing of -- non-textual bytestrings. It's not really binrep-related, but it needs -- _somewhere_ to go and my projects that need it usually also touch -- binrep, so here it is. -- -- Sadly, we can't use it to make aeson print integers as hex literals. -- It only deals in Scientifics, and if we tried printing them as -- strings, it would quote them. I need a YAML-like with better -- literals... module Binrep.Extra.HexByteString newtype Hex a Hex :: a -> Hex a [unHex] :: Hex a -> a type HexByteString = Hex ByteString -- | A hex bytestring looks like this: 00 01 89 8a FEff. You can -- mix and match capitalization and spacing, but I prefer to space each -- byte, full caps. parseHexByteString :: (MonadParsec e s m, Token s ~ Char) => ([Word8] -> a) -> m a -- | Parse a byte formatted as two hex digits e.g. EF. You _must_ provide -- both nibbles e.g. 0F, not F. They cannot be spaced -- e.g. E F is invalid. -- -- Returns a value 0-255, so can fit in any Num type that can store that. parseHexByte :: (MonadParsec e s m, Token s ~ Char, Num a) => m a -- | Pretty print to default format 00 12 AB FF: space between -- each byte, all caps. -- -- This format I consider most human readable. I prefer caps to draw -- attention to this being data instead of text (you don't see that many -- capital letters packed together in prose). prettyHexByteString :: (a -> [Word8]) -> a -> Text prettyHexByte :: (Char -> Char) -> Word8 -> (Char, Char) -- | Pretty print to "compact" format 0012abff (often output by -- hashers). prettyHexByteStringCompact :: (a -> [Word8]) -> a -> Text instance GHC.Classes.Eq a => GHC.Classes.Eq (Binrep.Extra.HexByteString.Hex a) instance Data.Data.Data a => Data.Data.Data (Binrep.Extra.HexByteString.Hex a) instance GHC.Generics.Generic (Binrep.Extra.HexByteString.Hex a) instance GHC.Show.Show (Binrep.Extra.HexByteString.Hex Data.ByteString.Internal.ByteString) instance Data.Aeson.Types.FromJSON.FromJSON (Binrep.Extra.HexByteString.Hex Data.ByteString.Internal.ByteString) instance Data.Aeson.Types.ToJSON.ToJSON (Binrep.Extra.HexByteString.Hex Data.ByteString.Internal.ByteString) instance GHC.Show.Show (Binrep.Extra.HexByteString.Hex Data.ByteString.Short.Internal.ShortByteString) instance Data.Aeson.Types.FromJSON.FromJSON (Binrep.Extra.HexByteString.Hex Data.ByteString.Short.Internal.ShortByteString) instance Data.Aeson.Types.ToJSON.ToJSON (Binrep.Extra.HexByteString.Hex Data.ByteString.Short.Internal.ShortByteString) module Binrep.Generic.Internal data Cfg a Cfg :: (String -> a) -> (a -> a -> Bool) -> (a -> Text) -> Cfg a -- | How to turn a constructor name into a byte tag. [cSumTag] :: Cfg a -> String -> a [cSumTagEq] :: Cfg a -> a -> a -> Bool [cSumTagShow] :: Cfg a -> a -> Text -- | Common type error string for when GHC attempts to derive an binrep -- instance for a (the?) void datatype V1. type GErrRefuseVoid = 'Text "Refusing to derive binary representation for void datatype" module Binrep.Put type Builder = BuilderFor StrictByteStringBackend class Put a -- | Serialize to binary. put :: Put a => a -> Builder -- | Run the serializer. runPut :: Put a => a -> ByteString runBuilder :: Builder -> ByteString -- | Put with inlined checks via an environment. class PutWith r a -- | Attempt to serialize to binary with the given environment. putWith :: PutWith r a => r -> a -> Either String Builder -- | Attempt to serialize to binary with the given environment. putWith :: (PutWith r a, Put a) => r -> a -> Either String Builder -- | Helper for wrapping a BinRep into a BinRepWith (for -- encoding). putWithout :: Put a => a -> Either String Builder -- | Run the serializer with the given environment. runPutWith :: PutWith r a => r -> a -> Either String ByteString instance Binrep.Put.Put a => Binrep.Put.PutWith r [a] instance Binrep.Put.Put Data.Void.Void instance Binrep.Put.Put a => Binrep.Put.Put [a] instance (Binrep.Put.Put a, Binrep.Put.Put b) => Binrep.Put.Put (a, b) instance Binrep.Put.Put Data.ByteString.Internal.ByteString instance Binrep.Put.Put GHC.Word.Word8 instance Binrep.Put.Put GHC.Int.Int8 module Binrep.Type.Common -- | Byte order. data Endianness -- | big endian, MSB first. e.g. most network protocols BE :: Endianness -- | little endian, MSB last. e.g. most processor architectures LE :: Endianness instance GHC.Classes.Eq Binrep.Type.Common.Endianness instance GHC.Show.Show Binrep.Type.Common.Endianness instance Data.Data.Data Binrep.Type.Common.Endianness instance GHC.Generics.Generic Binrep.Type.Common.Endianness module Binrep.Util tshow :: Show a => a -> Text -- | Convert some Int i where i >= 0 to a -- Natural. -- -- This is intended for wrapping the output of length functions. -- -- underflows if you call it with a negative Int :) posIntToNat :: Int -> Natural natVal'' :: forall a. KnownNat a => Natural -- | Safe, if silly, byte representation for use at the type level. -- -- Word8 is a special type that GHC doesn't (and I think can't) -- promote to the type level. We only have Naturals, which are -- unbounded. So we define a safe, promotable representation, to allow us -- to prove well-sizedness at compile time. Then we provide a bunch of -- type families and reifying typeclasses to enable going between -- "similar" kinds (Natural) and types (Word8, -- ByteString) respectively. -- -- Type-level functionality is stored in TypeLevel because the -- definitions are even sillier than the ones here. -- -- Do not use this on the term level. That would be _extremely_ silly. module Binrep.Type.Byte class ByteVal (n :: Natural) byteVal :: ByteVal n => Proxy# n -> Word8# type family Length (a :: [k]) :: Natural -- | Efficiently reify a list of type-level Natural bytes to to a -- bytestring builder. -- -- Attempting to reify a Natural larger than 255 results in a type -- error. -- -- This is about as far as one should go for pointless performance here, -- I should think. class ReifyBytes (ns :: [Natural]) reifyBytes :: ReifyBytes ns => Builder class WriteReifiedBytes (ns :: [Natural]) writeReifiedBytes :: WriteReifiedBytes ns => Addr# -> IO () instance (n GHC.Types.~ Binrep.Type.Byte.Length ns, GHC.TypeNats.KnownNat n, Binrep.Type.Byte.WriteReifiedBytes ns) => Binrep.Type.Byte.ReifyBytes ns instance Binrep.Type.Byte.WriteReifiedBytes '[] instance (Binrep.Type.Byte.ByteVal n, Binrep.Type.Byte.WriteReifiedBytes ns) => Binrep.Type.Byte.WriteReifiedBytes (n : ns) instance Binrep.Type.Byte.ByteVal 0 instance Binrep.Type.Byte.ByteVal 1 instance Binrep.Type.Byte.ByteVal 2 instance Binrep.Type.Byte.ByteVal 3 instance Binrep.Type.Byte.ByteVal 4 instance Binrep.Type.Byte.ByteVal 5 instance Binrep.Type.Byte.ByteVal 6 instance Binrep.Type.Byte.ByteVal 7 instance Binrep.Type.Byte.ByteVal 8 instance Binrep.Type.Byte.ByteVal 9 instance Binrep.Type.Byte.ByteVal 10 instance Binrep.Type.Byte.ByteVal 11 instance Binrep.Type.Byte.ByteVal 12 instance Binrep.Type.Byte.ByteVal 13 instance Binrep.Type.Byte.ByteVal 14 instance Binrep.Type.Byte.ByteVal 15 instance Binrep.Type.Byte.ByteVal 16 instance Binrep.Type.Byte.ByteVal 17 instance Binrep.Type.Byte.ByteVal 18 instance Binrep.Type.Byte.ByteVal 19 instance Binrep.Type.Byte.ByteVal 20 instance Binrep.Type.Byte.ByteVal 21 instance Binrep.Type.Byte.ByteVal 22 instance Binrep.Type.Byte.ByteVal 23 instance Binrep.Type.Byte.ByteVal 24 instance Binrep.Type.Byte.ByteVal 25 instance Binrep.Type.Byte.ByteVal 26 instance Binrep.Type.Byte.ByteVal 27 instance Binrep.Type.Byte.ByteVal 28 instance Binrep.Type.Byte.ByteVal 29 instance Binrep.Type.Byte.ByteVal 30 instance Binrep.Type.Byte.ByteVal 31 instance Binrep.Type.Byte.ByteVal 32 instance Binrep.Type.Byte.ByteVal 33 instance Binrep.Type.Byte.ByteVal 34 instance Binrep.Type.Byte.ByteVal 35 instance Binrep.Type.Byte.ByteVal 36 instance Binrep.Type.Byte.ByteVal 37 instance Binrep.Type.Byte.ByteVal 38 instance Binrep.Type.Byte.ByteVal 39 instance Binrep.Type.Byte.ByteVal 40 instance Binrep.Type.Byte.ByteVal 41 instance Binrep.Type.Byte.ByteVal 42 instance Binrep.Type.Byte.ByteVal 43 instance Binrep.Type.Byte.ByteVal 44 instance Binrep.Type.Byte.ByteVal 45 instance Binrep.Type.Byte.ByteVal 46 instance Binrep.Type.Byte.ByteVal 47 instance Binrep.Type.Byte.ByteVal 48 instance Binrep.Type.Byte.ByteVal 49 instance Binrep.Type.Byte.ByteVal 50 instance Binrep.Type.Byte.ByteVal 51 instance Binrep.Type.Byte.ByteVal 52 instance Binrep.Type.Byte.ByteVal 53 instance Binrep.Type.Byte.ByteVal 54 instance Binrep.Type.Byte.ByteVal 55 instance Binrep.Type.Byte.ByteVal 56 instance Binrep.Type.Byte.ByteVal 57 instance Binrep.Type.Byte.ByteVal 58 instance Binrep.Type.Byte.ByteVal 59 instance Binrep.Type.Byte.ByteVal 60 instance Binrep.Type.Byte.ByteVal 61 instance Binrep.Type.Byte.ByteVal 62 instance Binrep.Type.Byte.ByteVal 63 instance Binrep.Type.Byte.ByteVal 64 instance Binrep.Type.Byte.ByteVal 65 instance Binrep.Type.Byte.ByteVal 66 instance Binrep.Type.Byte.ByteVal 67 instance Binrep.Type.Byte.ByteVal 68 instance Binrep.Type.Byte.ByteVal 69 instance Binrep.Type.Byte.ByteVal 70 instance Binrep.Type.Byte.ByteVal 71 instance Binrep.Type.Byte.ByteVal 72 instance Binrep.Type.Byte.ByteVal 73 instance Binrep.Type.Byte.ByteVal 74 instance Binrep.Type.Byte.ByteVal 75 instance Binrep.Type.Byte.ByteVal 76 instance Binrep.Type.Byte.ByteVal 77 instance Binrep.Type.Byte.ByteVal 78 instance Binrep.Type.Byte.ByteVal 79 instance Binrep.Type.Byte.ByteVal 80 instance Binrep.Type.Byte.ByteVal 81 instance Binrep.Type.Byte.ByteVal 82 instance Binrep.Type.Byte.ByteVal 83 instance Binrep.Type.Byte.ByteVal 84 instance Binrep.Type.Byte.ByteVal 85 instance Binrep.Type.Byte.ByteVal 86 instance Binrep.Type.Byte.ByteVal 87 instance Binrep.Type.Byte.ByteVal 88 instance Binrep.Type.Byte.ByteVal 89 instance Binrep.Type.Byte.ByteVal 90 instance Binrep.Type.Byte.ByteVal 91 instance Binrep.Type.Byte.ByteVal 92 instance Binrep.Type.Byte.ByteVal 93 instance Binrep.Type.Byte.ByteVal 94 instance Binrep.Type.Byte.ByteVal 95 instance Binrep.Type.Byte.ByteVal 96 instance Binrep.Type.Byte.ByteVal 97 instance Binrep.Type.Byte.ByteVal 98 instance Binrep.Type.Byte.ByteVal 99 instance Binrep.Type.Byte.ByteVal 100 instance Binrep.Type.Byte.ByteVal 101 instance Binrep.Type.Byte.ByteVal 102 instance Binrep.Type.Byte.ByteVal 103 instance Binrep.Type.Byte.ByteVal 104 instance Binrep.Type.Byte.ByteVal 105 instance Binrep.Type.Byte.ByteVal 106 instance Binrep.Type.Byte.ByteVal 107 instance Binrep.Type.Byte.ByteVal 108 instance Binrep.Type.Byte.ByteVal 109 instance Binrep.Type.Byte.ByteVal 110 instance Binrep.Type.Byte.ByteVal 111 instance Binrep.Type.Byte.ByteVal 112 instance Binrep.Type.Byte.ByteVal 113 instance Binrep.Type.Byte.ByteVal 114 instance Binrep.Type.Byte.ByteVal 115 instance Binrep.Type.Byte.ByteVal 116 instance Binrep.Type.Byte.ByteVal 117 instance Binrep.Type.Byte.ByteVal 118 instance Binrep.Type.Byte.ByteVal 119 instance Binrep.Type.Byte.ByteVal 120 instance Binrep.Type.Byte.ByteVal 121 instance Binrep.Type.Byte.ByteVal 122 instance Binrep.Type.Byte.ByteVal 123 instance Binrep.Type.Byte.ByteVal 124 instance Binrep.Type.Byte.ByteVal 125 instance Binrep.Type.Byte.ByteVal 126 instance Binrep.Type.Byte.ByteVal 127 instance Binrep.Type.Byte.ByteVal 128 instance Binrep.Type.Byte.ByteVal 129 instance Binrep.Type.Byte.ByteVal 130 instance Binrep.Type.Byte.ByteVal 131 instance Binrep.Type.Byte.ByteVal 132 instance Binrep.Type.Byte.ByteVal 133 instance Binrep.Type.Byte.ByteVal 134 instance Binrep.Type.Byte.ByteVal 135 instance Binrep.Type.Byte.ByteVal 136 instance Binrep.Type.Byte.ByteVal 137 instance Binrep.Type.Byte.ByteVal 138 instance Binrep.Type.Byte.ByteVal 139 instance Binrep.Type.Byte.ByteVal 140 instance Binrep.Type.Byte.ByteVal 141 instance Binrep.Type.Byte.ByteVal 142 instance Binrep.Type.Byte.ByteVal 143 instance Binrep.Type.Byte.ByteVal 144 instance Binrep.Type.Byte.ByteVal 145 instance Binrep.Type.Byte.ByteVal 146 instance Binrep.Type.Byte.ByteVal 147 instance Binrep.Type.Byte.ByteVal 148 instance Binrep.Type.Byte.ByteVal 149 instance Binrep.Type.Byte.ByteVal 150 instance Binrep.Type.Byte.ByteVal 151 instance Binrep.Type.Byte.ByteVal 152 instance Binrep.Type.Byte.ByteVal 153 instance Binrep.Type.Byte.ByteVal 154 instance Binrep.Type.Byte.ByteVal 155 instance Binrep.Type.Byte.ByteVal 156 instance Binrep.Type.Byte.ByteVal 157 instance Binrep.Type.Byte.ByteVal 158 instance Binrep.Type.Byte.ByteVal 159 instance Binrep.Type.Byte.ByteVal 160 instance Binrep.Type.Byte.ByteVal 161 instance Binrep.Type.Byte.ByteVal 162 instance Binrep.Type.Byte.ByteVal 163 instance Binrep.Type.Byte.ByteVal 164 instance Binrep.Type.Byte.ByteVal 165 instance Binrep.Type.Byte.ByteVal 166 instance Binrep.Type.Byte.ByteVal 167 instance Binrep.Type.Byte.ByteVal 168 instance Binrep.Type.Byte.ByteVal 169 instance Binrep.Type.Byte.ByteVal 170 instance Binrep.Type.Byte.ByteVal 171 instance Binrep.Type.Byte.ByteVal 172 instance Binrep.Type.Byte.ByteVal 173 instance Binrep.Type.Byte.ByteVal 174 instance Binrep.Type.Byte.ByteVal 175 instance Binrep.Type.Byte.ByteVal 176 instance Binrep.Type.Byte.ByteVal 177 instance Binrep.Type.Byte.ByteVal 178 instance Binrep.Type.Byte.ByteVal 179 instance Binrep.Type.Byte.ByteVal 180 instance Binrep.Type.Byte.ByteVal 181 instance Binrep.Type.Byte.ByteVal 182 instance Binrep.Type.Byte.ByteVal 183 instance Binrep.Type.Byte.ByteVal 184 instance Binrep.Type.Byte.ByteVal 185 instance Binrep.Type.Byte.ByteVal 186 instance Binrep.Type.Byte.ByteVal 187 instance Binrep.Type.Byte.ByteVal 188 instance Binrep.Type.Byte.ByteVal 189 instance Binrep.Type.Byte.ByteVal 190 instance Binrep.Type.Byte.ByteVal 191 instance Binrep.Type.Byte.ByteVal 192 instance Binrep.Type.Byte.ByteVal 193 instance Binrep.Type.Byte.ByteVal 194 instance Binrep.Type.Byte.ByteVal 195 instance Binrep.Type.Byte.ByteVal 196 instance Binrep.Type.Byte.ByteVal 197 instance Binrep.Type.Byte.ByteVal 198 instance Binrep.Type.Byte.ByteVal 199 instance Binrep.Type.Byte.ByteVal 200 instance Binrep.Type.Byte.ByteVal 201 instance Binrep.Type.Byte.ByteVal 202 instance Binrep.Type.Byte.ByteVal 203 instance Binrep.Type.Byte.ByteVal 204 instance Binrep.Type.Byte.ByteVal 205 instance Binrep.Type.Byte.ByteVal 206 instance Binrep.Type.Byte.ByteVal 207 instance Binrep.Type.Byte.ByteVal 208 instance Binrep.Type.Byte.ByteVal 209 instance Binrep.Type.Byte.ByteVal 210 instance Binrep.Type.Byte.ByteVal 211 instance Binrep.Type.Byte.ByteVal 212 instance Binrep.Type.Byte.ByteVal 213 instance Binrep.Type.Byte.ByteVal 214 instance Binrep.Type.Byte.ByteVal 215 instance Binrep.Type.Byte.ByteVal 216 instance Binrep.Type.Byte.ByteVal 217 instance Binrep.Type.Byte.ByteVal 218 instance Binrep.Type.Byte.ByteVal 219 instance Binrep.Type.Byte.ByteVal 220 instance Binrep.Type.Byte.ByteVal 221 instance Binrep.Type.Byte.ByteVal 222 instance Binrep.Type.Byte.ByteVal 223 instance Binrep.Type.Byte.ByteVal 224 instance Binrep.Type.Byte.ByteVal 225 instance Binrep.Type.Byte.ByteVal 226 instance Binrep.Type.Byte.ByteVal 227 instance Binrep.Type.Byte.ByteVal 228 instance Binrep.Type.Byte.ByteVal 229 instance Binrep.Type.Byte.ByteVal 230 instance Binrep.Type.Byte.ByteVal 231 instance Binrep.Type.Byte.ByteVal 232 instance Binrep.Type.Byte.ByteVal 233 instance Binrep.Type.Byte.ByteVal 234 instance Binrep.Type.Byte.ByteVal 235 instance Binrep.Type.Byte.ByteVal 236 instance Binrep.Type.Byte.ByteVal 237 instance Binrep.Type.Byte.ByteVal 238 instance Binrep.Type.Byte.ByteVal 239 instance Binrep.Type.Byte.ByteVal 240 instance Binrep.Type.Byte.ByteVal 241 instance Binrep.Type.Byte.ByteVal 242 instance Binrep.Type.Byte.ByteVal 243 instance Binrep.Type.Byte.ByteVal 244 instance Binrep.Type.Byte.ByteVal 245 instance Binrep.Type.Byte.ByteVal 246 instance Binrep.Type.Byte.ByteVal 247 instance Binrep.Type.Byte.ByteVal 248 instance Binrep.Type.Byte.ByteVal 249 instance Binrep.Type.Byte.ByteVal 250 instance Binrep.Type.Byte.ByteVal 251 instance Binrep.Type.Byte.ByteVal 252 instance Binrep.Type.Byte.ByteVal 253 instance Binrep.Type.Byte.ByteVal 254 instance Binrep.Type.Byte.ByteVal 255 module Binrep.BLen.Internal.AsBLen -- | Helper definitions for using the given type to store byte lengths. -- -- Byte lengths must be non-negative. Thus, the ideal representation is a -- Natural. However, most underlying types that we use -- (ByteString, lists) store their length in Ints. By -- similarly storing an Int ourselves, we could potentially -- improve performance. -- -- I like both options, and don't want to give up either. So we provide -- helpers via a typeclass so that the user doesn't ever have to think -- about the underlying type. -- -- For simplicity, documentation may consider a to be an -- "unsigned" type. For example, underflow refers to a negative -- a result. class AsBLen a -- | Safe blen subtraction, returning Nothing for negative results. -- -- Regular subtraction should only be used when you have a guarantee that -- it won't underflow. safeBLenSub :: AsBLen a => a -> a -> Maybe a -- | Convert some Int i where i >= 0 to a blen. -- -- This is intended for wrapping the output of length functions. posIntToBLen :: AsBLen a => Int -> a -- | Convert some Word# w where w <= maxBound -- a@ to a blen. wordToBLen# :: AsBLen a => Word# -> a -- | Convert some Natural n where n <= maxBound -- a@ to a blen. natToBLen :: AsBLen a => Natural -> a instance Binrep.BLen.Internal.AsBLen.AsBLen GHC.Types.Int instance Binrep.BLen.Internal.AsBLen.AsBLen GHC.Num.Natural.Natural module Binrep.BLen -- | Newtype wrapper for defining BLen instances which are allowed -- to assume the existence of a valid CBLen family instance. newtype WithCBLen a WithCBLen :: a -> WithCBLen a [unWithCBLen] :: WithCBLen a -> a -- | The length in bytes of a value of the given type can be known on the -- cheap e.g. by reading a length field, or using compile time -- information. -- -- Some binary representation building blocks require the notion of -- length in bytes in order to handle, e.g. null padding. One may always -- obtain this by serializing the value, then reading out the length of -- the output bytestring. But in most cases, we can be much more -- efficient. -- -- -- -- This type class enables each type to implement its own efficient -- method of byte length calculation. Aim to write something that plainly -- feels more efficient than full serialization. If that doesn't feel -- possible, you might be working with a type ill-suited for binary -- representation. -- -- A thought: Some instances could be improved by reifying CBLen. -- But it would mess up all the deriving, and it feels like too minor an -- improvement to be worthwhile supporting, writing a bunch of newtype -- wrappers, etc. class BLen a where { -- | The length in bytes of any value of the given type is constant. -- -- Many binary representation primitives are constant, or may be designed -- to "store" their size in their type. This is a stronger statement -- about their length than just blen. -- -- This is now an associated type family of the BLen type class in -- hopes of simplifying the binrep framework. type CBLen a :: Natural; type CBLen a = TypeError ('Text "No CBLen associated family instance defined for " :<>: 'ShowType a); } -- | The length in bytes of the serialized value. -- -- The default implementation reifies the constant length for the type. -- If a type-wide constant length is not defined, it will fail at compile -- time. blen :: BLen a => a -> BLenT -- | The length in bytes of the serialized value. -- -- The default implementation reifies the constant length for the type. -- If a type-wide constant length is not defined, it will fail at compile -- time. blen :: (BLen a, KnownNat (CBLen a)) => a -> BLenT type BLenT = Int typeNatToBLen :: forall n. KnownNat n => BLenT -- | Reify a type's constant byte length to the term level. cblen :: forall a n. (n ~ CBLen a, KnownNat n) => BLenT instance GHC.TypeNats.KnownNat (Binrep.BLen.CBLen a) => Binrep.BLen.BLen (Binrep.BLen.WithCBLen [a]) instance GHC.TypeNats.KnownNat (Binrep.BLen.CBLen a GHC.TypeNats.+ Binrep.BLen.CBLen b) => Binrep.BLen.BLen (Binrep.BLen.WithCBLen (a, b)) instance Binrep.BLen.BLen Data.Void.Void instance Binrep.BLen.BLen a => Binrep.BLen.BLen [a] instance (Binrep.BLen.BLen a, Binrep.BLen.BLen b) => Binrep.BLen.BLen (a, b) instance Binrep.BLen.BLen Data.ByteString.Internal.ByteString instance Binrep.BLen.BLen GHC.Word.Word8 instance Binrep.BLen.BLen GHC.Int.Int8 instance Binrep.BLen.BLen GHC.Word.Word16 instance Binrep.BLen.BLen GHC.Int.Int16 instance Binrep.BLen.BLen GHC.Word.Word32 instance Binrep.BLen.BLen GHC.Int.Int32 instance Binrep.BLen.BLen GHC.Word.Word64 instance Binrep.BLen.BLen GHC.Int.Int64 module Binrep.Get type Getter a = Parser E a class Get a -- | Parse from binary. get :: Get a => Getter a runGet :: Get a => ByteString -> Either E (a, ByteString) runGetter :: Getter a -> ByteString -> Either E (a, ByteString) data E EBase :: EBase -> E EGeneric :: String -> EGeneric -> E data EBase ENoVoid :: EBase EFail :: EBase EEof :: EBase -- | expected first, got second EExpectedByte :: Word8 -> Word8 -> EBase -- | expected first, got second EOverlong :: BLenT -> BLenT -> EBase -- | expected first, got second EExpected :: ByteString -> ByteString -> EBase -- | known fail EFailNamed :: String -> EBase -- | parse fail (where you parse a larger object, then a smaller one in it) EFailParse :: String -> ByteString -> Word8 -> EBase -- | ran out of input, needed precisely n bytes for this part (n -- > 0) ERanOut :: Natural -> EBase data EGeneric EGenericSum :: EGenericSum -> EGeneric EGenericField :: String -> Maybe String -> Natural -> E -> EGeneric data EGenericSum EGenericSumTag :: E -> EGenericSum EGenericSumTagNoMatch :: [String] -> Text -> EGenericSum eBase :: EBase -> Getter a -- | TODO confirm correct operation (error combination) getEWrap :: Get a => (E -> E) -> Getter a getEBase :: Get a => EBase -> Getter a cutEBase :: Getter a -> EBase -> Getter a -- | A type that can be parsed from binary given some environment. -- -- Making this levity polymorphic makes things pretty strange, but is -- useful. See Binrep.Example.FileTable. class GetWith (r :: TYPE rep) a | a -> r -- | Parse from binary with the given environment. getWith :: GetWith r a => r -> Getter a runGetWith :: GetWith (r :: TYPE LiftedRep) a => r -> ByteString -> Either E (a, ByteString) instance GHC.Generics.Generic Binrep.Get.EBase instance GHC.Show.Show Binrep.Get.EBase instance GHC.Classes.Eq Binrep.Get.EBase instance GHC.Generics.Generic Binrep.Get.EGeneric instance GHC.Show.Show Binrep.Get.EGeneric instance GHC.Classes.Eq Binrep.Get.EGeneric instance GHC.Generics.Generic Binrep.Get.E instance GHC.Show.Show Binrep.Get.E instance GHC.Classes.Eq Binrep.Get.E instance GHC.Generics.Generic Binrep.Get.EGenericSum instance GHC.Show.Show Binrep.Get.EGenericSum instance GHC.Classes.Eq Binrep.Get.EGenericSum instance Binrep.Get.Get Data.Void.Void instance Binrep.Get.Get a => Binrep.Get.Get [a] instance (Binrep.Get.Get a, Binrep.Get.Get b) => Binrep.Get.Get (a, b) instance Binrep.Get.Get Data.ByteString.Internal.ByteString instance Binrep.Get.Get GHC.Word.Word8 instance Binrep.Get.Get GHC.Int.Int8 -- | _Experimental._ Generically derive CBLen type family instances. -- -- A type having a valid CBLen instance usually indicates one of -- the following: -- -- -- -- The first two cases must be handled manually. The third case is where -- Haskell generics excel, and the one this module targets. -- -- You can (attempt to) derive a CBLen type family instance -- generically for a type via -- -- instance BLen a where type CBLen a = CBLenGeneric w a -- -- As with deriving BLen generically, you must provide the type -- used to store the sum tag for sum types. -- -- Then try using it. Hopefully it works, or you get a useful type error. -- If not, sorry. I don't have much faith in this code. module Binrep.Generic.CBLen type CBLenGeneric w a = GCBLen w (Rep a) type family GCBLen w (f :: k -> Type) :: Natural type family GCBLenSum w (f :: k -> Type) type family MaybeEq a b -- | I don't know how to pattern match in types without writing type -- families. type family GCBLenCaseMaybe a data JustX a b data NothingX -- | Main end-user binrep module bundling most functionality. -- -- Generics are bundled together in Generic. module Binrep -- | The length in bytes of a Put-able type is the length of the -- serialized term. -- -- Do not use this in BLen instances. It's intended as a proof, -- and potentially for testing purposes. Calculating length in bytes -- shouldn't involve serializing (it should be fast and use minimal -- memory). blenViaPut :: Put a => a -> BLenT -- | Sized vectors. module Binrep.Type.Vector getVector :: KnownNat n => Getter a -> Getter (Vector n a) instance Binrep.BLen.BLen a => Binrep.BLen.BLen (Data.Vector.Sized.Vector n a) instance Binrep.Put.Put a => Binrep.Put.Put (Data.Vector.Sized.Vector n a) instance (Binrep.Get.Get a, GHC.TypeNats.KnownNat n) => Binrep.Get.Get (Data.Vector.Sized.Vector n a) -- | Variable-length integers (varints), a method to store arbitrarily -- large integers in a space efficient manner. -- -- Note that varints aren't particularly efficient due to their decoding -- being slow. They are most interesting when you wish to provide support -- for large integers, but know that many (most?) inputs will be small, -- and want to be space efficient for them. Protocol Buffers uses them -- extensively, while Cap'n Proto swears them off. -- -- TODO -- -- module Binrep.Type.Varint -- | A variable-length unsigned integer (natural). -- -- The base algorithm is to split the natural into groups of 7 bits, and -- use the MSB to indicate whether another octet follows. You must -- specify a handful of type variables, which select precise varint -- behaviour beyond this. See their documentation for details. -- -- You may select the type to use varnats at, but error handling isn't -- provided: negatives won't work correctly, and overflow cannot be -- detected. So most of the time, you probably want Natural and -- Integer. -- -- Some examples: -- -- newtype Varnat (enc :: Encoding) (cont :: ContinuationBitBehaviour) (e :: Endianness) i Varnat :: i -> Varnat (enc :: Encoding) (cont :: ContinuationBitBehaviour) (e :: Endianness) i [getVarnat] :: Varnat (enc :: Encoding) (cont :: ContinuationBitBehaviour) (e :: Endianness) i -> i data ContinuationBitBehaviour -- | on=continue, off=end OnContinues :: ContinuationBitBehaviour -- | on=end, off=continue OffContinues :: ContinuationBitBehaviour data Encoding -- | simple, some varints have the same value Redundant :: Encoding -- | each integer has exactly 1 varint encoding Bijective :: Encoding class VarintContinuation (cont :: ContinuationBitBehaviour) varintContinue :: VarintContinuation cont => Bool testVarintCont :: forall cont a. VarintContinuation cont => Bits a => a -> Int -> Bool setVarintCont :: forall cont a. VarintContinuation cont => Bits a => a -> Int -> a instance GHC.Show.Show i => GHC.Show.Show (Binrep.Type.Varint.Varnat enc cont e i) instance GHC.Real.Integral i => GHC.Real.Integral (Binrep.Type.Varint.Varnat enc cont e i) instance GHC.Real.Real i => GHC.Real.Real (Binrep.Type.Varint.Varnat enc cont e i) instance GHC.Num.Num i => GHC.Num.Num (Binrep.Type.Varint.Varnat enc cont e i) instance GHC.Enum.Enum i => GHC.Enum.Enum (Binrep.Type.Varint.Varnat enc cont e i) instance GHC.Classes.Ord i => GHC.Classes.Ord (Binrep.Type.Varint.Varnat enc cont e i) instance GHC.Classes.Eq i => GHC.Classes.Eq (Binrep.Type.Varint.Varnat enc cont e i) instance (Binrep.Type.Varint.VarintContinuation cont, GHC.Real.Integral i, GHC.Bits.Bits i) => Binrep.Get.Get (Binrep.Type.Varint.Varnat 'Binrep.Type.Varint.Redundant cont 'Binrep.Type.Common.BE i) instance (Binrep.Type.Varint.VarintContinuation cont, GHC.Real.Integral i, GHC.Bits.Bits i) => Binrep.Get.Get (Binrep.Type.Varint.Varnat 'Binrep.Type.Varint.Bijective cont 'Binrep.Type.Common.BE i) instance (Binrep.Type.Varint.VarintContinuation cont, GHC.Real.Integral i, GHC.Bits.Bits i) => Binrep.Get.Get (Binrep.Type.Varint.Varnat 'Binrep.Type.Varint.Redundant cont 'Binrep.Type.Common.LE i) instance (Binrep.Type.Varint.VarintContinuation cont, GHC.Real.Integral i, GHC.Bits.Bits i) => Binrep.Get.Get (Binrep.Type.Varint.Varnat 'Binrep.Type.Varint.Bijective cont 'Binrep.Type.Common.LE i) instance (Binrep.Type.Varint.VarintContinuation cont, GHC.Real.Integral i, GHC.Bits.Bits i) => Binrep.Put.Put (Binrep.Type.Varint.Varnat 'Binrep.Type.Varint.Redundant cont 'Binrep.Type.Common.LE i) instance (Binrep.Type.Varint.VarintContinuation cont, GHC.Real.Integral i, GHC.Bits.Bits i) => Binrep.Put.Put (Binrep.Type.Varint.Varnat 'Binrep.Type.Varint.Redundant cont 'Binrep.Type.Common.BE i) instance Binrep.Type.Varint.VarintContinuation 'Binrep.Type.Varint.OnContinues instance Binrep.Type.Varint.VarintContinuation 'Binrep.Type.Varint.OffContinues -- | Constant-size data. module Binrep.Type.Sized data Size (n :: Natural) type Sized n a = Refined (Size n) a instance GHC.TypeNats.KnownNat n => Binrep.BLen.BLen (Binrep.Type.Sized.Sized n a) instance Binrep.Put.Put a => Binrep.Put.Put (Binrep.Type.Sized.Sized n a) instance (Binrep.Get.Get a, GHC.TypeNats.KnownNat n) => Binrep.Get.Get (Binrep.Type.Sized.Sized n a) instance (Binrep.BLen.BLen a, GHC.TypeNats.KnownNat n) => Refined.Predicate (Binrep.Type.Sized.Size n) a module Binrep.Type.NullPadded data NullPad (n :: Natural) type NullPadded n a = Refined (NullPad n) a getNNulls :: BLenT -> Parser E () instance GHC.TypeNats.KnownNat n => Binrep.BLen.BLen (Binrep.Type.NullPadded.NullPadded n a) instance (Binrep.Put.Put a, Binrep.BLen.BLen a, GHC.TypeNats.KnownNat n) => Binrep.Put.Put (Binrep.Type.NullPadded.NullPadded n a) instance (Binrep.Get.Get a, Binrep.BLen.BLen a, GHC.TypeNats.KnownNat n) => Binrep.Get.Get (Binrep.Type.NullPadded.NullPadded n a) instance (Binrep.BLen.BLen a, GHC.TypeNats.KnownNat n) => Refined.Predicate (Binrep.Type.NullPadded.NullPad n) a -- | Inefficient attempt at UTF-8 magics. -- -- To encode UTF-8 strings to bytestrings at compile time, we really need -- more support from the compiler. We can go Char -> Natural, -- but we can't go Natural -> [Natural] where each value is -- <= 255. Doing so is hard without bit twiddling. -- -- The best we can do is get reify the Symbol directly, then -- encode as UTF-8 at runtime. It's a bit of a farce, and we can't derive -- a CBLen instance, but works just fine. Actually, I dunno, it -- might be faster than the bytewise magic handling, depending on how GHC -- optimizes its instances. module Binrep.Type.Magic.UTF8 data MagicUTF8 (str :: Symbol) MagicUTF8 :: MagicUTF8 (str :: Symbol) symVal :: forall str. KnownSymbol str => String encodeStringUtf8 :: String -> ByteString instance GHC.Show.Show (Binrep.Type.Magic.UTF8.MagicUTF8 str) instance GHC.TypeLits.KnownSymbol str => Binrep.BLen.BLen (Binrep.Type.Magic.UTF8.MagicUTF8 str) instance GHC.TypeLits.KnownSymbol str => Binrep.Put.Put (Binrep.Type.Magic.UTF8.MagicUTF8 str) instance GHC.TypeLits.KnownSymbol str => Binrep.Get.Get (Binrep.Type.Magic.UTF8.MagicUTF8 str) -- | Magic numbers (also just magic): short constant bytestrings usually -- found at the top of a file, often used as an early sanity check. -- -- TODO unassociated type fams bad (maybe). turn into class -- and turn -- the reifier into a default method! (TODO think about this) -- -- There are two main flavors of magics: -- -- -- -- For bytewise magics, use type-level Natural lists. For ASCII -- magics, use Symbols (type-level strings). -- -- Previously, I squashed these into a representationally-safe type. Now -- the check only occurs during reification. So you are able to define -- invalid magics now (bytes over 255, non-ASCII characters), and -- potentially use them, but you'll get a clear type error like "no -- instance for ByteVal 256" when attempting to reify. -- -- String magics are restricted to ASCII, and will type error during -- reification otherwise. If you really want UTF-8, please read -- UTF8. module Binrep.Type.Magic -- | An empty data type representing a magic number (a constant bytestring) -- via a phantom type. -- -- The phantom type variable unambiguously defines a short, constant -- bytestring. A handful of types are supported for using magics -- conveniently, e.g. for pure ASCII magics, you may use a Symbol -- type-level string. data Magic (a :: k) Magic :: Magic (a :: k) type family SymbolUnicodeCodepoints (a :: Symbol) :: [Natural] type family CharListUnicodeCodepoints (a :: [Char]) :: [Natural] type family SymbolAsCharList (a :: Symbol) :: [Char] type family SymbolAsCharList' (a :: Maybe (Char, Symbol)) :: [Char] -- | Types which define a magic value. class Magical (a :: k) where { -- | How to turn the type into a list of bytes. type MagicBytes a :: [Natural]; } instance forall k (a :: k). GHC.Classes.Eq (Binrep.Type.Magic.Magic a) instance forall k (a :: k). GHC.Show.Show (Binrep.Type.Magic.Magic a) instance forall k (a :: k). (Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable k) => Data.Data.Data (Binrep.Type.Magic.Magic a) instance forall k (a :: k). GHC.Generics.Generic (Binrep.Type.Magic.Magic a) instance forall k (a :: k). GHC.TypeNats.KnownNat (Binrep.Type.Byte.Length (Binrep.Type.Magic.MagicBytes a)) => Binrep.BLen.BLen (Binrep.Type.Magic.Magic a) instance forall k (bs :: [GHC.Num.Natural.Natural]) (a :: k). (bs GHC.Types.~ Binrep.Type.Magic.MagicBytes a, Binrep.Type.Byte.ReifyBytes bs) => Binrep.Put.Put (Binrep.Type.Magic.Magic a) instance forall k (bs :: [GHC.Num.Natural.Natural]) (a :: k). (bs GHC.Types.~ Binrep.Type.Magic.MagicBytes a, Binrep.Type.Byte.ReifyBytes bs) => Binrep.Get.Get (Binrep.Type.Magic.Magic a) instance Binrep.Type.Magic.Magical ns instance Binrep.Type.Magic.Magical sym instance forall k (a :: k). Strongweak.Weaken.Weaken (Binrep.Type.Magic.Magic a) instance forall k (a :: k). Strongweak.Strengthen.Strengthen (Binrep.Type.Magic.Magic a) module Binrep.Type.Int -- | Wrapper type grouping machine integers (sign, size) along with an -- explicit endianness. -- -- The internal representation is selected via a type family to -- correspond to the relevant Haskell data type, so common overflow -- behaviour should match. We derive lots of handy instances, so you may -- perform regular arithmetic on pairs of these types. For example: -- --
--   >>> 255 + 1 :: I 'U 'I1 e
--   0
--   
-- --
--   >>> 255 + 1 :: I 'U 'I2 e
--   256
--   
newtype I (sign :: ISign) (size :: ISize) (e :: Endianness) I :: IRep sign size -> I (sign :: ISign) (size :: ISize) (e :: Endianness) [getI] :: I (sign :: ISign) (size :: ISize) (e :: Endianness) -> IRep sign size -- | Machine integer sign. data ISign -- | signed S :: ISign -- | unsigned U :: ISign -- | Machine integer size in number of bytes. data ISize I1 :: ISize I2 :: ISize I4 :: ISize I8 :: ISize -- | Grouping for matching a signedness and size to a Haskell integer data -- type. type family IRep (sign :: ISign) (size :: ISize) -- | Shortcut. type family IMax (sign :: ISign) (size :: ISize) :: Natural -- | Restricted reflected version of maxBound. type family MaxBound w :: Natural instance GHC.Classes.Eq Binrep.Type.Int.ISign instance GHC.Show.Show Binrep.Type.Int.ISign instance Data.Data.Data Binrep.Type.Int.ISign instance GHC.Generics.Generic Binrep.Type.Int.ISign instance GHC.Classes.Eq Binrep.Type.Int.ISize instance GHC.Show.Show Binrep.Type.Int.ISize instance Data.Data.Data Binrep.Type.Int.ISize instance GHC.Generics.Generic Binrep.Type.Int.ISize instance GHC.Generics.Generic (Binrep.Type.Int.I sign size e) instance (Data.Data.Data (Binrep.Type.Int.IRep sign size), Data.Typeable.Internal.Typeable sign, Data.Typeable.Internal.Typeable size, Data.Typeable.Internal.Typeable e) => Data.Data.Data (Binrep.Type.Int.I sign size e) instance GHC.Show.Show (Binrep.Type.Int.IRep sign size) => GHC.Show.Show (Binrep.Type.Int.I sign size e) instance GHC.Classes.Eq (Binrep.Type.Int.IRep sign size) => GHC.Classes.Eq (Binrep.Type.Int.I sign size e) instance GHC.Classes.Ord (Binrep.Type.Int.IRep sign size) => GHC.Classes.Ord (Binrep.Type.Int.I sign size e) instance GHC.Enum.Bounded (Binrep.Type.Int.IRep sign size) => GHC.Enum.Bounded (Binrep.Type.Int.I sign size e) instance GHC.Num.Num (Binrep.Type.Int.IRep sign size) => GHC.Num.Num (Binrep.Type.Int.I sign size e) instance GHC.Real.Real (Binrep.Type.Int.IRep sign size) => GHC.Real.Real (Binrep.Type.Int.I sign size e) instance GHC.Enum.Enum (Binrep.Type.Int.IRep sign size) => GHC.Enum.Enum (Binrep.Type.Int.I sign size e) instance GHC.Real.Integral (Binrep.Type.Int.IRep sign size) => GHC.Real.Integral (Binrep.Type.Int.I sign size e) instance Data.Aeson.Types.ToJSON.ToJSON (Binrep.Type.Int.IRep sign size) => Data.Aeson.Types.ToJSON.ToJSON (Binrep.Type.Int.I sign size e) instance Data.Aeson.Types.FromJSON.FromJSON (Binrep.Type.Int.IRep sign size) => Data.Aeson.Types.FromJSON.FromJSON (Binrep.Type.Int.I sign size e) instance (irep GHC.Types.~ Binrep.Type.Int.IRep 'Binrep.Type.Int.U size, GHC.Real.Integral irep) => Strongweak.Weaken.Weaken (Binrep.Type.Int.I 'Binrep.Type.Int.U size end) instance (irep GHC.Types.~ Binrep.Type.Int.IRep 'Binrep.Type.Int.U size, GHC.Real.Integral irep, GHC.Enum.Bounded irep, GHC.Show.Show irep, Data.Typeable.Internal.Typeable size, Data.Typeable.Internal.Typeable end) => Strongweak.Strengthen.Strengthen (Binrep.Type.Int.I 'Binrep.Type.Int.U size end) instance (irep GHC.Types.~ Binrep.Type.Int.IRep 'Binrep.Type.Int.S size, GHC.Real.Integral irep) => Strongweak.Weaken.Weaken (Binrep.Type.Int.I 'Binrep.Type.Int.S size end) instance (irep GHC.Types.~ Binrep.Type.Int.IRep 'Binrep.Type.Int.S size, GHC.Real.Integral irep, GHC.Enum.Bounded irep, GHC.Show.Show irep, Data.Typeable.Internal.Typeable size, Data.Typeable.Internal.Typeable end) => Strongweak.Strengthen.Strengthen (Binrep.Type.Int.I 'Binrep.Type.Int.S size end) instance GHC.TypeNats.KnownNat (Binrep.BLen.CBLen (Binrep.Type.Int.I sign size end)) => Binrep.BLen.BLen (Binrep.Type.Int.I sign size end) instance Binrep.Put.Put (Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I1 e) instance Binrep.Get.Get (Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I1 e) instance Binrep.Put.Put (Binrep.Type.Int.I 'Binrep.Type.Int.S 'Binrep.Type.Int.I1 e) instance Binrep.Get.Get (Binrep.Type.Int.I 'Binrep.Type.Int.S 'Binrep.Type.Int.I1 e) instance Binrep.Put.Put (Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I2 'Binrep.Type.Common.BE) instance Binrep.Get.Get (Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I2 'Binrep.Type.Common.BE) instance Binrep.Put.Put (Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I2 'Binrep.Type.Common.LE) instance Binrep.Get.Get (Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I2 'Binrep.Type.Common.LE) instance Binrep.Put.Put (Binrep.Type.Int.I 'Binrep.Type.Int.S 'Binrep.Type.Int.I2 'Binrep.Type.Common.BE) instance Binrep.Get.Get (Binrep.Type.Int.I 'Binrep.Type.Int.S 'Binrep.Type.Int.I2 'Binrep.Type.Common.BE) instance Binrep.Put.Put (Binrep.Type.Int.I 'Binrep.Type.Int.S 'Binrep.Type.Int.I2 'Binrep.Type.Common.LE) instance Binrep.Get.Get (Binrep.Type.Int.I 'Binrep.Type.Int.S 'Binrep.Type.Int.I2 'Binrep.Type.Common.LE) instance Binrep.Put.Put (Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I4 'Binrep.Type.Common.BE) instance Binrep.Get.Get (Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I4 'Binrep.Type.Common.BE) instance Binrep.Put.Put (Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I4 'Binrep.Type.Common.LE) instance Binrep.Get.Get (Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I4 'Binrep.Type.Common.LE) instance Binrep.Put.Put (Binrep.Type.Int.I 'Binrep.Type.Int.S 'Binrep.Type.Int.I4 'Binrep.Type.Common.BE) instance Binrep.Get.Get (Binrep.Type.Int.I 'Binrep.Type.Int.S 'Binrep.Type.Int.I4 'Binrep.Type.Common.BE) instance Binrep.Put.Put (Binrep.Type.Int.I 'Binrep.Type.Int.S 'Binrep.Type.Int.I4 'Binrep.Type.Common.LE) instance Binrep.Get.Get (Binrep.Type.Int.I 'Binrep.Type.Int.S 'Binrep.Type.Int.I4 'Binrep.Type.Common.LE) instance Binrep.Put.Put (Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I8 'Binrep.Type.Common.BE) instance Binrep.Get.Get (Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I8 'Binrep.Type.Common.BE) instance Binrep.Put.Put (Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I8 'Binrep.Type.Common.LE) instance Binrep.Get.Get (Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I8 'Binrep.Type.Common.LE) instance Binrep.Put.Put (Binrep.Type.Int.I 'Binrep.Type.Int.S 'Binrep.Type.Int.I8 'Binrep.Type.Common.BE) instance Binrep.Get.Get (Binrep.Type.Int.I 'Binrep.Type.Int.S 'Binrep.Type.Int.I8 'Binrep.Type.Common.BE) instance Binrep.Put.Put (Binrep.Type.Int.I 'Binrep.Type.Int.S 'Binrep.Type.Int.I8 'Binrep.Type.Common.LE) instance Binrep.Get.Get (Binrep.Type.Int.I 'Binrep.Type.Int.S 'Binrep.Type.Int.I8 'Binrep.Type.Common.LE) module Binrep.Type.LenPfx -- | Holy shit - no need to do a smart constructor, it's simply impossible -- to instantiate invalid values of this type! data LenPfx (size :: ISize) (end :: Endianness) a LenPfx :: Vector n a -> LenPfx (size :: ISize) (end :: Endianness) a [unLenPfx] :: LenPfx (size :: ISize) (end :: Endianness) a -> Vector n a vsEq :: forall a n m. (Eq a, KnownNat n, KnownNat m) => Vector n a -> Vector m a -> Bool asLenPfx :: forall size end n a irep. (irep ~ IRep 'U size, KnownNat n, KnownNat (MaxBound irep)) => Vector n a -> Maybe (LenPfx size end a) lenPfxFromList :: forall size end a irep. (irep ~ IRep 'U size, KnownNat (MaxBound irep)) => [a] -> Maybe (LenPfx size end a) lenPfxSize :: Num (IRep 'U size) => LenPfx size end a -> I 'U size end getLenPfx :: forall size end a itype irep. (itype ~ I 'U size end, irep ~ IRep 'U size, Get itype, Integral irep, KnownNat (MaxBound irep)) => Getter a -> Getter (LenPfx size end a) instance GHC.Generics.Generic (Binrep.Type.LenPfx.LenPfx size end a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Binrep.Type.LenPfx.LenPfx size end a) instance GHC.Show.Show a => GHC.Show.Show (Binrep.Type.LenPfx.LenPfx size end a) instance Strongweak.Weaken.Weaken (Binrep.Type.LenPfx.LenPfx size end a) instance (GHC.TypeNats.KnownNat (Binrep.Type.Int.MaxBound (Binrep.Type.Int.IRep 'Binrep.Type.Int.U size)), GHC.Show.Show a, Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable size, Data.Typeable.Internal.Typeable end) => Strongweak.Strengthen.Strengthen (Binrep.Type.LenPfx.LenPfx size end a) instance (Binrep.BLen.BLen a, itype GHC.Types.~ Binrep.Type.Int.I 'Binrep.Type.Int.U size end, GHC.TypeNats.KnownNat (Binrep.BLen.CBLen itype)) => Binrep.BLen.BLen (Binrep.Type.LenPfx.LenPfx size end a) instance (itype GHC.Types.~ Binrep.Type.Int.I 'Binrep.Type.Int.U size end, irep GHC.Types.~ Binrep.Type.Int.IRep 'Binrep.Type.Int.U size, Binrep.Put.Put a, Binrep.Put.Put itype, GHC.Num.Num irep) => Binrep.Put.Put (Binrep.Type.LenPfx.LenPfx size end a) instance (itype GHC.Types.~ Binrep.Type.Int.I 'Binrep.Type.Int.U size end, irep GHC.Types.~ Binrep.Type.Int.IRep 'Binrep.Type.Int.U size, Binrep.Get.Get itype, GHC.Real.Integral irep, Binrep.Get.Get a, GHC.TypeNats.KnownNat (Binrep.Type.Int.MaxBound irep)) => Binrep.Get.Get (Binrep.Type.LenPfx.LenPfx size end a) -- | Machine bytestrings. -- -- I mix string and bytestring terminology here due to bad C influences, -- but this module is specifically interested in bytestrings and their -- encoding. String/text encoding is handled in another module. -- -- Note that the length prefix predicate is also defined here... because -- that's just Pascal-style bytestrings, extended to other types. I can't -- easily put it in an orphan module, because we define byte length for -- *all length-prefixed types* in one fell swoop. module Binrep.Type.ByteString -- | Bytestring representation. data Rep -- | C-style bytestring. Arbitrary length, terminated with a null byte. -- Permits no null bytes inside the bytestring. C :: Rep -- | Pascal-style bytestring. Length defined in a prefixing integer of -- given size and endianness. Pascal :: ISize -> Endianness -> Rep -- | A bytestring using the given representation, stored in the -- Text type. type AsByteString (rep :: Rep) = Refined rep ByteString getCString :: Getter ByteString putCString :: ByteString -> Builder instance GHC.Classes.Eq Binrep.Type.ByteString.Rep instance GHC.Show.Show Binrep.Type.ByteString.Rep instance Data.Data.Data Binrep.Type.ByteString.Rep instance GHC.Generics.Generic Binrep.Type.ByteString.Rep instance Binrep.BLen.BLen (Binrep.Type.ByteString.AsByteString 'Binrep.Type.ByteString.C) instance Binrep.Put.Put (Binrep.Type.ByteString.AsByteString 'Binrep.Type.ByteString.C) instance Binrep.Get.Get (Binrep.Type.ByteString.AsByteString 'Binrep.Type.ByteString.C) instance (itype GHC.Types.~ Binrep.Type.Int.I 'Binrep.Type.Int.U size end, irep GHC.Types.~ Binrep.Type.Int.IRep 'Binrep.Type.Int.U size, GHC.TypeNats.KnownNat (Binrep.BLen.CBLen irep)) => Binrep.BLen.BLen (Binrep.Type.ByteString.AsByteString ('Binrep.Type.ByteString.Pascal size end)) instance (itype GHC.Types.~ Binrep.Type.Int.I 'Binrep.Type.Int.U size end, irep GHC.Types.~ Binrep.Type.Int.IRep 'Binrep.Type.Int.U size, Binrep.Put.Put itype, GHC.Num.Num irep) => Binrep.Put.Put (Binrep.Type.ByteString.AsByteString ('Binrep.Type.ByteString.Pascal size end)) instance (itype GHC.Types.~ Binrep.Type.Int.I 'Binrep.Type.Int.U size end, irep GHC.Types.~ Binrep.Type.Int.IRep 'Binrep.Type.Int.U size, GHC.Real.Integral irep, Binrep.Get.Get itype) => Binrep.Get.Get (Binrep.Type.ByteString.AsByteString ('Binrep.Type.ByteString.Pascal size end)) instance Refined.Predicate 'Binrep.Type.ByteString.C Data.ByteString.Internal.ByteString instance (irep GHC.Types.~ Binrep.Type.Int.IRep 'Binrep.Type.Int.U size, GHC.Enum.Bounded irep, GHC.Real.Integral irep, GHC.Show.Show irep, Data.Typeable.Internal.Typeable size, Data.Typeable.Internal.Typeable e) => Refined.Predicate ('Binrep.Type.ByteString.Pascal size e) Data.ByteString.Internal.ByteString module Binrep.Type.Text -- | Character encoding. -- -- Byte-oriented encodings like ASCII and UTF-8 don't need to worry about -- endianness. For UTF-16 and UTF-32, the designers decided to allow -- different endiannesses, rather than saying "codepoints must be -- X-endian". data Encoding UTF8 :: Encoding UTF16 :: Endianness -> Encoding UTF32 :: Endianness -> Encoding -- | 7-bit ASCII :: Encoding SJIS :: Encoding -- | A string of a given encoding, stored in the Text type. type AsText (enc :: Encoding) = Refined enc Text -- | Bytestring encoders for text validated for a given encoding. class Encode (enc :: Encoding) -- | Encode some validated text. encode :: forall enc. Encode enc => AsText enc -> Bytes class Decode (enc :: Encoding) -- | Decode a ByteString to Text with an explicit encoding. -- -- This is intended to be used with visible type applications. decode :: Decode enc => Bytes -> Either String (AsText enc) -- | Encode some text to a bytestring, asserting that the resulting value -- is valid for the requested bytestring representation. -- -- This is intended to be used with visible type applications: -- --
--   >>> let Right t = refine @'UTF8 (Text.pack "hi")
--   
--   >>> :t t
--   t :: AsText 'UTF8
--   
--   >>> let Right bs = encodeToRep @'C t
--   
--   >>> :t bs
--   bs :: Refined 'C Bytes
--   
encodeToRep :: forall (rep :: Rep) enc. (Encode enc, Predicate rep Bytes) => AsText enc -> Either RefineException (Refined rep Bytes) decodeViaTextICU :: String -> ByteString -> IO (Either String Text) instance GHC.Classes.Eq Binrep.Type.Text.Encoding instance GHC.Show.Show Binrep.Type.Text.Encoding instance Data.Data.Data Binrep.Type.Text.Encoding instance GHC.Generics.Generic Binrep.Type.Text.Encoding instance Binrep.Type.Text.Decode 'Binrep.Type.Text.UTF8 instance Binrep.Type.Text.Decode ('Binrep.Type.Text.UTF16 'Binrep.Type.Common.BE) instance Binrep.Type.Text.Decode ('Binrep.Type.Text.UTF16 'Binrep.Type.Common.LE) instance Binrep.Type.Text.Decode ('Binrep.Type.Text.UTF32 'Binrep.Type.Common.BE) instance Binrep.Type.Text.Decode ('Binrep.Type.Text.UTF32 'Binrep.Type.Common.LE) instance Binrep.Type.Text.Decode 'Binrep.Type.Text.SJIS instance Binrep.Type.Text.Encode 'Binrep.Type.Text.UTF8 instance Binrep.Type.Text.Encode 'Binrep.Type.Text.ASCII instance Binrep.Type.Text.Encode ('Binrep.Type.Text.UTF16 'Binrep.Type.Common.BE) instance Binrep.Type.Text.Encode ('Binrep.Type.Text.UTF16 'Binrep.Type.Common.LE) instance Binrep.Type.Text.Encode ('Binrep.Type.Text.UTF32 'Binrep.Type.Common.BE) instance Binrep.Type.Text.Encode ('Binrep.Type.Text.UTF32 'Binrep.Type.Common.LE) instance Binrep.Type.Text.Encode 'Binrep.Type.Text.SJIS instance Refined.Predicate 'Binrep.Type.Text.UTF8 Data.Text.Internal.Text instance Data.Typeable.Internal.Typeable e => Refined.Predicate ('Binrep.Type.Text.UTF16 e) Data.Text.Internal.Text instance Data.Typeable.Internal.Typeable e => Refined.Predicate ('Binrep.Type.Text.UTF32 e) Data.Text.Internal.Text instance Refined.Predicate 'Binrep.Type.Text.ASCII Data.Text.Internal.Text instance Refined.Predicate 'Binrep.Type.Text.SJIS Data.Text.Internal.Text -- | Naturals represented via ASCII numerals. -- -- A concept which sees occasional use in places where neither speed nor -- size efficiency matter. -- -- The tar file format uses it, apparently to sidestep making a decision -- on byte ordering. Though digits are encoded "big-endian", so, uh. I -- don't get it. -- -- I don't really see the usage of these. It seems silly and inefficient, -- aimed solely at easing debugging. module Binrep.Type.AsciiNat -- | A Natural represented in binary as an ASCII string, where each -- character a is a digit in the given base (> 1). -- -- Show instances display the stored number in the given base. If -- the base has a common prefix (e.g. 0x for hex), it is used. newtype AsciiNat (base :: Natural) AsciiNat :: Natural -> AsciiNat (base :: Natural) [getAsciiNat] :: AsciiNat (base :: Natural) -> Natural -- | Compare two AsciiNats with arbitrary bases. asciiNatCompare :: AsciiNat b1 -> AsciiNat b2 -> Ordering octalFromAsciiDigit :: Word8 -> Maybe Word8 natToAsciiBytes :: (Word8 -> Word8) -> Natural -> Natural -> Builder asciiBytesToNat :: (Word8 -> Maybe Word8) -> Natural -> ByteString -> Either Word8 Natural digits :: forall b a. (Integral a, Integral b) => a -> a -> NonEmpty b instance GHC.Classes.Ord (Binrep.Type.AsciiNat.AsciiNat base) instance GHC.Classes.Eq (Binrep.Type.AsciiNat.AsciiNat base) instance GHC.TypeNats.KnownNat base => Data.Data.Data (Binrep.Type.AsciiNat.AsciiNat base) instance GHC.Generics.Generic (Binrep.Type.AsciiNat.AsciiNat base) instance GHC.Show.Show (Binrep.Type.AsciiNat.AsciiNat 2) instance GHC.Show.Show (Binrep.Type.AsciiNat.AsciiNat 8) instance GHC.Show.Show (Binrep.Type.AsciiNat.AsciiNat 10) instance GHC.Show.Show (Binrep.Type.AsciiNat.AsciiNat 16) instance GHC.TypeNats.KnownNat base => Binrep.BLen.BLen (Binrep.Type.AsciiNat.AsciiNat base) instance Binrep.Put.Put (Binrep.Type.AsciiNat.AsciiNat 8) instance Binrep.Get.Get (Binrep.Type.AsciiNat.AsciiNat 8) module Binrep.Example.FileTable type BS = ByteString newtype Table s a Table :: SW s (LenPfx 'I1 'LE (Entry s a)) -> Table s a [unTable] :: Table s a -> SW s (LenPfx 'I1 'LE (Entry s a)) putFileTable :: (Put a, BLen a) => Table 'Strong a -> Builder prepEntry :: (Put a, BLen a) => Entry 'Strong a -> (BLenT, Word8 -> Builder, BS) getFileTable :: Get a => Getter (Table 'Strong a) data Entry s a Entry :: a -> SW s (Refined (SizeLessThan (IMax 'U 'I1)) BS) -> Entry s a [entryName] :: Entry s a -> a [entryData] :: Entry s a -> SW s (Refined (SizeLessThan (IMax 'U 'I1)) BS) getEntry :: Get a => Addr# -> Getter (Entry 'Strong a) w8i# :: Word8# -> Int# exBs :: BS instance GHC.Generics.Generic (Binrep.Example.FileTable.Entry s a) instance GHC.Show.Show a => GHC.Show.Show (Binrep.Example.FileTable.Entry 'Strongweak.Weaken.Weak a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Binrep.Example.FileTable.Entry 'Strongweak.Weaken.Weak a) instance GHC.Show.Show a => GHC.Show.Show (Binrep.Example.FileTable.Entry 'Strongweak.Weaken.Strong a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Binrep.Example.FileTable.Entry 'Strongweak.Weaken.Strong a) instance (Binrep.Put.Put a, Binrep.BLen.BLen a) => Binrep.Put.Put (Binrep.Example.FileTable.Table 'Strongweak.Weaken.Strong a) instance Binrep.Get.Get a => Binrep.Get.Get (Binrep.Example.FileTable.Table 'Strongweak.Weaken.Strong a) instance Strongweak.Weaken.Weaken (Binrep.Example.FileTable.Entry 'Strongweak.Weaken.Strong a) instance Strongweak.Strengthen.Strengthen (Binrep.Example.FileTable.Entry 'Strongweak.Weaken.Strong a) instance Binrep.Get.Get a => Binrep.Get.GetWith GHC.Prim.Addr# (Binrep.Example.FileTable.Entry 'Strongweak.Weaken.Strong a) module Data.Aeson.Extra.SizedVector instance Data.Aeson.Types.ToJSON.ToJSON (v a) => Data.Aeson.Types.ToJSON.ToJSON (Data.Vector.Generic.Sized.Internal.Vector v n a) instance (Data.Aeson.Types.FromJSON.FromJSON (v a), GHC.TypeNats.KnownNat n, Data.Vector.Generic.Base.Vector v a) => Data.Aeson.Types.FromJSON.FromJSON (Data.Vector.Generic.Sized.Internal.Vector v n a) module Haskpatch.Format.Bps -- | TODO * can't do generic because BPS doesn't store command list length, -- instead requiring a dynamic check on every command * wonder if this is -- better or more efficient that using a BpsVarint for the length, -- same as metadata, or storing the end size as a BpsVarint. * -- maybe two diff types of varint, +ve and -ve. unclear from spec * -- perhaps store the varint type(s) as a type var, to allow switching -- between efficient machine ints and safe Integer, -- Natural! data Bps (s :: Strength) i a Bps :: SW s (Magic "BPS1") -> SW s (BpsVarint i) -> SW s (BpsVarint i) -> BpsMeta a -> [BpsCommand] -> BpsFooter s -> Bps (s :: Strength) i a [bpsMagic] :: Bps (s :: Strength) i a -> SW s (Magic "BPS1") [bpsSourceSize] :: Bps (s :: Strength) i a -> SW s (BpsVarint i) [bpsTargetSize] :: Bps (s :: Strength) i a -> SW s (BpsVarint i) -- | Optional metadata. According to the specification, this should -- "officially" be XML version 1.0 encoding UTF-8 data, but anything -- goes. [bpsMetadata] :: Bps (s :: Strength) i a -> BpsMeta a [bpsCommands] :: Bps (s :: Strength) i a -> [BpsCommand] [bpsFooter] :: Bps (s :: Strength) i a -> BpsFooter s type BpsVarint = Varnat 'Bijective 'OffContinues 'LE data BpsMeta a data BpsCommand BpsCommandSourceRead :: BpsCommand BpsCommandTargetRead :: BpsCommand BpsCommandSourceCopy :: BpsCommand BpsCommandTargetCopy :: BpsCommand data BpsFooter (s :: Strength) BpsFooter :: SW s (Sized 4 ByteString) -> SW s (Sized 4 ByteString) -> SW s (Sized 4 ByteString) -> BpsFooter (s :: Strength) [bpsFooterSourceChecksum] :: BpsFooter (s :: Strength) -> SW s (Sized 4 ByteString) [bpsFooterTargetChecksum] :: BpsFooter (s :: Strength) -> SW s (Sized 4 ByteString) [bpsFooterPatchChecksum] :: BpsFooter (s :: Strength) -> SW s (Sized 4 ByteString) module Haskpatch.Format.Vcdiff data Vcdiff (s :: Strength) Vcdiff :: Header s -> Vcdiff (s :: Strength) [vcdiffHeader] :: Vcdiff (s :: Strength) -> Header s data Header (s :: Strength) Header :: SW s (Magic '[0xD6, 0xC3, 0xC4, 0x00]) -> SW s (Magic '[0x00]) -> Header (s :: Strength) -- | First 3 bytes are VCD each with their MSB on. [headerMagic] :: Header (s :: Strength) -> SW s (Magic '[0xD6, 0xC3, 0xC4, 0x00]) -- | TODO annoying and impacts rest of format. forcing to 0x00 to simplify [headerIndicator] :: Header (s :: Strength) -> SW s (Magic '[0x00]) data Window (s :: Strength) Window :: SW s (Magic '[0x00]) -> Delta s -> Window (s :: Strength) [windowIndicator] :: Window (s :: Strength) -> SW s (Magic '[0x00]) [windowDelta] :: Window (s :: Strength) -> Delta s data Delta (s :: Strength) Delta :: SW s (Magic '[0x00]) -> ByteString -> [InstrCode] -> ByteString -> Delta (s :: Strength) [deltaIndicator] :: Delta (s :: Strength) -> SW s (Magic '[0x00]) [deltaAddRun] :: Delta (s :: Strength) -> ByteString [deltaInstrs] :: Delta (s :: Strength) -> [InstrCode] [deltaCopy] :: Delta (s :: Strength) -> ByteString data InstrCode InstrCode :: InstrTriple -> InstrTriple -> InstrCode [instrCodeTriple1] :: InstrCode -> InstrTriple [instrCodeTriple2] :: InstrCode -> InstrTriple data InstrTriple InstrTriple :: Instr -> Word8 -> Word8 -> InstrTriple [instrTripleInstr] :: InstrTriple -> Instr [instrTripleSize] :: InstrTriple -> Word8 -- | 0 and meaningless unless instr is a COPY [instrTripleMode] :: InstrTriple -> Word8 data Instr Instr0Noop :: Instr Instr1Add :: Instr Instr2Run :: Instr Instr3Copy :: Instr -- | Apparently from the Sfio library, also similar (but not identical) to -- BPS's varints. type VcdiffVarint = Varnat 'Redundant 'OnContinues 'BE Natural module Util.Generic -- | datatypeName without the value (only used as a proxy). Lets us -- push our undefineds into one place. datatypeName' :: forall d. Datatype d => String -- | conName without the value (only used as a proxy). Lets us push -- our undefineds into one place. conName' :: forall c. Constructor c => String -- | selName without the value (only used as a proxy). Lets us push -- our undefineds into one place. selName' :: forall s. Selector s => String -- | Get the record name for a selector if present. -- -- On the type level, a 'Maybe Symbol' is stored for record names. But -- the reification is done using fromMaybe "". So we have to -- inspect the resulting string to determine whether the field uses -- record syntax or not. (Silly.) selName'' :: forall s. Selector s => Maybe String module Binrep.Generic.Put putGeneric :: (Generic a, GPut (Rep a), Put w) => Cfg w -> a -> Builder class GPut f gput :: (GPut f, Put w) => Cfg w -> f p -> Builder class GPutSum f gputsum :: (GPutSum f, Put w) => Cfg w -> f a -> Builder -- | Get the name of the constructor of a sum datatype. class GetConName f getConName :: GetConName f => f a -> String instance forall k (l :: k -> *) (r :: k -> *). (Binrep.Generic.Put.GPutSum (l GHC.Generics.:+: r), Binrep.Generic.Put.GetConName (l GHC.Generics.:+: r)) => Binrep.Generic.Put.GPut (l GHC.Generics.:+: r) instance forall k (a :: k -> *) (b :: k -> *). (Binrep.Generic.Put.GetConName a, Binrep.Generic.Put.GetConName b) => Binrep.Generic.Put.GetConName (a GHC.Generics.:+: b) instance forall k (c :: GHC.Generics.Meta) (a :: k -> *). GHC.Generics.Constructor c => Binrep.Generic.Put.GetConName (GHC.Generics.C1 c a) instance forall k (l :: k -> *) (r :: k -> *). (Binrep.Generic.Put.GPutSum l, Binrep.Generic.Put.GPutSum r) => Binrep.Generic.Put.GPutSum (l GHC.Generics.:+: r) instance forall k (r :: k -> *) (c :: GHC.Generics.Meta). (Binrep.Generic.Put.GPut r, GHC.Generics.Constructor c) => Binrep.Generic.Put.GPutSum (GHC.Generics.C1 c r) instance Binrep.Generic.Put.GPut GHC.Generics.U1 instance Binrep.Put.Put c => Binrep.Generic.Put.GPut (GHC.Generics.K1 i c) instance forall k (l :: k -> *) (r :: k -> *). (Binrep.Generic.Put.GPut l, Binrep.Generic.Put.GPut r) => Binrep.Generic.Put.GPut (l GHC.Generics.:*: r) instance (TypeError ...) => Binrep.Generic.Put.GPut GHC.Generics.V1 instance forall k (f :: k -> *) i (d :: GHC.Generics.Meta). Binrep.Generic.Put.GPut f => Binrep.Generic.Put.GPut (GHC.Generics.M1 i d f) module Binrep.Generic.Get getGeneric :: (Generic a, GGetD (Rep a), Get w) => Cfg w -> Getter a class GGetD f ggetD :: (GGetD f, Get w) => Cfg w -> Getter (f a) class GGetC f ggetC :: (GGetC f, Get w) => Cfg w -> String -> Getter (f a) class GGetS f ggetS :: (GGetS f, Get w) => Cfg w -> String -> String -> Natural -> Getter (Natural, f a) -- | TODO: Want to return an Either [(String, Text)] indicating -- the constructors and their expected tags tested, but needs fiddling -- (can't use Alternative). Pretty minor, but Aeson does it and -- it's nice. class GGetCSum f ggetCSum :: (GGetCSum f, Get w) => Cfg w -> String -> w -> Maybe (Getter (f a)) instance forall k (l :: k -> *) (r :: k -> *). Binrep.Generic.Get.GGetCSum (l GHC.Generics.:+: r) => Binrep.Generic.Get.GGetC (l GHC.Generics.:+: r) instance forall k (l :: k -> *) (r :: k -> *). (Binrep.Generic.Get.GGetCSum l, Binrep.Generic.Get.GGetCSum r) => Binrep.Generic.Get.GGetCSum (l GHC.Generics.:+: r) instance forall k (f :: k -> *) (c :: GHC.Generics.Meta). (Binrep.Generic.Get.GGetS f, GHC.Generics.Constructor c) => Binrep.Generic.Get.GGetCSum (GHC.Generics.C1 c f) instance forall k (f :: k -> *) (c :: GHC.Generics.Meta). (Binrep.Generic.Get.GGetS f, GHC.Generics.Constructor c) => Binrep.Generic.Get.GGetC (GHC.Generics.C1 c f) instance Binrep.Generic.Get.GGetS GHC.Generics.U1 instance forall k (l :: k -> *) (r :: k -> *). (Binrep.Generic.Get.GGetS l, Binrep.Generic.Get.GGetS r) => Binrep.Generic.Get.GGetS (l GHC.Generics.:*: r) instance (Binrep.Get.Get a, GHC.Generics.Selector s) => Binrep.Generic.Get.GGetS (GHC.Generics.S1 s (GHC.Generics.Rec0 a)) instance forall k (f :: k -> *) (d :: GHC.Generics.Meta). (Binrep.Generic.Get.GGetC f, GHC.Generics.Datatype d) => Binrep.Generic.Get.GGetD (GHC.Generics.D1 d f) instance (TypeError ...) => Binrep.Generic.Get.GGetC GHC.Generics.V1 module Binrep.Generic.BLen blenGeneric :: (Generic a, GBLen (Rep a), BLen w) => Cfg w -> a -> BLenT class GBLen f gblen :: (GBLen f, BLen w) => Cfg w -> f p -> BLenT class GBLenSum f gblensum :: (GBLenSum f, BLen w) => Cfg w -> f p -> BLenT instance forall k (l :: k -> *) (r :: k -> *). Binrep.Generic.BLen.GBLenSum (l GHC.Generics.:+: r) => Binrep.Generic.BLen.GBLen (l GHC.Generics.:+: r) instance forall k (l :: k -> *) (r :: k -> *). (Binrep.Generic.BLen.GBLenSum l, Binrep.Generic.BLen.GBLenSum r) => Binrep.Generic.BLen.GBLenSum (l GHC.Generics.:+: r) instance forall k (f :: k -> *) (c :: GHC.Generics.Meta). (Binrep.Generic.BLen.GBLen f, GHC.Generics.Constructor c) => Binrep.Generic.BLen.GBLenSum (GHC.Generics.C1 c f) instance Binrep.Generic.BLen.GBLen GHC.Generics.U1 instance Binrep.BLen.BLen c => Binrep.Generic.BLen.GBLen (GHC.Generics.K1 i c) instance forall k (l :: k -> *) (r :: k -> *). (Binrep.Generic.BLen.GBLen l, Binrep.Generic.BLen.GBLen r) => Binrep.Generic.BLen.GBLen (l GHC.Generics.:*: r) instance (TypeError ...) => Binrep.Generic.BLen.GBLen GHC.Generics.V1 instance forall k (f :: k -> *) i (d :: GHC.Generics.Meta). Binrep.Generic.BLen.GBLen f => Binrep.Generic.BLen.GBLen (GHC.Generics.M1 i d f) -- | Derive BLen, Put, Get and CBLen -- instances generically. module Binrep.Generic data Cfg a Cfg :: (String -> a) -> (a -> a -> Bool) -> (a -> Text) -> Cfg a -- | How to turn a constructor name into a byte tag. [cSumTag] :: Cfg a -> String -> a [cSumTagEq] :: Cfg a -> a -> a -> Bool [cSumTagShow] :: Cfg a -> a -> Text cfg :: (Eq a, Show a) => (String -> a) -> Cfg a -- | Obtain the tag for a sum type value by applying a function to the -- constructor name, and reading the result as a hexadecimal number. cSumTagHex :: forall a. Integral a => (String -> String) -> String -> a -- | Obtain the tag for a sum type value using the constructor name -- directly (with a null terminator). -- -- This is probably not what you want in a binary representation, but -- it's safe and may be useful for debugging. -- -- The refine force is safe under the assumption that Haskell constructor -- names are UTF-8 with no null bytes allowed. I haven't confirmed that, -- but I'm fairly certain. cSumTagNullTerm :: String -> AsByteString 'C -- | Default generic derivation configuration, using -- cSumTagNullTerm. cDef :: Cfg (AsByteString 'C) -- | Special generic derivation configuration you may use for non-sum data -- types. -- -- When generically deriving binrep instances for a non-sum type, you may -- like to ignore sum tag handling. You could use cDef, but this -- will silently change behaviour if your type becomes a sum type. This -- configuration will generate clear runtime errors when used with a sum -- type. -- -- By selecting Void for the sum tag type, consumption actions -- (serializing, getting length in bytes) will runtime error, while -- generation actions (parsing) will hit the Void instance first -- and always safely error out. cNoSum :: Cfg Void data EDerivedSumInstanceWithNonSumCfg EDerivedSumInstanceWithNonSumCfg :: EDerivedSumInstanceWithNonSumCfg blenGeneric :: (Generic a, GBLen (Rep a), BLen w) => Cfg w -> a -> BLenT putGeneric :: (Generic a, GPut (Rep a), Put w) => Cfg w -> a -> Builder getGeneric :: (Generic a, GGetD (Rep a), Get w) => Cfg w -> Getter a type CBLenGeneric w a = GCBLen w (Rep a) instance GHC.Show.Show Binrep.Generic.EDerivedSumInstanceWithNonSumCfg instance GHC.Exception.Type.Exception Binrep.Generic.EDerivedSumInstanceWithNonSumCfg module Binrep.Example.Wav type End = 'LE type W32 = I 'U 'I4 End type W16 = I 'U 'I2 End data WavHeader WavHeader :: Magic "RIFF" -> W32 -> Magic "WAVE" -> Magic "fmt " -> W16 -> W16 -> WavHeader [wavHeaderMagic] :: WavHeader -> Magic "RIFF" [wavHeaderChunkSize] :: WavHeader -> W32 [wavHeaderFmt] :: WavHeader -> Magic "WAVE" [wavHeaderFmtChunkMarker] :: WavHeader -> Magic "fmt " [wavHeaderFmtType] :: WavHeader -> W16 [wavHeaderChannels] :: WavHeader -> W16 instance GHC.Classes.Eq Binrep.Example.Wav.WavHeader instance GHC.Show.Show Binrep.Example.Wav.WavHeader instance Data.Data.Data Binrep.Example.Wav.WavHeader instance GHC.Generics.Generic Binrep.Example.Wav.WavHeader instance Binrep.BLen.BLen Binrep.Example.Wav.WavHeader instance Binrep.Put.Put Binrep.Example.Wav.WavHeader instance Binrep.Get.Get Binrep.Example.Wav.WavHeader module Binrep.Example.Tiff type W8 = I 'U 'I1 'LE data Tiff [Tiff] :: (Put (I 'U 'I4 end), bs ~ MagicBytes (TiffMagic end), ReifyBytes bs, KnownNat (Length bs)) => TiffBody end -> Tiff data TiffBody (end :: Endianness) TiffBody :: Magic (TiffMagic end) -> I 'U 'I4 end -> TiffBody (end :: Endianness) [tiffBodyMagic] :: TiffBody (end :: Endianness) -> Magic (TiffMagic end) [tiffBodyExInt] :: TiffBody (end :: Endianness) -> I 'U 'I4 end type family TiffMagic (end :: Endianness) :: Symbol tiffLEbs :: ByteString tiffBEbs :: ByteString instance GHC.Classes.Eq (Binrep.Example.Tiff.TiffBody end) instance GHC.Show.Show (Binrep.Example.Tiff.TiffBody end) instance GHC.Generics.Generic (Binrep.Example.Tiff.TiffBody end) instance (GHC.TypeLits.KnownSymbol (Binrep.Example.Tiff.TiffMagic end), Data.Typeable.Internal.Typeable end) => Data.Data.Data (Binrep.Example.Tiff.TiffBody end) instance GHC.Show.Show Binrep.Example.Tiff.Tiff instance Binrep.BLen.BLen Binrep.Example.Tiff.Tiff instance Binrep.Put.Put Binrep.Example.Tiff.Tiff instance Binrep.Get.Get Binrep.Example.Tiff.Tiff instance (bs GHC.Types.~ Binrep.Type.Magic.MagicBytes (Binrep.Example.Tiff.TiffMagic end), GHC.TypeNats.KnownNat (Binrep.Type.Byte.Length bs)) => Binrep.BLen.BLen (Binrep.Example.Tiff.TiffBody end) instance (bs GHC.Types.~ Binrep.Type.Magic.MagicBytes (Binrep.Example.Tiff.TiffMagic end), Binrep.Type.Byte.ReifyBytes bs, irep GHC.Types.~ Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I4 end, Binrep.Put.Put irep) => Binrep.Put.Put (Binrep.Example.Tiff.TiffBody end) instance (bs GHC.Types.~ Binrep.Type.Magic.MagicBytes (Binrep.Example.Tiff.TiffMagic end), Binrep.Type.Byte.ReifyBytes bs, irep GHC.Types.~ Binrep.Type.Int.I 'Binrep.Type.Int.U 'Binrep.Type.Int.I4 end, Binrep.Get.Get irep) => Binrep.Get.Get (Binrep.Example.Tiff.TiffBody end) module Binrep.Example.Tar type BS = ByteString -- | The naturals in tars are sized octal ASCII digit strings that end with -- a null byte (and may start with leading ASCII zeroes). The size -- includes the terminating null, so you get n-1 digits. What a -- farce. -- -- Don't use this constructor directly! The size must be checked to -- ensure it fits. newtype TarNat n TarNat :: AsciiNat 8 -> TarNat n [getTarNat] :: TarNat n -> AsciiNat 8 data Tar Tar :: NullPadded 100 BS -> TarNat 8 -> TarNat 8 -> TarNat 8 -> TarNat 12 -> TarNat 12 -> Tar [tarFileName] :: Tar -> NullPadded 100 BS [tarFileMode] :: Tar -> TarNat 8 [tarFileUIDOwner] :: Tar -> TarNat 8 [tarFileUIDGroup] :: Tar -> TarNat 8 [tarFileFileSize] :: Tar -> TarNat 12 [tarFileLastMod] :: Tar -> TarNat 12 instance forall k (n :: k). GHC.Classes.Eq (Binrep.Example.Tar.TarNat n) instance forall k (n :: k). GHC.Show.Show (Binrep.Example.Tar.TarNat n) instance forall k (n :: k). GHC.Generics.Generic (Binrep.Example.Tar.TarNat n) instance GHC.Classes.Eq Binrep.Example.Tar.Tar instance GHC.Show.Show Binrep.Example.Tar.Tar instance GHC.Generics.Generic Binrep.Example.Tar.Tar instance Binrep.BLen.BLen Binrep.Example.Tar.Tar instance Binrep.Put.Put Binrep.Example.Tar.Tar instance Binrep.Get.Get Binrep.Example.Tar.Tar instance GHC.TypeNats.KnownNat n => Binrep.BLen.BLen (Binrep.Example.Tar.TarNat n) instance GHC.TypeNats.KnownNat n => Binrep.Put.Put (Binrep.Example.Tar.TarNat n) instance GHC.TypeNats.KnownNat n => Binrep.Get.Get (Binrep.Example.Tar.TarNat n) module Binrep.Example data DV data DU DU :: DU data DSS DSS :: I 'U 'I1 'LE -> I 'U 'I2 'LE -> I 'U 'I4 'LE -> I 'U 'I8 'LE -> I 'U 'I1 'LE -> DSS [dss1] :: DSS -> I 'U 'I1 'LE [dss2] :: DSS -> I 'U 'I2 'LE [dss3] :: DSS -> I 'U 'I4 'LE [dss4] :: DSS -> I 'U 'I8 'LE [dss5] :: DSS -> I 'U 'I1 'LE data DCS DCS1 :: DCS DCS2 :: DCS DCS3 :: DCS DCS4 :: DCS DCS5 :: DCS type BrSumDCS = I 'U 'I1 'LE brCfgDCS :: Cfg BrSumDCS data DX DX :: DU -> DX instance Data.Data.Data Binrep.Example.DV instance GHC.Generics.Generic Binrep.Example.DV instance GHC.Classes.Eq Binrep.Example.DU instance GHC.Show.Show Binrep.Example.DU instance Data.Data.Data Binrep.Example.DU instance GHC.Generics.Generic Binrep.Example.DU instance GHC.Classes.Eq Binrep.Example.DSS instance GHC.Show.Show Binrep.Example.DSS instance Data.Data.Data Binrep.Example.DSS instance GHC.Generics.Generic Binrep.Example.DSS instance GHC.Classes.Eq Binrep.Example.DCS instance GHC.Show.Show Binrep.Example.DCS instance Data.Data.Data Binrep.Example.DCS instance GHC.Generics.Generic Binrep.Example.DCS instance GHC.Classes.Eq Binrep.Example.DX instance GHC.Show.Show Binrep.Example.DX instance Data.Data.Data Binrep.Example.DX instance GHC.Generics.Generic Binrep.Example.DX instance Binrep.BLen.BLen Binrep.Example.DX instance Binrep.Put.Put Binrep.Example.DX instance Binrep.Get.Get Binrep.Example.DX instance Binrep.BLen.BLen Binrep.Example.DCS instance Binrep.Put.Put Binrep.Example.DCS instance Binrep.Get.Get Binrep.Example.DCS instance Binrep.BLen.BLen Binrep.Example.DSS instance Binrep.Put.Put Binrep.Example.DSS instance Binrep.Get.Get Binrep.Example.DSS instance Binrep.BLen.BLen Binrep.Example.DU instance Binrep.Put.Put Binrep.Example.DU instance Binrep.Get.Get Binrep.Example.DU