2019-07-09 21:55:08 +10:00
|
|
|
# Binary Data Format
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2019-07-09 22:02:35 +10:00
|
|
|
### Links
|
|
|
|
|
2019-07-09 22:05:34 +10:00
|
|
|
- <a href="#overview">Overview</a>
|
2020-07-22 15:27:04 +10:00
|
|
|
- <a href="#languages">Languages</a>
|
2019-07-09 22:08:22 +10:00
|
|
|
- <a href="#data-types">Data types</a>
|
2019-07-09 22:07:02 +10:00
|
|
|
- <a href="#creating-an-object">Creating an object</a>
|
|
|
|
- <a href="#arrays">Arrays</a>
|
|
|
|
- <a href="#named-lists">Named lists</a>
|
2020-09-09 14:02:38 +10:00
|
|
|
- <a href="#human-readable-representation">Human readable representation</a>
|
|
|
|
- <a href="#special-notes">Special notes</a>
|
2019-07-09 22:02:35 +10:00
|
|
|
|
|
|
|
### Overview
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-09-09 14:02:38 +10:00
|
|
|
Binary Data Format (BDF) is a statically typed data representation
|
|
|
|
format. It was made to be free, fast, compact, and seamlessly
|
|
|
|
convertable between its human readable and binary representations.
|
2020-07-22 15:27:04 +10:00
|
|
|
|
|
|
|
### Languages
|
|
|
|
|
|
|
|
- <a href="https://github.com/jsrobson10/BdfCpp">C++</a>
|
2020-09-09 14:02:38 +10:00
|
|
|
- Java
|
2020-07-22 15:27:04 +10:00
|
|
|
|
2019-07-09 22:07:51 +10:00
|
|
|
### Data types
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
- Undefined
|
2019-07-09 21:53:05 +10:00
|
|
|
- Boolean
|
|
|
|
- Integer
|
|
|
|
- Long
|
|
|
|
- Short
|
|
|
|
- Byte
|
|
|
|
- Double
|
|
|
|
- Float
|
2020-08-17 22:54:22 +10:00
|
|
|
- Boolean Array
|
|
|
|
- Integer Array
|
|
|
|
- Long Array
|
|
|
|
- Short Array
|
|
|
|
- Byte Array
|
|
|
|
- Double Array
|
|
|
|
- Float Array
|
2019-07-09 21:53:05 +10:00
|
|
|
- String
|
|
|
|
- Array
|
|
|
|
- Named List
|
|
|
|
|
2019-07-09 21:55:08 +10:00
|
|
|
### Creating an object
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
You will need to generate a BdfObject to serialize anything,
|
|
|
|
this can be done by first generating a BdfReader, or generating
|
|
|
|
a new object via an existing BdfObject.
|
2019-07-09 21:53:05 +10:00
|
|
|
|
|
|
|
```java
|
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
// Create a reader object
|
|
|
|
BdfReader reader = new BdfReader();
|
|
|
|
|
|
|
|
// Get the BdfObject instance
|
|
|
|
BdfObject bdf = reader.getObject();
|
|
|
|
|
|
|
|
// Generate another BdfObject instance
|
|
|
|
BdfObject bdf_new = bdf.newObject();
|
2019-07-09 21:53:05 +10:00
|
|
|
|
|
|
|
// Get an integer
|
|
|
|
int v = bdf.getInteger();
|
|
|
|
|
|
|
|
// Set an integer
|
|
|
|
bdf.setInteger(5);
|
|
|
|
|
2020-09-09 14:02:38 +10:00
|
|
|
// Set an integer with an automatic type
|
|
|
|
bdf.setAutoInt(53);
|
|
|
|
|
|
|
|
// Set a primitive array of ints
|
|
|
|
int intArray[] = {3, 4, 5, 6};
|
|
|
|
bdf.setIntegerArray(intArray);
|
|
|
|
|
|
|
|
// Get a byte array
|
|
|
|
byte[] byteArray = bdf.getByteArray();
|
2020-08-17 22:54:22 +10:00
|
|
|
|
2019-07-09 21:53:05 +10:00
|
|
|
// Get the type of variable of the object
|
|
|
|
int type = bdf.getType();
|
|
|
|
|
|
|
|
// Compare the type with a type from BdfTypes
|
|
|
|
if(type == BdfTypes.INTEGER)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Serialize the BDF object
|
2020-09-09 14:02:38 +10:00
|
|
|
byte[] data = bdf->serialize(&data, &data_size);
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-09-09 14:02:38 +10:00
|
|
|
// Load another reader object from the serialized bytes
|
|
|
|
BdfReader reader2 = new BdfReader(data);
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-09-09 14:02:38 +10:00
|
|
|
/*
|
|
|
|
A reader object can be serialized to the human readable
|
|
|
|
representation as a string or sent over a stream
|
|
|
|
*/
|
|
|
|
reader2.serializeHumanReadable(System.out, new BdfIndent("\t", "\n"));
|
|
|
|
String data_hr = reader2.serializeHumanReadable(new BdfIndent("\t", "\n"));
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-09-09 14:02:38 +10:00
|
|
|
// A reader object can be loaded from a human readable object
|
|
|
|
BdfReader reader3 = new BdfReaderHuman(data_hr);
|
2019-07-09 21:53:05 +10:00
|
|
|
|
|
|
|
```
|
|
|
|
|
2019-07-09 21:55:08 +10:00
|
|
|
### Arrays
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-09-09 14:02:38 +10:00
|
|
|
Arrays can be used to store chunks of information, they hold instances of
|
|
|
|
BdfObject. Arrays can also be iterated over just like any other array.
|
2019-07-09 21:53:05 +10:00
|
|
|
|
|
|
|
```java
|
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
BdfReader reader = new BdfReader();
|
|
|
|
BdfObject bdf = reader.getObject();
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
// Can be created from a bdf object
|
|
|
|
BdfArray array = bdf.newArray();
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
// Get the length of an array
|
2019-07-09 21:53:05 +10:00
|
|
|
int size = array.size();
|
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
// Remove any index from an array
|
|
|
|
array.remove(3);
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
// Set an object to an index of an array
|
|
|
|
array.set(4, bdf.newObject().setString("A String"));
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
// Add an object to an array
|
2020-09-09 14:02:38 +10:00
|
|
|
array.add(bdf.newObject().setByte((byte)53));
|
2019-07-09 21:53:05 +10:00
|
|
|
|
|
|
|
// Set the array to the bdf object
|
|
|
|
bdf.setArray(array);
|
|
|
|
|
|
|
|
```
|
|
|
|
|
2019-07-09 22:07:02 +10:00
|
|
|
### Named lists
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
Named lists can be used to store data under ids/strings
|
2019-07-09 21:53:05 +10:00
|
|
|
to be used like variables in a program. A named list
|
2020-08-17 22:54:22 +10:00
|
|
|
can be created similar to an array.
|
2019-07-09 21:53:05 +10:00
|
|
|
|
|
|
|
```java
|
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
BdfReader reader = new BdfReader();
|
2020-09-09 14:02:38 +10:00
|
|
|
BdfObject bdf = reader.getObject();
|
2020-08-17 22:54:22 +10:00
|
|
|
|
|
|
|
// New named list
|
2020-09-09 14:02:38 +10:00
|
|
|
BdfNamedList list = bdf.newNamedList();
|
2020-08-17 22:54:22 +10:00
|
|
|
|
|
|
|
// Set an element to the named list
|
2020-09-09 14:02:38 +10:00
|
|
|
list.set("key1", bdf.newObject().setInteger(5));
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
// Use ids instead of strings for optimisation
|
|
|
|
// if set/get is being called multiple times
|
|
|
|
// on the same key.
|
|
|
|
|
2020-09-09 14:02:38 +10:00
|
|
|
int key2 = bdf.getKeyLocation("key2");
|
|
|
|
list.set(key2, bdf.newObject().setFloat(42.0F));
|
2019-07-09 21:53:05 +10:00
|
|
|
|
|
|
|
// Get an elements value
|
|
|
|
int v = list.get("key1").getInteger();
|
|
|
|
|
|
|
|
// Check if an element exists
|
2020-09-09 14:02:38 +10:00
|
|
|
bool has_key = list.contains("key1");
|
2019-07-09 21:53:05 +10:00
|
|
|
|
|
|
|
// Get the lists keys
|
2020-08-17 22:54:22 +10:00
|
|
|
int[] keys = list.getKeys();
|
2019-07-09 21:53:05 +10:00
|
|
|
|
|
|
|
// Iterate over the lists keys
|
2020-08-17 22:54:22 +10:00
|
|
|
for(int key : keys)
|
2019-07-09 21:53:05 +10:00
|
|
|
{
|
2020-08-17 22:54:22 +10:00
|
|
|
// Get the keys name
|
2020-09-09 14:02:38 +10:00
|
|
|
String key_name = bdf.getKeyName(key);
|
2019-07-09 21:53:05 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
|
2020-09-09 14:02:38 +10:00
|
|
|
### Human readable representation
|
2020-07-22 15:48:08 +10:00
|
|
|
|
2020-09-09 14:02:38 +10:00
|
|
|
A big part of binary data format is the human readable
|
|
|
|
representation. It has a JSON-like syntax.
|
|
|
|
This can be used with config files and to modify/view
|
|
|
|
binaries. A big advantage to using the human readable
|
|
|
|
representation in configuration files is its support
|
|
|
|
for comments.
|
2020-07-22 15:48:08 +10:00
|
|
|
|
2020-09-09 14:02:38 +10:00
|
|
|
```hbdf
|
2020-08-17 22:54:22 +10:00
|
|
|
|
2020-09-09 14:02:38 +10:00
|
|
|
/*
|
|
|
|
A Named List is represented
|
|
|
|
by an opening tag and a closing
|
|
|
|
tag { }
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
A key value pair can be stored
|
|
|
|
within a Named List with a string
|
|
|
|
property
|
|
|
|
*/
|
|
|
|
"hello": "world",
|
|
|
|
|
|
|
|
/*
|
|
|
|
Integers can be stored here too.
|
|
|
|
They have a character at the end
|
|
|
|
to say what type they are.
|
|
|
|
|
|
|
|
The tag at the end can be:
|
|
|
|
- I: Integer - a value between -2^31 and 2^31 - 1
|
|
|
|
- S: Short - a value between -32768 and 32767
|
|
|
|
- L: Long - a value between -2^63 and 2^63 - 1
|
|
|
|
- B: Byte - a value between -128 and 127
|
|
|
|
- D: Double - has 15 decimal digits of precision
|
|
|
|
- F: Float - has 7 decimal digits of precision
|
|
|
|
*/
|
|
|
|
"number": 42I,
|
|
|
|
"byte": -23B,
|
|
|
|
"decimal": 73.5D,
|
|
|
|
|
|
|
|
/*
|
|
|
|
This is a boolean. It can
|
|
|
|
be true or false.
|
|
|
|
*/
|
|
|
|
"boolTest": false,
|
|
|
|
|
|
|
|
/*
|
|
|
|
Primitive arrays are represented
|
|
|
|
by a type, an opening tag, and a
|
|
|
|
closing tag. They are like an array
|
|
|
|
but they contain only 1 data type.
|
|
|
|
|
|
|
|
The tag at the start can be:
|
|
|
|
- int
|
|
|
|
- short
|
|
|
|
- long
|
|
|
|
- byte
|
|
|
|
- double
|
|
|
|
- float
|
|
|
|
- bool
|
|
|
|
*/
|
|
|
|
"intArray": int (
|
|
|
|
64I, 42I, 63I,
|
|
|
|
22I, 96I, -12I,
|
|
|
|
),
|
|
|
|
|
|
|
|
/*
|
|
|
|
The double and float types support
|
|
|
|
Infinity, -Infinity, and NaN.
|
|
|
|
|
|
|
|
They also support both really
|
|
|
|
high and really low value numbers.
|
|
|
|
*/
|
|
|
|
"doubleArray": double (
|
|
|
|
42.5D, -20D, 400D,
|
|
|
|
NaND, -InfinityD, InfinityD,
|
2020-09-13 16:17:53 +10:00
|
|
|
5.3e-200D, 4e+120D, 2.2e200D,
|
|
|
|
),
|
2020-09-09 14:02:38 +10:00
|
|
|
|
|
|
|
/*
|
|
|
|
Arrays are enclosed by an opening
|
|
|
|
tag and a closing tag [ ]
|
|
|
|
|
|
|
|
Like the Named List, it can hold
|
|
|
|
any data type.
|
|
|
|
*/
|
|
|
|
"people": [
|
|
|
|
{"name": "foo", "age": 60B},
|
|
|
|
{"name": "bar", "age": 21B},
|
|
|
|
],
|
|
|
|
|
|
|
|
// This is a single-line comment
|
|
|
|
|
|
|
|
/* This is a multi-line comment */
|
|
|
|
}
|
2020-07-22 15:48:08 +10:00
|
|
|
|
|
|
|
```
|
2020-08-17 22:54:22 +10:00
|
|
|
|
2020-09-09 14:02:38 +10:00
|
|
|
### Special notes
|
2020-07-22 15:48:08 +10:00
|
|
|
|
2020-09-09 14:02:38 +10:00
|
|
|
Don't mix bdf types between different
|
|
|
|
readers, this will cause problems.
|
2020-08-17 22:54:22 +10:00
|
|
|
|
2020-09-09 14:02:38 +10:00
|
|
|
```java
|
|
|
|
|
|
|
|
BdfReader reader1 = new BdfReader();
|
|
|
|
BdfReader reader2 = new BdfReader();
|
|
|
|
|
|
|
|
BdfObject bdf1 = reader1.getObject();
|
|
|
|
BdfObject bdf2 = reader2.getObject();
|
|
|
|
|
|
|
|
// Don't do this
|
|
|
|
bdf1.setNamedList(bdf2.newNamedList());
|
2020-07-22 15:48:08 +10:00
|
|
|
|
2020-09-09 14:02:38 +10:00
|
|
|
// Or this
|
|
|
|
bdf1.setArray(bdf2.newArray());
|
|
|
|
|
|
|
|
// Or this
|
|
|
|
BdfNamedList nl = bdf1.newArray();
|
|
|
|
nl.set("illegal", bdf2.newObject().setString("action"));
|
|
|
|
|
|
|
|
```
|
2020-07-22 15:48:08 +10:00
|
|
|
|