Made reading read-only ByteBuffers work.

Also added new constructor that allows ByteBuffer reuse.

Change-Id: I9c20ea96c67533066461f4e23b0d03b9b47cd068
Tested: on OS X.
parent 8e40902d
...@@ -30,7 +30,7 @@ public class FlatBufferBuilder { ...@@ -30,7 +30,7 @@ public class FlatBufferBuilder {
int space; // Remaining space in the ByteBuffer. int space; // Remaining space in the ByteBuffer.
static final Charset utf8charset = Charset.forName("UTF-8"); static final Charset utf8charset = Charset.forName("UTF-8");
int minalign = 1; // Minimum alignment encountered so far. int minalign = 1; // Minimum alignment encountered so far.
int[] vtable; // The vtable for the current table, null otherwise. int[] vtable = null; // The vtable for the current table, null otherwise.
int object_start; // Starting offset of the current struct/table. int object_start; // Starting offset of the current struct/table.
int[] vtables = new int[16]; // List of offsets of all vtables. int[] vtables = new int[16]; // List of offsets of all vtables.
int num_vtables = 0; // Number of entries in `vtables` in use. int num_vtables = 0; // Number of entries in `vtables` in use.
...@@ -47,6 +47,14 @@ public class FlatBufferBuilder { ...@@ -47,6 +47,14 @@ public class FlatBufferBuilder {
bb = newByteBuffer(new byte[initial_size]); bb = newByteBuffer(new byte[initial_size]);
} }
// Alternative constructor allowing reuse of ByteBuffers
public FlatBufferBuilder(ByteBuffer existing_bb) {
bb = existing_bb;
bb.clear();
bb.order(ByteOrder.LITTLE_ENDIAN);
space = bb.capacity();
}
ByteBuffer newByteBuffer(byte[] buf) { ByteBuffer newByteBuffer(byte[] buf) {
ByteBuffer newbb = ByteBuffer.wrap(buf); ByteBuffer newbb = ByteBuffer.wrap(buf);
newbb.order(ByteOrder.LITTLE_ENDIAN); newbb.order(ByteOrder.LITTLE_ENDIAN);
......
...@@ -42,7 +42,17 @@ public class Table { ...@@ -42,7 +42,17 @@ public class Table {
// Create a java String from UTF-8 data stored inside the flatbuffer. // Create a java String from UTF-8 data stored inside the flatbuffer.
protected String __string(int offset) { protected String __string(int offset) {
offset += bb.getInt(offset); offset += bb.getInt(offset);
return new String(bb.array(), offset + SIZEOF_INT, bb.getInt(offset), Charset.forName("UTF-8")); if (bb.hasArray()) {
return new String(bb.array(), offset + SIZEOF_INT, bb.getInt(offset), Charset.forName("UTF-8"));
} else {
// We can't access .array(), since the ByteBuffer is read-only.
// We're forced to make an extra copy:
bb.position(offset + SIZEOF_INT);
byte[] copy = new byte[bb.getInt(offset)];
bb.get(copy);
bb.position(0);
return new String(copy, 0, copy.length, Charset.forName("UTF-8"));
}
} }
// Get the length of a vector whose offset is stored at "offset" in this object. // Get the length of a vector whose offset is stored at "offset" in this object.
......
...@@ -103,9 +103,12 @@ class JavaTest { ...@@ -103,9 +103,12 @@ class JavaTest {
} }
// Test it: // Test it:
TestBuffer(fbb.dataBuffer(), fbb.dataStart()); TestBuffer(fbb.dataBuffer(), fbb.dataStart());
// Make sure it also works with read only ByteBuffers. This is slower, since
// creating strings incurs an additional copy (see Table.__string).
TestBuffer(fbb.dataBuffer().asReadOnlyBuffer(), fbb.dataStart());
System.out.println("FlatBuffers test: completed successfully"); System.out.println("FlatBuffers test: completed successfully");
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment