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

View File

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

View File

@ -26,8 +26,15 @@ public class BdfObject implements IBdfType
this.lookupTable = lookupTable; this.lookupTable = lookupTable;
// Get the type and database values // Get the type and database values
type = data.getByte(0); byte flags = data.getByte(0);
database = data.getPointer(1, data.size() - 1);
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 // Set the object variable if there is an object specified
if(type == BdfTypes.STRING) object = database.getString(); 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 @Override
public void getLocationUses(int[] locations) public void getLocationUses(int[] locations)
{ {
@ -52,33 +102,38 @@ public class BdfObject implements IBdfType
{ {
int size; int size;
IBdfDatabase db = database.getPointer(1); boolean storeSize = shouldStoreSize(type);
// Objects // Objects
switch(type) switch(type)
{ {
case BdfTypes.ARRAY: case BdfTypes.ARRAY:
size = ((BdfArray)object).serialize(db, locations) + 1; size = ((BdfArray)object).serialize(database.getPointer(5), locations) + 5;
break; break;
case BdfTypes.NAMED_LIST: case BdfTypes.NAMED_LIST:
size = ((BdfNamedList)object).serialize(db, locations) + 1; size = ((BdfNamedList)object).serialize(database.getPointer(5), locations) + 5;
break; break;
case BdfTypes.STRING: case BdfTypes.STRING:
byte[] str = ((String)object).getBytes(); byte[] str = ((String)object).getBytes();
size = str.length + 1; size = str.length + 5;
db.setBytes(0, str); database.setBytes(5, str);
break; break;
default: default:
size = this.database.size() + 1; int o = storeSize ? 5 : 1;
db.setBytes(0, this.database.getBytes()); size = this.database.size() + o;
database.setBytes(o, this.database.getBytes());
break; break;
} }
database.setByte(0, type); database.setByte(0, type);
if(storeSize) {
database.setBytes(1, DataHelpers.serializeInt(size - 5));
}
return size; return size;
} }
@ -88,13 +143,18 @@ public class BdfObject implements IBdfType
// Objects // Objects
switch(type) switch(type)
{ {
case BdfTypes.ARRAY: return ((BdfArray)object).serializeSeeker(locations) + 1; case BdfTypes.ARRAY: return ((BdfArray)object).serializeSeeker(locations) + 5;
case BdfTypes.NAMED_LIST: return ((BdfNamedList)object).serializeSeeker(locations) + 1; case BdfTypes.NAMED_LIST: return ((BdfNamedList)object).serializeSeeker(locations) + 5;
case BdfTypes.STRING: return ((String)object).getBytes().length + 1; case BdfTypes.STRING: return ((String)object).getBytes().length + 5;
} }
// Anything else int size = getSize(type);
return database.size() + 1;
if(size != -1) {
return size;
}
return database.size() + 5;
} }
private String calcIndent(BdfIndent indent, int it) { private String calcIndent(BdfIndent indent, int it) {

View File

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