isobmff-0.14.0.0: A parser and generator for the ISO-14496-12/14 base media file format

Safe HaskellNone
LanguageHaskell2010

Data.Type.BitRecords.Structure

Contents

Description

NamedStructure definition for sequences of bits.

This module provides the core data types and functions for conversion of finite bit sequences from an to conventional (Haskell) data types.

Non-compressed, non-random finite bit sequences generated by programs are usually compositions of bytes and multi byte words, and a ton of Haskell libraries exist for the serialization and deserialization of ByteStrings.

This module allows the definition of a structure i.e. a very simple grammar, which allows functions in this library to read and write single bytes, words and bits.

Also complete bit sequence may be constructed or destructed from and to Haskell types.

Further more, the Record may contain dependent sub-sequences, for example to express Record that precede a length field before a repetitive block data.

Antother example for dependent sequences is fields whose presence depends on flags preceding them.

This library is also designed with zero copying in mind.

It should be emphasized that binary deserialization is not to be confused with binary destructuring. While the former usually involves copying all regular sub sequences from the input to a value of a certain type, the later merely requires to peek into the sequeuence at a certain position and deserializing a sub sequence. The starting position and the interpretation are governed by the strucuture applied to the sequence.

Synopsis

Documentation

data Structure (sizeType :: StructureSizeType) where Source #

Phantom type for structures

Instances
type PrettyStructure (Anonymous (Name name struct) :: Structure sizeType -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (Anonymous (Name name struct) :: Structure sizeType -> Type) = name <:> PrettyStructure struct
type ToPretty (struct :: Extends (Structure sizeType)) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type ToPretty (struct :: Extends (Structure sizeType)) = PrettyStructure struct
type GetStructureSize (Anonymous (Name name struct)) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (Anonymous (Name name struct)) = GetStructureSize struct
type GetStructureSize (Record (x ': xs)) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (Record ([] :: [Extends (Named (Structure FixSize))])) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type FixStructure = Structure FixSize Source #

Structures that have statically known fixed size.

type VariableStructure = Structure VarSize Source #

Structures that have no statically known fixed size.

data StructureSizeType Source #

Phantom type indicating that if a Structure has a statically known size.

Constructors

VarSize 
FixSize 

type family GetStructureSize (t :: Extends (Structure FixSize)) :: Nat Source #

The number of bits that a structure with a predetermined fixed size requires.

Instances
type GetStructureSize EmptyStructure Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (TypeStructure Bool) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (TypeStructure Int8) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (TypeStructure Word8) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (BitSequence length) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (FixSizeStringStructure size) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure.String

type GetStructureSize (Anonymous (Name name struct)) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (Anonymous (Name name struct)) = GetStructureSize struct
type GetStructureSize (Alias lhs rhs) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (LiteralStructure (Value s k1 x)) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (Record (x ': xs)) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (Record ([] :: [Extends (Named (Structure FixSize))])) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (ConditionalStructure False l r) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (ConditionalStructure True l r) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (IntegerStructure n s e) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (Padded (either literal) struct) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (Padded (either literal) struct) = PaddedStructureValidateSize literal struct (GetPaddingSize literal struct + GetStructureSize struct)

type family PrettyStructure (struct :: Extends (Structure sizeType)) :: PrettyType Source #

Support for Pretty Printing Structure Types

Instances
type PrettyStructure EmptyStructure Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (TypeStructure Bool) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (TypeStructure Int8) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (TypeStructure Word8) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (BitSequence length :: Structure FixSize -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (BitSequence length :: Structure FixSize -> Type) = WithValidBitSequenceLength length (PutStr "BitSequence " <+> PutNat length)
type PrettyStructure (FixSizeStringStructure size :: Structure FixSize -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure.String

type PrettyStructure (FixSizeStringStructure size :: Structure FixSize -> Type) = "FixSizeStringStructure" <:> (PutNat size <++> PutStr "bits")
type PrettyStructure (Anonymous (Name name struct) :: Structure sizeType -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (Anonymous (Name name struct) :: Structure sizeType -> Type) = name <:> PrettyStructure struct
type PrettyStructure (Record xs :: Structure sizeType -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (Record xs :: Structure sizeType -> Type) = "Record" <:$$--> PrettyRecord xs
type PrettyStructure (Alias lhs rhs :: Structure FixSize -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (LiteralStructure (Value s k1 x) :: Structure FixSize -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (LiteralStructure (Value s k1 x) :: Structure FixSize -> Type) = "LiteralStructure" <:> Pretty s x
type PrettyStructure (ConditionalStructure False l r :: Structure FixSize -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (ConditionalStructure True l r :: Structure FixSize -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (IntegerStructure n s e :: Structure FixSize -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (IntegerStructure n s e :: Structure FixSize -> Type) = IntegerStructureValidateLength n (((PutStr "IntegerStructure" <+> PutNat n) <+> If (s == Signed) (PutStr "Signed") (PutStr "Unsigned")) <+> If (e == BE) (PutStr "BE") (PutStr "LE"))
type PrettyStructure (Padded (either literal) struct :: Structure FixSize -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (Padded (either literal) struct :: Structure FixSize -> Type) = PrettyParens (PrettyStructure struct) <+> (("padded with" <:> PutNat (GetPaddingSize literal struct)) <+> PutStr "bits.")

data Record :: [Extends (Named (Structure sizeType))] -> Extends (Structure sizeType) Source #

A record is a list of fields, Name Structure composed of a list of other Record in natural order.

Instances
type PrettyStructure (Record xs :: Structure sizeType -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (Record xs :: Structure sizeType -> Type) = "Record" <:$$--> PrettyRecord xs
type GetStructureSize (Record (x ': xs)) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (Record ([] :: [Extends (Named (Structure FixSize))])) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type family (a :: Extends (Named (Structure sizeType))) <> (b :: k) :: Extends (Structure sizeType) where ... infixr 6 Source #

Compose Named Structures to a Record.

Equations

a <> (b :: Extends (Named (Structure sizeType))) = Record '[a, b] 
a <> (Record xs) = Record (a ': xs) 

type family PrettyRecord (xs :: [Extends (Named (Structure sizeType))]) :: PrettyType where ... Source #

Internal function to render Records

data BitSequence (length :: Nat) :: Extends (Structure FixSize) Source #

A fixed length sequence of bits.

Instances
type PrettyStructure (BitSequence length :: Structure FixSize -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (BitSequence length :: Structure FixSize -> Type) = WithValidBitSequenceLength length (PutStr "BitSequence " <+> PutNat length)
type GetStructureSize (BitSequence length) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type family WithValidBitSequenceLength (length :: Nat) (out :: k) :: k where ... Source #

Internal function to validate that a BitSequence has a valid length.

Equations

WithValidBitSequenceLength length out = If ((length <=? 64) && (1 <=? length)) out (TypeError (Text "invalid bit sequence length: " :<>: ShowType length)) 

type family (name :: Symbol) // (length :: Nat) :: Extends (Named (Structure FixSize)) where ... infixr 7 Source #

An alias to construct a Named BitSequence with the given number of bits

Equations

name // length = WithValidBitSequenceLength length (Name name (BitSequence length)) 

data LiteralStructure a :: Extends (Structure FixSize) Source #

A constant, fixed length sequence of bits, generated by a type level LiteralFamily.

Instances
type PrettyStructure (LiteralStructure (Value s k1 x) :: Structure FixSize -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (LiteralStructure (Value s k1 x) :: Structure FixSize -> Type) = "LiteralStructure" <:> Pretty s x
type GetStructureSize (LiteralStructure (Value s k1 x)) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

data Padded (literal :: Either j j) (struct :: Extends (Structure FixSize)) :: Extends (Structure FixSize) Source #

Pad a Structure to a structure with a length being a multiple of the length of the literal.

Instances
type PrettyStructure (Padded (either literal) struct :: Structure FixSize -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (Padded (either literal) struct :: Structure FixSize -> Type) = PrettyParens (PrettyStructure struct) <+> (("padded with" <:> PutNat (GetPaddingSize literal struct)) <+> PutStr "bits.")
type GetStructureSize (Padded (either literal) struct) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (Padded (either literal) struct) = PaddedStructureValidateSize literal struct (GetPaddingSize literal struct + GetStructureSize struct)

type family GetPaddingSize literal (struct :: Extends (Structure FixSize)) :: Nat where ... Source #

Type function calculating the number of padding bits requred to pad struct to a multiple of literal size.

Equations

GetPaddingSize (Value s k (x :: k)) y = (SizeOf s x - (GetStructureSize y `Mod` SizeOf s x)) `Mod` SizeOf s x 

type family PaddedStructureValidateSize literal (rhs :: Extends (Structure FixSize)) (out :: k) :: k where ... Source #

Type function to validate that both arguments to Alias have a valid length. The lengths are valid iff the right hand side requires the same amount of bits as the left hand side. If necessary, one can always pad the right hand side to match the left hand side using Padded.

Equations

PaddedStructureValidateSize (Value s k (x :: k)) rhs out = If (SizeOf s x == 0) (TypeError (((Text "Cannot use a literal of size 0: " :<>: ShowType (Value s k (x :: k))) :<>: Text " to pad the structure: ") :<>: ShowType rhs)) out 

data Alias :: Extends (Structure FixSize) -> Extends (Structure FixSize) -> Extends (Structure FixSize) Source #

Alias structures, the size of the an alias structure is equal to the size of both elements.

Instances
type PrettyStructure (Alias lhs rhs :: Structure FixSize -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type GetStructureSize (Alias lhs rhs) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type family AliasStructureValidateSize (lhs :: Extends (Structure FixSize)) (rhs :: Extends (Structure FixSize)) (out :: k) :: k where ... Source #

Internal function to validate that both arguments to Alias have a valid length. The lengths are valid iff the right hand side requires the same amount of bits as the left hand side. If necessary, one can always pad the right hand side to match the left hand side using Padded.

Equations

AliasStructureValidateSize lhs rhs out = If (GetStructureSize rhs == GetStructureSize lhs) out (TypeError ((((((((Text "Cannot alias structures of different size " :<>: ShowType rhs) :<>: Text " requires ") :<>: ShowType (GetStructureSize rhs)) :<>: Text " bits, but ") :<>: ShowType lhs) :<>: Text " requires ") :<>: ShowType (GetStructureSize lhs)) :<>: Text " bits.")) 

Integer Sequences

type U8 = TypeStructure Word8 Source #

An usigned 8-bit integer

type S8 = TypeStructure Int8 Source #

A signed 8-bit integer

type FlagStructure = TypeStructure Bool Source #

A single bit structure

data IntegerStructure :: Nat -> Sign -> Endianess -> Extends (Structure FixSize) where Source #

(Structure 'FixSize) holding integral numbers

Instances
type PrettyStructure (IntegerStructure n s e :: Structure FixSize -> Type) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

type PrettyStructure (IntegerStructure n s e :: Structure FixSize -> Type) = IntegerStructureValidateLength n (((PutStr "IntegerStructure" <+> PutNat n) <+> If (s == Signed) (PutStr "Signed") (PutStr "Unsigned")) <+> If (e == BE) (PutStr "BE") (PutStr "LE"))
type GetStructureSize (IntegerStructure n s e) Source # 
Instance details

Defined in Data.Type.BitRecords.Structure

data Endianess Source #

Endianess of an IntegerStructure

Constructors

LE 
BE 

data Sign Source #

Integer sign of an IntegerStructure

Constructors

Signed 
Unsigned 

type family IntegerStructureValidateLength (n :: Nat) (out :: k) where ... Source #

Internal function to ensure that the length of an IntegerStructure is 16,32 or 64

Equations

IntegerStructureValidateLength n out = If (n == 16) out (If (n == 32) out (If (n == 64) out (TypeError (Text "Invalid IntegerStructure size: " :<>: ShowType n)))) 

type U n e = IntegerStructure n Unsigned e Source #

An unsigned integer structure

Structure PrettyType Printing

showStructure :: forall proxy (struct :: Extends (Structure FixSize)). PrettyTypeShow (PrettyStructure struct) => proxy struct -> String Source #

Render struct to a pretty, human readable form. Internally this is a wrapper around ptShow using PrettyStructure.

data BoolProxy (t :: Bool) where Source #

Internal type used for unit tests

_typeSpecGetStructureSize :: BoolProxy (testBool :: Bool) -> Expect [GetStructureSize U8 `ShouldBe` 8, GetStructureSize EmptyStructure `ShouldBe` 0, GetStructureSize (Record [Name "x" U8, Name "y" U8]) `ShouldBe` 16, GetStructureSize (S 16 BE) `ShouldBe` 16, GetStructureSize (ConditionalStructure testBool (U 32 LE) S8) `ShouldBe` If testBool 32 8, GetStructureSize (("field 1" // 3) <> (("field 2" // 2) <> (("field 3" // 5) <> Name "field 4" (("field 4.1" // 3) <> ("field 4.2" // 6))))) `ShouldBe` 19, GetStructureSize (Alias (BitSequence 4) (LiteralStructure (Bits '[1, 0, 0, 1]))) `ShouldBe` 4, GetStructureSize (Padded (Left (Bits '[1, 0, 1, 0, 1, 0, 1, 0])) (("x" // 1) <> ("y" // 2))) `ShouldBe` 8, GetStructureSize (Padded (Right (Bits '[1, 0, 1, 0, 1, 0, 1, 0])) (Anonymous ("x" // 9))) `ShouldBe` 16, GetStructureSize (Padded (Left (Bits '[1, 0, 1, 0, 1, 0, 1, 0])) (Anonymous ("x" // 22))) `ShouldBe` 24, GetStructureSize (Padded (Right (Bits '[1, 0, 1, 0, 1, 0, 1, 0])) (Anonymous ("x" // 33))) `ShouldBe` 40, GetStructureSize (Padded (Right (To (Sequence Word8 Nat) '[0, 255, 0, 255])) (Anonymous ("x" // 10))) `ShouldBe` 32] Source #