Trying to compress the format as much as possible

This commit is contained in:
josua 2020-08-14 12:25:04 +10:00
parent f73eb0454f
commit 8ba902bacd
4 changed files with 122 additions and 63 deletions

View File

@ -28,16 +28,16 @@ public class BdfArray implements IBdfType, Iterable<BdfObject>
while(i < data.size())
{
// Get the size of the object
int size = DataHelpers.getByteBuffer(data.getPointer(i, Integer.BYTES)).getInt();
int size = BdfObject.getSize(data.getPointer(i));
// Get the object
BdfObject object = new BdfObject(lookupTable, data.getPointer((i+Integer.BYTES), size));
BdfObject object = new BdfObject(lookupTable, data.getPointer(i, size));
// Add the object to the elements list
elements.add(object);
// Increase the iterator by the amount of bytes
i += Integer.BYTES+size;
i += size;
}
}
@ -48,7 +48,6 @@ public class BdfArray implements IBdfType, Iterable<BdfObject>
for(BdfObject o : elements) {
size += o.serializeSeeker(locations);
size += 4;
}
return size;
@ -59,13 +58,8 @@ public class BdfArray implements IBdfType, Iterable<BdfObject>
{
int pos = 0;
for(BdfObject o : elements)
{
int size = o.serialize(database.getPointer(pos + 4), locations);
database.setBytes(pos, DataHelpers.serializeInt(size));
pos += size;
pos += 4;
for(BdfObject o : elements) {
pos += o.serialize(database.getPointer(pos), locations);
}
return pos;

View File

@ -38,8 +38,7 @@ public class BdfNamedList implements IBdfType
i += 4;
// Get the object
int object_size = DataHelpers.getByteBuffer(data.getPointer(i, 4)).getInt();
i += 4;
int object_size = BdfObject.getSize(data.getPointer(i));
BdfObject object = new BdfObject(lookupTable, data.getPointer(i, object_size));
// Create a new element and save some data to it
@ -64,14 +63,9 @@ public class BdfNamedList implements IBdfType
{
database.setBytes(pos, DataHelpers.serializeInt(locations[o.key]));
pos += 4;
int size = o.object.serialize(database.getPointer(pos + 4), locations);
database.setBytes(pos, DataHelpers.serializeInt(size));
pos += 4;
pos += size;
pos += size + 4;
}
return pos;
@ -84,7 +78,7 @@ public class BdfNamedList implements IBdfType
for(Element o : elements)
{
size += 8;
size += 4;
size += o.object.serializeSeeker(locations);
}
@ -128,19 +122,16 @@ public class BdfNamedList implements IBdfType
stream.write('}');
}
public BdfObject get(String key)
public BdfObject get(int key)
{
// Get the object to send back
BdfObject object = null;
// Convert the key to bytes
byte[] key_bytes = key.getBytes();
// Loop over the elements
for(Element e : elements)
{
// Is this the element key
if(DataHelpers.bytesAreEqual(lookupTable.getName(e.key), key_bytes))
if(e.key == key)
{
// Set the object
object = e.object;
@ -160,11 +151,8 @@ public class BdfNamedList implements IBdfType
return o;
}
public BdfObject remove(String key)
public BdfObject remove(int key)
{
// Convert the key to bytes
byte[] key_bytes = key.getBytes();
// Loop over the elements
for(int i=0;i<elements.size();i++)
{
@ -172,7 +160,7 @@ public class BdfNamedList implements IBdfType
Element e = elements.get(i);
// Is the specified key the same as the elements key
if(DataHelpers.bytesAreEqual(lookupTable.getName(e.key), key_bytes)) {
if(e.key == key) {
return elements.remove(i).object;
}
}
@ -181,16 +169,13 @@ public class BdfNamedList implements IBdfType
return null;
}
public BdfNamedList set(String key, BdfObject object)
public BdfNamedList set(int key, BdfObject object)
{
// Convert the key to bytes
byte[] key_bytes = key.getBytes();
// Loop over the elements, does it already exist
for(Element e : elements)
{
// Is the key here the same as the specified key
if(DataHelpers.bytesAreEqual(lookupTable.getName(e.key), key_bytes))
if(e.key == key)
{
// Set the new object
e.object = object;
@ -202,8 +187,8 @@ public class BdfNamedList implements IBdfType
// Create a new element object
Element e = new Element();
e.key = lookupTable.getLocation(key_bytes);
e.object = object;
e.key = key;
// Add the new element object to the elements list
elements.add(e);
@ -212,16 +197,13 @@ public class BdfNamedList implements IBdfType
return this;
}
public boolean contains(String key)
public boolean contains(int key)
{
// Convert the key to bytes
byte[] key_bytes = key.getBytes();
// Loop over the elements
for(Element e : elements)
{
// Is the elements key the same as the specified key
if(DataHelpers.bytesAreEqual(lookupTable.getName(e.key), key_bytes))
if(e.key == key)
{
// Send back true to say the element was found
return true;
@ -232,23 +214,47 @@ public class BdfNamedList implements IBdfType
return false;
}
public String[] getKeys()
public int[] getKeys()
{
// Get the keys to send back
String[] keys = new String[elements.size()];
int[] keys = new int[elements.size()];
// Loop over the elements
for(int i=0;i<elements.size();i++)
{
// Get the element
Element e = elements.get(i);
keys[i] = new String(lookupTable.getName(e.key));
keys[i] = e.key;
}
// Return the list of keys as strings
return keys;
}
public int getKeyLocation(String key) {
return lookupTable.getLocation(key.getBytes());
}
public String getKeyName(int key) {
return new String(lookupTable.getName(key));
}
public boolean contains(String key) {
return contains(lookupTable.getLocation(key.getBytes()));
}
public BdfNamedList set(String key, BdfObject object) {
return set(lookupTable.getLocation(key.getBytes()), object);
}
public BdfObject remove(String key) {
return remove(lookupTable.getLocation(key.getBytes()));
}
public BdfObject get(String key) {
return get(lookupTable.getLocation(key.getBytes()));
}
public int size() {
return elements.size();
}

View File

@ -26,8 +26,15 @@ public class BdfObject implements IBdfType
this.lookupTable = lookupTable;
// Get the type and database values
type = data.getByte(0);
database = data.getPointer(1, data.size() - 1);
byte flags = data.getByte(0);
type = flags & 0x0f;
database = data.getPointer(1);
// Skip the size bytes if size is stored
if(shouldStoreSize(type)) {
database = database.getPointer(4 - (flags & 0b00110000) >> 4);
}
// Set the object variable if there is an object specified
if(type == BdfTypes.STRING) object = database.getString();
@ -39,6 +46,49 @@ public class BdfObject implements IBdfType
}
}
private boolean shouldStoreSize(byte b) {
return b > 7;
}
static int getSize(IBdfDatabase db)
{
byte type = db.getByte(0);
int size = getSize(type);
if(size != -1) {
return size;
}
return DataHelpers.getByteBuffer(db.getPointer(1, 4)).getInt() + 5;
}
static int getSize(byte type)
{
type &= 0x0f;
switch(type)
{
case BdfTypes.BOOLEAN:
return 2;
case BdfTypes.BYTE:
return 2;
case BdfTypes.DOUBLE:
return 9;
case BdfTypes.FLOAT:
return 5;
case BdfTypes.INTEGER:
return 5;
case BdfTypes.LONG:
return 9;
case BdfTypes.SHORT:
return 3;
case BdfTypes.UNDEFINED:
return 1;
default:
return -1;
}
}
@Override
public void getLocationUses(int[] locations)
{
@ -52,33 +102,38 @@ public class BdfObject implements IBdfType
{
int size;
IBdfDatabase db = database.getPointer(1);
boolean storeSize = shouldStoreSize(type);
// Objects
switch(type)
{
case BdfTypes.ARRAY:
size = ((BdfArray)object).serialize(db, locations) + 1;
size = ((BdfArray)object).serialize(database.getPointer(5), locations) + 5;
break;
case BdfTypes.NAMED_LIST:
size = ((BdfNamedList)object).serialize(db, locations) + 1;
size = ((BdfNamedList)object).serialize(database.getPointer(5), locations) + 5;
break;
case BdfTypes.STRING:
byte[] str = ((String)object).getBytes();
size = str.length + 1;
db.setBytes(0, str);
size = str.length + 5;
database.setBytes(5, str);
break;
default:
size = this.database.size() + 1;
db.setBytes(0, this.database.getBytes());
int o = storeSize ? 5 : 1;
size = this.database.size() + o;
database.setBytes(o, this.database.getBytes());
break;
}
database.setByte(0, type);
if(storeSize) {
database.setBytes(1, DataHelpers.serializeInt(size - 5));
}
return size;
}
@ -88,13 +143,18 @@ public class BdfObject implements IBdfType
// Objects
switch(type)
{
case BdfTypes.ARRAY: return ((BdfArray)object).serializeSeeker(locations) + 1;
case BdfTypes.NAMED_LIST: return ((BdfNamedList)object).serializeSeeker(locations) + 1;
case BdfTypes.STRING: return ((String)object).getBytes().length + 1;
case BdfTypes.ARRAY: return ((BdfArray)object).serializeSeeker(locations) + 5;
case BdfTypes.NAMED_LIST: return ((BdfNamedList)object).serializeSeeker(locations) + 5;
case BdfTypes.STRING: return ((String)object).getBytes().length + 5;
}
// Anything else
return database.size() + 1;
int size = getSize(type);
if(size != -1) {
return size;
}
return database.size() + 5;
}
private String calcIndent(BdfIndent indent, int it) {

View File

@ -39,8 +39,8 @@ public class BdfReader
// Get the rest of the data
int upto = lookupTable_size + 4;
int bdf_size = DataHelpers.getByteBuffer(database.getPointer(upto, 4)).getInt();
bdf = new BdfObject(lookupTable, database.getPointer(upto + 4, bdf_size));
int bdf_size = BdfObject.getSize(database.getPointer(upto));
bdf = new BdfObject(lookupTable, database.getPointer(upto, bdf_size));
}
public BdfDatabase serialize()
@ -49,14 +49,13 @@ public class BdfReader
int bdf_size = bdf.serializeSeeker(locations);
int lookupTable_size = lookupTable.serializeSeeker(locations);
int database_size = bdf_size + lookupTable_size + 8;
int database_size = bdf_size + lookupTable_size + 4;
BdfDatabase database = new BdfDatabase(database_size);
database.setBytes(0, DataHelpers.serializeInt(lookupTable_size));
database.setBytes(4 + lookupTable_size, DataHelpers.serializeInt(bdf_size));
lookupTable.serialize(database.getPointer(4, lookupTable_size), locations);
bdf.serialize(database.getPointer(8 + lookupTable_size, database_size), locations);
bdf.serialize(database.getPointer(4 + lookupTable_size, database_size), locations);
return database;
}