Java builder now checks if buffer was finished upon access.

Also checks for nesting of objects in vector construction.

This avoids common errors in FlatBuffer construction.

Change-Id: I5507c5d767684e20e94883a92448f05acefba4d6
Tested: on Linux.
parent d10f9a6a
...@@ -35,6 +35,7 @@ public class FlatBufferBuilder { ...@@ -35,6 +35,7 @@ public class FlatBufferBuilder {
int[] vtable = null; // The vtable for the current table. int[] vtable = null; // The vtable for the current table.
int vtable_in_use = 0; // The amount of fields we're actually using. int vtable_in_use = 0; // The amount of fields we're actually using.
boolean nested = false; // Whether we are currently serializing a table. boolean nested = false; // Whether we are currently serializing a table.
boolean finished = false; // Whether the buffer is finished.
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.
...@@ -86,6 +87,7 @@ public class FlatBufferBuilder { ...@@ -86,6 +87,7 @@ public class FlatBufferBuilder {
space = bb.capacity(); space = bb.capacity();
vtable_in_use = 0; vtable_in_use = 0;
nested = false; nested = false;
finished = false;
object_start = 0; object_start = 0;
num_vtables = 0; num_vtables = 0;
vector_num_elems = 0; vector_num_elems = 0;
...@@ -240,6 +242,7 @@ public class FlatBufferBuilder { ...@@ -240,6 +242,7 @@ public class FlatBufferBuilder {
vector_num_elems = num_elems; vector_num_elems = num_elems;
prep(SIZEOF_INT, elem_size * num_elems); prep(SIZEOF_INT, elem_size * num_elems);
prep(alignment, elem_size * num_elems); // Just in case alignment > int. prep(alignment, elem_size * num_elems); // Just in case alignment > int.
nested = true;
} }
/** /**
...@@ -250,6 +253,9 @@ public class FlatBufferBuilder { ...@@ -250,6 +253,9 @@ public class FlatBufferBuilder {
* @see #startVector(int, int, int) * @see #startVector(int, int, int)
*/ */
public int endVector() { public int endVector() {
if (!nested)
throw new AssertionError("FlatBuffers: endVector called without startVector");
nested = false;
putInt(vector_num_elems); putInt(vector_num_elems);
return offset(); return offset();
} }
...@@ -284,6 +290,16 @@ public class FlatBufferBuilder { ...@@ -284,6 +290,16 @@ public class FlatBufferBuilder {
return endVector(); return endVector();
} }
/**
* Should not be accessing the final buffer before it is finished.
*/
public void finished() {
if (!finished)
throw new AssertionError(
"FlatBuffers: you can only access the serialized buffer after it has been" +
" finished by FlatBufferBuilder.finish().");
}
/** /**
* Should not be creating any other object, string or vector * Should not be creating any other object, string or vector
* while an object is being constructed * while an object is being constructed
...@@ -452,6 +468,7 @@ public class FlatBufferBuilder { ...@@ -452,6 +468,7 @@ public class FlatBufferBuilder {
prep(minalign, SIZEOF_INT); prep(minalign, SIZEOF_INT);
addOffset(root_table); addOffset(root_table);
bb.position(space); bb.position(space);
finished = true;
} }
public void finish(int root_table, String file_identifier) { public void finish(int root_table, String file_identifier) {
...@@ -481,7 +498,10 @@ public class FlatBufferBuilder { ...@@ -481,7 +498,10 @@ public class FlatBufferBuilder {
// Get the ByteBuffer representing the FlatBuffer. Only call this after you've // Get the ByteBuffer representing the FlatBuffer. Only call this after you've
// called finish(). The actual data starts at the ByteBuffer's current position, // called finish(). The actual data starts at the ByteBuffer's current position,
// not necessarily at 0. // not necessarily at 0.
public ByteBuffer dataBuffer() { return bb; } public ByteBuffer dataBuffer() {
finished();
return bb;
}
/** /**
* The FlatBuffer data doesn't start at offset 0 in the {@link ByteBuffer}, but * The FlatBuffer data doesn't start at offset 0 in the {@link ByteBuffer}, but
...@@ -493,6 +513,7 @@ public class FlatBufferBuilder { ...@@ -493,6 +513,7 @@ public class FlatBufferBuilder {
*/ */
@Deprecated @Deprecated
private int dataStart() { private int dataStart() {
finished();
return space; return space;
} }
...@@ -506,6 +527,7 @@ public class FlatBufferBuilder { ...@@ -506,6 +527,7 @@ public class FlatBufferBuilder {
* @throws IndexOutOfBoundsException If the range of bytes is ouf of bound * @throws IndexOutOfBoundsException If the range of bytes is ouf of bound
*/ */
public byte[] sizedByteArray(int start, int length){ public byte[] sizedByteArray(int start, int length){
finished();
byte[] array = new byte[length]; byte[] array = new byte[length];
bb.position(start); bb.position(start);
bb.get(array); bb.get(array);
......
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