BBFL is a loosely-defined language for describing the content of binary files. The intention is to be unambiguous enough for a human to understand how a file is structured.
This document uses the following units:
- bit: A unit of information; 0 or 1.
- byte: The smallest addressable unit of information. usually defined as 8 bits.
- word: The natural unit of information for a processor. Usually defined as 32 or 64 bits.
A name is a sequence of letters, digits, and underscores, that does not begin with a digit.
The language consists of a number of declarations. A declaration is a name
followed by a type. The special name main
indicates the type that is the root
of a file, or that the entire file is comprised of.
TypeA Type
TypeB Type
main Type
...
Some primitive types may have a size, represented by a decimal integer appended to the type's name, indicating the number of bits.
name // Some default number of bits
name8 // 8 bits
name32 // 32 bits
A boolean type is indicated by the bool
literal. The type may have an optional
size. The default size is 8 bits.
Boolean bool // 8 bits
BitBool bool1 // 1 bit
An integer type is indicated by the int
literal for signed integers, and the
uint
literal for unsigned integers. The type may have an optional size. The
default size is 32 bits for both int
and uint
.
Char uint8
SignedChar int8
Short int16
UnsignedShort uint16
Int int // 32 bits
Uint uint // 32 bits
Long int32
UnsignedLong uint32
LongLong int64
UnsignedLongLong uint64
The byte type, indicated by the byte
literal, is an alias of uint8
.
A floating point type is indicated by the float
literal. The type may have an
optional size. The default size is 32 bits.
Float float32
Double float64
LongDouble float128
A fixed point type is indicated by the fixed
literal for signed values, and
the ufixed
literal for unsigned values. The literal is followed by a size of
the form m.n
, where m
is the size of the integer portion and n
is the size
of the fractional portion.
Fixed fixed8.8 // 16 bits
UnsignedFixed ufixed8.8 // 16 bits
Half fixed11.5 // 16 bits
Single fixed24.8 // 32 bits
Double fixed53.11 // 64 bits
Quad fixed113.15 // 128 bits
A fixed point number has the following properties:
Minimum value: -2^(m-1)
Maxmimum value: 2^(m-1) - 2^-n
Resolution: 2^-n
An unsigned fixed point number has the following properties:
Maxmimum value: 2^m - 2^-n
Resolution: 2^-n
A struct is an ordered collection of fields.
Name {
FieldA Type
FieldB Type
...
}
An array type is indicated by a length enclosed within brackets, followed by a type.
The length may be an integer indicating a constant size.
Within a struct, the length may be specified by a .
followed by the name of a
field within the struct, which indicates that the length is the value of the
field. Fields may be chained to specify fields within structs.
The length may be empty, indicating an array of variable length.
Array [4]byte
String {
Length uint64
Bytes [.Length]byte
}
VariableArray []Chunk
A sequence specifies a sequence of values that is terminated by specific value. It is indicated by brackets enclosing a terminator, followed by a primitive type.
NullString [!0]byte
An enum consists of a set of named values. It is indicated by the literal enum
followed by a basic type, or whose underlying type is basic. This is followed by
curly braces enclosing a number of enum items. Each item describes a possible
value of the enum.
Name enum(uint8) {
ItemA = 0
ItemB = 1
ItemC = 2
ItemD = 3
}
A type name may be followed by a list of parameters enclosed in angle brackets.
Array<T> {
Length uint32
Items [.Length]T
}
Map<K,V> {
Length uint32
Keys [.Length]K
Values [.Length]V
}
When the type is declared, the parameters are replaced by a concrete type.
ByteArray Array<byte>
ByteMap Map<byte,byte>