Merge pull request #1 from jsrobson10/save

Save
This commit is contained in:
jsrobson10 2019-07-10 14:42:09 +10:00 committed by GitHub
commit 3b94ac2646
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 425 additions and 137 deletions

138
README.md
View File

@ -7,16 +7,16 @@
- <a href="#creating-an-object">Creating an object</a>
- <a href="#arrays">Arrays</a>
- <a href="#named-lists">Named lists</a>
- <a href="#example-bdf-program">Example BDF program</a>
- <a href="#saving-classes">Saving classes</a>
### Overview
Binary Data Format (or BDF) is designed to store data in a tag-like binary structure,
Binary Data Format (or BDF) is designed to store data in a tree-like binary structure,
like Notch's NBT format, but also open source and free like JSON. The format is
fast and allows multiple data types, it uses 32-bit integers, so BDF files can
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
purposes, but it currently can't parse the result to an object.
purposes, but it currently can't parse the human readable serialized string to an object.
### Data types
@ -166,70 +166,92 @@ for(String key : list)
```
### Saving classes
### Example BDF program
Classes can be saved with `BdfClassManager` and by
implementing the `IBdfClassManager` interface,
adding 2 functions `BdfClassLoad` and `BdfClassSave`.
`BdfClassLoad` is for checking and loading data from
bdf into the classes variables, while `BdfClassSave`
is for packing pre-existing variables into bdf format.
A BdfClassManager can be used to pass the `IBdfClassManager`
interface into.
A class with `IBdfClassManager` to save the data
could look like this:
```java
// Create a new BdfObject instance
BdfObject bdf = new BdfObject();
class HelloWorld implements IBdfClassManager
{
int iterator = 0;
@Override
public void BdfClassLoad(BdfObject bdf)
{
// Load scripts here
// Create a new named list if the object isn't a named list
bdf.setNamedListIfInvalid();
// Set the iterator if the iterator hasn't been set yet
bdf.getNamedList().setIfUndefined("iterator", BdfObject.withInteger(0));
// Set the iterator stored in bdf
int iterator = bdf.getNamedList().get("iterator").getInteger();
}
@Override
public void BdfClassSave(BdfObject bdf)
{
// Save scripts here
// Create a named list
BdfNamedList bdf_nl = new BdfNamedList();
bdf.setNamedList();
// Add some variables to the named list
bdf_nl.set("boolean", BdfObject.with(true));
bdf_nl.set("an_int", BdfObject.with((int)53));
bdf_nl.set("double", new BdfObject().setDouble(632.5));
// Set the iterator to the named list
bdf.getNamedList().set("iterator", BdfObject.withInteger(iterator));
}
// Output some checks on BdfNamedList
System.out.println(bdf_nl.contains("an_int")); // true
System.out.println(bdf_nl.contains("this_dosn't_exist")); // false
public void hello()
{
// Increase the iterator by 1
iterator++;
// Create an array
BdfArray bdf_array = new BdfArray();
// Say "Hello, World! Script executed <iterator> times!"
System.out.println("Hello, World! Script executed "+iterator+" times!");
}
// Add some values to the array
bdf_array.add(BdfObject.with("Hello, World!"));
bdf_array.add(BdfObject.with(1234567890L));
bdf_array.set(1, BdfObject.with((short)432));
// Output the size of the array
System.out.println(bdf_array.size()); // 2
// Output the type of the 2nd item in the array, value types are in BdfTypes
System.out.println(bdf_array.get(1).getType()); // 3 (BdfTypes.SHORT)
// Save the array to the named list
bdf_nl.set("array", BdfObject.with(bdf_array));
// Set the named list to the bdf object
bdf.setNamedList(bdf_nl);
// Serialize the data
byte[] bdf_data = bdf.serialize().getBytes();
// Load the serialized data
BdfObject bdf2 = new BdfObject(new BdfDatabase(bdf_data));
// Show the human readable serialized data
System.out.println(bdf2.serializeHumanReadable()); // {"boolean": true, "an_int": 53I, "double": 632.5D, "array": ["Hello, World!", 432S]}
// Show the value of the boolean in the named list
System.out.println(bdf2.getNamedList().get("boolean").getBoolean()); // true
// Show the value of item 0 in the array
System.out.println(bdf2.getNamedList().get("array").getArray().get(0).getString()); // Hello, World!
// Check if the double exists
System.out.println(bdf2.getNamedList().contains("double")); // true
// Remove the double from the named list
bdf2.getNamedList().remove("double");
// Check if the double exists
System.out.println(bdf2.getNamedList().contains("double")); // false
}
```
A script to manage this could look something like this:
```java
/*
Get a new BdfObject instance, it could be existing,
or from another file, BdfArray, or BdfNamedList instance.
*/
BdfObject bdf = new BdfObject();
// Create the HelloWorld class
HelloWorld hello = new HelloWorld();
// Get a new BdfClassManager instance to deal with BDF data
BdfClassManager manager = new BdfClassManager(hello);
// Give the manager an existing BdfObject instance
manager.setBdf(bdf);
// Load the classes bdf data
manager.load();
// Call the hello world function
hello.hello();
// Save the classes bdf data
manager.save();
```

BIN
db.bdf Executable file

Binary file not shown.

Binary file not shown.

View File

@ -1,75 +0,0 @@
package bdf;
import bdf.data.BdfDatabase;
import bdf.types.BdfArray;
import bdf.types.BdfNamedList;
import bdf.types.BdfObject;
public class Tests {
public static void main(String[] args)
{
// Create a new BdfObject instance
BdfObject bdf = new BdfObject();
// Create a named list
BdfNamedList bdf_nl = new BdfNamedList();
// Add some variables to the named list
bdf_nl.set("boolean", BdfObject.with(true));
bdf_nl.set("an_int", BdfObject.with((int)53));
bdf_nl.set("double", new BdfObject().setDouble(632.5));
// Output some checks on BdfNamedList
System.out.println(bdf_nl.contains("an_int")); // true
System.out.println(bdf_nl.contains("this_dosn't_exist")); // false
// Create an array
BdfArray bdf_array = new BdfArray();
// Add some values to the array
bdf_array.add(BdfObject.with("Hello, World!"));
bdf_array.add(BdfObject.with(1234567890L));
bdf_array.set(1, BdfObject.with((short)432));
// Output the size of the array
System.out.println(bdf_array.size()); // 2
// Output the type of the 2nd item in the array, value types are in BdfTypes
System.out.println(bdf_array.get(1).getType()); // 3 (BdfTypes.SHORT)
// Save the array to the named list
bdf_nl.set("array", BdfObject.with(bdf_array));
// Set the named list to the bdf object
bdf.setNamedList(bdf_nl);
// Serialize the data
byte[] bdf_data = bdf.serialize().getBytes();
// Load the serialized data
BdfObject bdf2 = new BdfObject(new BdfDatabase(bdf_data));
// Show the human readable serialized data
System.out.println(bdf2.serializeHumanReadable()); // {"boolean": true, "an_int": 53I, "double": 632.5D, "array": ["Hello, World!", 432S]}
// Show the value of the boolean in the named list
System.out.println(bdf2.getNamedList().get("boolean").getBoolean()); // true
// Show the value of item 0 in the array
System.out.println(bdf2.getNamedList().get("array").getArray().get(0).getString()); // Hello, World!
// Check if the double exists
System.out.println(bdf2.getNamedList().contains("double")); // true
// Remove the double from the named list
bdf2.getNamedList().remove("double");
// Check if the double exists
System.out.println(bdf2.getNamedList().contains("double")); // false
}
}

View File

@ -0,0 +1,39 @@
package bdf.classes;
import bdf.types.BdfObject;
public class BdfClassManager
{
protected IBdfClassManager method;
protected BdfObject object = new BdfObject();
public BdfClassManager(IBdfClassManager method)
{
// Save some variables for later
this.method = method;
}
public void setBdf(BdfObject bdf) {
this.object = bdf;
}
public BdfObject getBdf() {
return this.object;
}
public void save(BdfObject bdf) {
method.BdfClassSave(bdf);
}
public void load(BdfObject bdf) {
method.BdfClassLoad(bdf);
}
public void save() {
this.save(this.object);
}
public void load() {
this.load(this.object);
}
}

View File

@ -0,0 +1,9 @@
package bdf.classes;
import bdf.types.BdfObject;
public interface IBdfClassManager
{
public void BdfClassLoad(BdfObject bdf);
public void BdfClassSave(BdfObject bdf);
}

View File

@ -41,7 +41,7 @@ public class BdfFileManager extends BdfObject
File file = new File(path);
// Create the parent directories
file.getParentFile().mkdirs();
file.getAbsoluteFile().getParentFile().mkdirs();
// Get the database file for output
FileOutputStream out = new FileOutputStream(path);

View File

@ -121,7 +121,7 @@ public class BdfNamedList implements IBdfType
throw new UndefinedKeyException(key);
}
public void remove(String key)
public BdfNamedList remove(String key)
{
// Convert the key to bytes
byte[] key_bytes = key.getBytes();
@ -139,7 +139,7 @@ public class BdfNamedList implements IBdfType
elements.remove(i);
// Exit out of the function, prevent NullPointException
return;
return this;
}
}
@ -147,7 +147,7 @@ public class BdfNamedList implements IBdfType
throw new UndefinedKeyException(key);
}
public void set(String key, BdfObject object)
public BdfNamedList set(String key, BdfObject object)
{
// Convert the key to bytes
byte[] key_bytes = key.getBytes();
@ -162,7 +162,7 @@ public class BdfNamedList implements IBdfType
e.object = object;
// Exit out of the function, don't add another object
return;
return this;
}
}
@ -173,6 +173,23 @@ public class BdfNamedList implements IBdfType
// Add the new element object to the elements list
elements.add(e);
// Send this class back
return this;
}
public BdfNamedList setIfUndefined(String key, BdfObject object)
{
if(this.contains(key)) return this;
else return this.set(key, object);
}
public BdfNamedList allocIfUndefined(String key) {
return this.setIfUndefined(key, new BdfObject());
}
public BdfNamedList alloc(String key) {
return this.set(key, new BdfObject());
}
public boolean contains(String key)

View File

@ -113,6 +113,54 @@ public class BdfObject implements IBdfType
return (new BdfObject()).setNamedList(v);
}
public static BdfObject withInteger(int v) {
return (new BdfObject()).setInteger(v);
}
public static BdfObject withByte(byte v) {
return (new BdfObject()).setByte(v);
}
public static BdfObject withBoolean(boolean v) {
return (new BdfObject()).setBoolean(v);
}
public static BdfObject withFloat(float v) {
return (new BdfObject()).setFloat(v);
}
public static BdfObject withDouble(double v) {
return (new BdfObject()).setDouble(v);
}
public static BdfObject withLong(long v) {
return (new BdfObject()).setLong(v);
}
public static BdfObject withShort(short v) {
return (new BdfObject()).setShort(v);
}
public static BdfObject withString(String v) {
return (new BdfObject()).setString(v);
}
public static BdfObject withArray(BdfArray v) {
return (new BdfObject()).setArray(v);
}
public static BdfObject withBdfNamedList(BdfNamedList v) {
return (new BdfObject()).setNamedList(v);
}
public static BdfObject withArray() {
return (new BdfObject()).setArray(new BdfArray());
}
public static BdfObject withBdfNamedList() {
return (new BdfObject()).setNamedList(new BdfNamedList());
}
public byte getType() {
return this.type;
}
@ -228,4 +276,163 @@ public class BdfObject implements IBdfType
this.object = value;
return this;
}
public BdfObject setArray() {
return this.setArray(new BdfArray());
}
public BdfObject setNamedList() {
return this.setNamedList(new BdfNamedList());
}
public BdfObject set(int v) {
return this.setInteger(v);
}
public BdfObject set(byte v) {
return this.setByte(v);
}
public BdfObject set(boolean v) {
return this.setBoolean(v);
}
public BdfObject set(float v) {
return this.setFloat(v);
}
public BdfObject set(double v) {
return this.setDouble(v);
}
public BdfObject set(long v) {
return this.setLong(v);
}
public BdfObject set(short v) {
return this.setShort(v);
}
public BdfObject set(String v) {
return this.setString(v);
}
public BdfObject set(BdfArray v) {
return this.setArray(v);
}
public BdfObject set(BdfNamedList v) {
return this.setNamedList(v);
}
public BdfObject setIfInvalid(int v) {
if(this.getType() == BdfTypes.INTEGER) return this;
return this.setInteger(v);
}
public BdfObject setIfInvalid(byte v) {
if(this.getType() == BdfTypes.BYTE) return this;
return this.setByte(v);
}
public BdfObject setIfInvalid(boolean v) {
if(this.getType() == BdfTypes.BOOLEAN) return this;
return this.setBoolean(v);
}
public BdfObject setIfInvalid(float v) {
if(this.getType() == BdfTypes.FLOAT) return this;
return this.setFloat(v);
}
public BdfObject setIfInvalid(double v) {
if(this.getType() == BdfTypes.DOUBLE) return this;
return this.setDouble(v);
}
public BdfObject setIfInvalid(long v) {
if(this.getType() == BdfTypes.LONG) return this;
return this.setLong(v);
}
public BdfObject setIfInvalid(short v) {
if(this.getType() == BdfTypes.SHORT) return this;
return this.setShort(v);
}
public BdfObject setIfInvalid(String v) {
if(this.getType() == BdfTypes.STRING) return this;
return this.setString(v);
}
public BdfObject setIfInvalid(BdfArray v) {
if(this.getType() == BdfTypes.ARRAY) return this;
return this.setArray(v);
}
public BdfObject setIfInvalid(BdfNamedList v) {
if(this.getType() == BdfTypes.NAMED_LIST) return this;
return this.setNamedList(v);
}
public BdfObject setIntegerIfInvalid(int v) {
if(this.getType() == BdfTypes.INTEGER) return this;
return this.setInteger(v);
}
public BdfObject setByteIfInvalid(byte v) {
if(this.getType() == BdfTypes.BYTE) return this;
return this.setByte(v);
}
public BdfObject setBooleanIfInvalid(boolean v) {
if(this.getType() == BdfTypes.BOOLEAN) return this;
return this.setBoolean(v);
}
public BdfObject setFloatIfInvalid(float v) {
if(this.getType() == BdfTypes.FLOAT) return this;
return this.setFloat(v);
}
public BdfObject setDoubleIfInvalid(double v) {
if(this.getType() == BdfTypes.DOUBLE) return this;
return this.setDouble(v);
}
public BdfObject setLongIfInvalid(long v) {
if(this.getType() == BdfTypes.LONG) return this;
return this.setLong(v);
}
public BdfObject setShortIfInvalid(short v) {
if(this.getType() == BdfTypes.SHORT) return this;
return this.setShort(v);
}
public BdfObject setStringIfInvalid(String v) {
if(this.getType() == BdfTypes.STRING) return this;
return this.setString(v);
}
public BdfObject setArrayIfInvalid(BdfArray v) {
if(this.getType() == BdfTypes.ARRAY) return this;
return this.setArray(v);
}
public BdfObject setNamedListIfInvalid(BdfNamedList v) {
if(this.getType() == BdfTypes.NAMED_LIST) return this;
return this.setNamedList(v);
}
public BdfObject setArrayIfInvalid() {
if(this.getType() == BdfTypes.ARRAY) return this;
return this.setArray(new BdfArray());
}
public BdfObject setNamedListIfInvalid() {
if(this.getType() == BdfTypes.NAMED_LIST) return this;
return this.setNamedList(new BdfNamedList());
}
}

31
src/tests/TestClass.java Executable file
View File

@ -0,0 +1,31 @@
package tests;
import bdf.classes.IBdfClassManager;
import bdf.types.BdfObject;
public class TestClass implements IBdfClassManager
{
int i = 0;
@Override
public void BdfClassLoad(BdfObject bdf)
{
bdf.setNamedListIfInvalid();
bdf.getNamedList().setIfUndefined("i", BdfObject.withInteger(0));
this.i = bdf.getNamedList().get("i").getInteger();
}
@Override
public void BdfClassSave(BdfObject bdf)
{
bdf.setNamedList();
bdf.getNamedList().set("i", BdfObject.withInteger(i));
}
public void tick()
{
System.out.println(i);
i++;
}
}

38
src/tests/Tests.java Executable file
View File

@ -0,0 +1,38 @@
package tests;
import bdf.classes.BdfClassManager;
import bdf.file.BdfFileManager;
public class Tests {
public static void main(String[] args)
{
BdfFileManager bdf = new BdfFileManager("db.bdf");
bdf.setNamedListIfInvalid();
bdf.getNamedList().allocIfUndefined("class1");
bdf.getNamedList().allocIfUndefined("class2");
TestClass t1 = new TestClass();
BdfClassManager m1 = new BdfClassManager(t1);
m1.setBdf(bdf.getNamedList().get("class1"));
TestClass t2 = new TestClass();
BdfClassManager m2 = new BdfClassManager(t2);
m2.setBdf(bdf.getNamedList().get("class2"));
m1.load();
m2.load();
t1.tick();
t2.tick();
m1.save();
m2.save();
bdf.saveDatabase();
System.out.println(bdf.serializeHumanReadable());
}
}