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>
|
2019-07-10 12:15:25 +10:00
|
|
|
- <a href="#saving-classes">Saving classes</a>
|
2020-07-22 15:48:08 +10:00
|
|
|
- <a href="#implementation-details">Implementation details</a>
|
2019-07-09 22:02:35 +10:00
|
|
|
|
|
|
|
### Overview
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2019-07-10 12:02:36 +10:00
|
|
|
Binary Data Format (or BDF) is designed to store data in a tree-like binary structure,
|
2019-07-09 21:53:05 +10:00
|
|
|
like Notch's NBT format, but also open source and free like JSON. The format is
|
2020-08-17 22:54:22 +10:00
|
|
|
fast and allows multiple data types. It uses 32-bit integers, so BDF files can
|
2019-07-09 21:53:05 +10:00
|
|
|
be fast and work well on 32-bit systems, but have a maximum size of 2 GB.
|
|
|
|
BDF allows human readable serialization to see what is going on for debugging
|
2019-07-10 12:02:36 +10:00
|
|
|
purposes, but it currently can't parse the human readable serialized string to an object.
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-07-22 15:27:04 +10:00
|
|
|
|
|
|
|
### Languages
|
|
|
|
|
|
|
|
- Java
|
|
|
|
- <a href="https://github.com/jsrobson10/BdfCpp">C++</a>
|
|
|
|
|
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-08-17 22:54:22 +10:00
|
|
|
// Set a "smart" integer
|
|
|
|
bdf.setSmartInteger(53);
|
|
|
|
|
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-08-17 22:54:22 +10:00
|
|
|
IBdfDatabase data = bdf.serialize();
|
2019-07-09 21:53:05 +10:00
|
|
|
|
|
|
|
// Load another BDF object with the serialized bytes
|
|
|
|
BdfObject bdf2 = new BdfObject(new BdfDatabase(data));
|
|
|
|
|
|
|
|
```
|
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
A file manager instance can be used in the same way as a reader object,
|
|
|
|
but it also needs a String parameter for the path of the file. The file
|
|
|
|
manager instance also has the capacity to use compression (by default this
|
|
|
|
uses the GZIP compression algorithm).
|
2019-07-09 21:53:05 +10:00
|
|
|
|
|
|
|
```java
|
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
// Open a file with compression enabled
|
|
|
|
BdfFileManager reader = new BdfFileManager("file.bdf", true);
|
2019-07-09 21:53:05 +10:00
|
|
|
|
|
|
|
// Save the database
|
2020-08-17 22:54:22 +10:00
|
|
|
reader.saveDatabase();
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
// The file can be casted to a BdfReader
|
|
|
|
BdfReader reader2 = (BdfReader) reader;
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
// Can be used just as any reader instance
|
|
|
|
BdfObject bdf = reader.getObject();
|
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-08-17 22:54:22 +10:00
|
|
|
Arrays can be used to store lists of information, they hold instances of
|
|
|
|
BdfObject. Arrays have support for Iterators and are an instance of Iterable.
|
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
|
|
|
|
array.add(bdf.newObject().setByte(53));
|
2019-07-09 21:53:05 +10:00
|
|
|
|
|
|
|
// Set the array to the bdf object
|
|
|
|
bdf.setArray(array);
|
|
|
|
|
|
|
|
// Iterate over an array
|
|
|
|
for(BdfObject o : 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();
|
|
|
|
BdfObject bdf = new BdfObject();
|
|
|
|
|
|
|
|
// New named list
|
|
|
|
BdfNamedList nl = bdf.newNamedList();
|
|
|
|
|
|
|
|
// Set an element to the named list
|
|
|
|
nl.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.
|
|
|
|
|
|
|
|
int key2 = nl.getKeyLocation("key2");
|
|
|
|
nl.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
|
|
|
|
boolean has_key = list.contains("key1");
|
|
|
|
|
|
|
|
// 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
|
|
|
|
String key_name = nl.getKeyName(key);
|
2019-07-09 21:53:05 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
### Further optimisations
|
2019-07-09 21:53:05 +10:00
|
|
|
|
2020-07-22 15:48:08 +10:00
|
|
|
|
|
|
|
### Implementation details
|
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
All integer data types are in the Big Endian layout.
|
|
|
|
|
|
|
|
**Flags (1 unsigned byte)**
|
|
|
|
This holds 3 values:
|
|
|
|
- Type (0-17)
|
|
|
|
- Size type (0-2)
|
|
|
|
- Parent payload (0-2)
|
2020-07-22 15:48:08 +10:00
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
**Type**
|
2020-07-22 15:48:08 +10:00
|
|
|
```
|
2020-08-17 22:54:22 +10:00
|
|
|
0: UNDEFINED (0 bytes)
|
2020-07-22 15:48:08 +10:00
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
1: BOOLEAN (1 byte, 0x00 or 0x01)
|
|
|
|
2: INTEGER (4 bytes)
|
|
|
|
3: LONG (8 bytes)
|
|
|
|
4: SHORT (2 bytes)
|
|
|
|
5: BYTE (1 byte)
|
|
|
|
6: DOUBLE (8 bytes)
|
|
|
|
7: FLOAT (4 bytes)
|
2020-07-22 15:48:08 +10:00
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
8: STRING
|
|
|
|
9: ARRAY
|
|
|
|
10: NAMED_LIST
|
2020-07-22 15:48:08 +10:00
|
|
|
|
|
|
|
11: ARRAY_BOOLEAN
|
|
|
|
12: ARRAY_INTEGER
|
|
|
|
13: ARRAY_LONG
|
|
|
|
14: ARRAY_SHORT
|
|
|
|
15: ARRAY_BYTE
|
|
|
|
16: ARRAY_DOUBLE
|
|
|
|
17: ARRAY_FLOAT
|
2020-08-17 22:54:22 +10:00
|
|
|
|
2020-07-22 15:48:08 +10:00
|
|
|
```
|
|
|
|
|
2020-08-17 22:54:22 +10:00
|
|
|
**Size Type**
|
|
|
|
This value holds info for how big the size of
|
|
|
|
the size of the payload is, in bytes. The purpose
|
|
|
|
of this is to reduce the size as much as possible
|
|
|
|
by throwing out unneccicary zeros.
|
|
|
|
|
2020-07-22 15:48:08 +10:00
|
|
|
**Object**
|
2020-08-17 22:54:22 +10:00
|
|
|
- Flags (unsigned byte, 1 byte)
|
|
|
|
- Size (variable length)
|
2020-07-22 15:48:08 +10:00
|
|
|
- Payload (Any type, variable length)
|
|
|
|
|
|
|
|
**NamedList**
|
2020-08-17 22:54:22 +10:00
|
|
|
- Key ID (variable length)
|
2020-07-22 15:48:08 +10:00
|
|
|
- Payload (Object, variable length)
|
|
|
|
|
|
|
|
**Array**
|
|
|
|
- Payload (Object, variable length)
|