protodef
Version:
A simple yet powerful way to define binary protocols
293 lines (214 loc) • 6.86 kB
Markdown
# Datatypes
Protodef has a number of useful default datatypes.
## Conditional
### switch
switch make it possible to choose a datatype depending on the value of an other field.
It is similar to the switch/case syntax.
It takes 3 arguments:
* compareTo : the value is the other field
* compareToValue : an optional property (it's either compareTo or compareToValue) that allows the comparison to be made with a value instead of an other field
* fields : an object mapping the values to the types
* default : an optional property saying the type taken if the value doesn't fit into the cases
Example:
A switch which can encode a byte, a varint, a float or a string depending on "someField".
If the value of someField is different, then the value encoded is of type void.
```json
[
"switch",
{
"compareTo": "someField",
"fields": {
"0": "i8",
"1": "varint",
"2": "f32",
"3": "string"
},
"default": "void"
}
]
```
Example of value: `4.5`
### option
option represents a simple optional type. It's encoded as a boolean indicating whether the value is there or not.
It's similar to the Optional type in java or Maybe in haskell.
It takes only one argument : the type of the value.
Example:
An option of value string
```json
[
"option",
"string"
]
```
Example of value: `"my string"`
## Numeric
These datatypes don't take any arguments. They represent numbers.
| Name | Size in bytes | Example of value | Also called |
| --- | --- | --- | --- |
| i8 | 1 | -125 | byte |
| u8 | 1 | 255 | unsigned byte |
| i16 | 2 | -32000 | short |
| u16 | 2 | 60000 | unsigned short |
| i32 | 4 | -2000000000 | int |
| u32 | 4 | 3000000000 | unsigned int |
| f32 | 4 | 4.5 | float |
| f64 | 8 | 4.5 | double |
| i64 | 8 | 1 | long |
| u64 | 8 | 1 | unsigned long |
| li8 | 1 | -125 | little endian byte |
| lu8 | 1 | 255 | little endian unsigned byte |
| li16 | 2 | -32000 | little endian short |
| lu16 | 2 | 60000 | little endian unsigned short |
| li32 | 4 | -2000000000 | little endian int |
| lu32 | 4 | 3000000000 | little endian unsigned int |
| lf32 | 4 | 4.5 | little endian float |
| lf64 | 8 | 4.5 | little endian double |
| li64 | 8 | 1 | little endian long |
| lu64 | 8 | 1 | little endian unsigned long |
## Structures
### array
array represents a list of values.
It takes for arguments:
* type : the type of the element
* countType : the type of the length prefix
* count : optional (either count or countType), a reference to the field counting the elements, or a fixed size (an integer)
See [Counting](#counting)
Example:
An array of int prefixed by a short length.
```json
[
"array",
{
"countType": "i16",
"type": "i32"
}
]
```
Example of value: `[1,2,3,4]`
### count
It represents a count field for an array or a buffer.
Example:
A count for a field name records, of type short.
```json
[
"count",
{
"type": "i16",
"countFor": "records"
}
]
```
Example of value: `5`
### container
It represents a list of named values. It takes for argument these values with their types and names.
Example:
A container with fields of type int, int, ushort and ushort.
```json
[
"container",
[
{
"name": "x",
"type": "i32"
},
{
"name": "z",
"type": "i32"
},
{
"name": "bitMap",
"type": "u16"
},
{
"name": "addBitMap",
"type": "u16"
}
]
]
```
Example of value: `{"x":10,"z":10,"bitMap":10,"addBitMap":10}`
## Utils
### varint
A variable-length number representation.
Size: between 1 and 5
Example of value : `5`
### bool
A boolean, encoded in one byte.
Example of value : `true`
### pstring
A length prefixed string. It takes one argument : the type of the length prefix.
It is usually used to define a "string" type that can be used without argument.
The count can also be defined in different ways, see [Counting](#counting).
Example:
A string length prefixed by a varint.
```json
[
"pstring",{
"countType":"varint"
}
]
```
Example of value: `"my string"`
### buffer
buffer represents a Buffer
It takes for arguments:
* countType : the type of the length prefix
* count : optional (either count or countType), a reference to the field counting the elements, or a fixed size (an integer)
See [Counting](#counting)
Example:
An buffer prefixed by a varint length.
```json
[
"buffer",
{
"countType": "varint"
}
]
```
Example of value: `new Buffer([0x01,0x02,0x03])`
### void
void represents an empty value. It has a size of 0.
Example of value: `undefined`
### bitfield
bitfield represents a list of value with sizes that are not a multiple of 8bits.
It takes for argument a list of values with:
* a size
* a name
* signed
The sum of the sizes must be a multiple of 8.
Example:
3 values, x, y and z with sizes in bits : 26, 12, 26. Notice that 26+12+26=64.
```json
["bitfield", [
{ "name": "x", "size": 26, "signed": true },
{ "name": "y", "size": 12, "signed": true },
{ "name": "z", "size": 26, "signed": true }
]]
```
Example of value: `{"x":10,"y":10,"z":10}`
### cstring
cstring represents a null terminated string. Similar to strings in C.
Example of value: "my string"
### mapper
mappers maps values. It takes as argument the type of the input, and a mappings object with the values to map.
Example:
Maps a byte to a string, 1 to "byte", 2 to "short", 3 to "int", 4 to "long".
```json
[
"mapper",
{
"type": "i8",
"mappings": {
"1": "byte",
"2": "short",
"3": "int",
"4": "long"
}
}
]
```
Example of value: `3`
# Common datatypes arguments
## Counting
* countType : the type of the length prefix
* count : optional (either count or countType), a reference to the field counting the elements, or a fixed size (an integer)