diff --git a/README.md b/README.md
index 786a7cc..aca3372 100644
--- a/README.md
+++ b/README.md
@@ -7,16 +7,16 @@
- Creating an object
- Arrays
- Named lists
-- Example BDF program
+- Saving classes
### 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
+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
+ bdf.setNamedList();
+
+ // Set the iterator to the named list
+ bdf.getNamedList().set("iterator", BdfObject.withInteger(iterator));
+ }
+
+ public void hello()
+ {
+ // Increase the iterator by 1
+ iterator++;
+
+ // Say "Hello, World! Script executed times!"
+ System.out.println("Hello, World! Script executed "+iterator+" times!");
+ }
+
+}
+
+```
+
+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 a named list
-BdfNamedList bdf_nl = new BdfNamedList();
+// Create the HelloWorld class
+HelloWorld hello = new HelloWorld();
-// 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));
+// Get a new BdfClassManager instance to deal with BDF data
+BdfClassManager manager = new BdfClassManager(hello);
-// 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
+// Give the manager an existing BdfObject instance
+manager.setBdf(bdf);
-// Create an array
-BdfArray bdf_array = new BdfArray();
+// Load the classes bdf data
+manager.load();
-// 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));
+// Call the hello world function
+hello.hello();
-// Output the size of the array
-System.out.println(bdf_array.size()); // 2
+// Save the classes bdf data
+manager.save();
-// 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
-
```
\ No newline at end of file
diff --git a/db.bdf b/db.bdf
new file mode 100755
index 0000000..6ba2bbf
Binary files /dev/null and b/db.bdf differ
diff --git a/db/file.db b/db/file.db
deleted file mode 100755
index 9d461fb..0000000
Binary files a/db/file.db and /dev/null differ
diff --git a/src/bdf/Tests.java b/src/bdf/Tests.java
deleted file mode 100644
index 519c57e..0000000
--- a/src/bdf/Tests.java
+++ /dev/null
@@ -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
-
- }
-
-}
diff --git a/src/bdf/classes/BdfClassManager.java b/src/bdf/classes/BdfClassManager.java
new file mode 100755
index 0000000..28cff0e
--- /dev/null
+++ b/src/bdf/classes/BdfClassManager.java
@@ -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);
+ }
+}
diff --git a/src/bdf/classes/IBdfClassManager.java b/src/bdf/classes/IBdfClassManager.java
new file mode 100755
index 0000000..68a0f5d
--- /dev/null
+++ b/src/bdf/classes/IBdfClassManager.java
@@ -0,0 +1,9 @@
+package bdf.classes;
+
+import bdf.types.BdfObject;
+
+public interface IBdfClassManager
+{
+ public void BdfClassLoad(BdfObject bdf);
+ public void BdfClassSave(BdfObject bdf);
+}
diff --git a/src/bdf/file/BdfFileManager.java b/src/bdf/file/BdfFileManager.java
index 61b9e4a..33ac3f5 100644
--- a/src/bdf/file/BdfFileManager.java
+++ b/src/bdf/file/BdfFileManager.java
@@ -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);
diff --git a/src/bdf/types/BdfNamedList.java b/src/bdf/types/BdfNamedList.java
index 46296ee..56924ae 100644
--- a/src/bdf/types/BdfNamedList.java
+++ b/src/bdf/types/BdfNamedList.java
@@ -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)
diff --git a/src/bdf/types/BdfObject.java b/src/bdf/types/BdfObject.java
index 661583d..217273a 100644
--- a/src/bdf/types/BdfObject.java
+++ b/src/bdf/types/BdfObject.java
@@ -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());
+ }
+
}
diff --git a/src/tests/TestClass.java b/src/tests/TestClass.java
new file mode 100755
index 0000000..c12b74a
--- /dev/null
+++ b/src/tests/TestClass.java
@@ -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++;
+ }
+
+}
diff --git a/src/tests/Tests.java b/src/tests/Tests.java
new file mode 100755
index 0000000..ca7aa62
--- /dev/null
+++ b/src/tests/Tests.java
@@ -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());
+ }
+
+}