mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-29 01:00:01 +00:00
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.
This commit is contained in:
@@ -28,18 +28,19 @@ import java.nio.charset.Charset;
|
|||||||
* main FlatBuffers documentation.
|
* main FlatBuffers documentation.
|
||||||
*/
|
*/
|
||||||
public class FlatBufferBuilder {
|
public class FlatBufferBuilder {
|
||||||
ByteBuffer bb; // Where we construct the FlatBuffer.
|
ByteBuffer bb; // Where we construct the FlatBuffer.
|
||||||
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 = 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.
|
||||||
int object_start; // Starting offset of the current struct/table.
|
boolean finished = false; // Whether the buffer is finished.
|
||||||
int[] vtables = new int[16]; // List of offsets of all vtables.
|
int object_start; // Starting offset of the current struct/table.
|
||||||
int num_vtables = 0; // Number of entries in `vtables` in use.
|
int[] vtables = new int[16]; // List of offsets of all vtables.
|
||||||
int vector_num_elems = 0; // For the current vector being built.
|
int num_vtables = 0; // Number of entries in `vtables` in use.
|
||||||
boolean force_defaults = false; // False omits default values from the serialized data
|
int vector_num_elems = 0; // For the current vector being built.
|
||||||
|
boolean force_defaults = false; // False omits default values from the serialized data
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start with a buffer of size {@code initial_size}, then grow as required.
|
* Start with a buffer of size {@code initial_size}, then grow as required.
|
||||||
@@ -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 {
|
|||||||
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 {
|
|||||||
* @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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
// 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 {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
private int dataStart() {
|
private int dataStart() {
|
||||||
|
finished();
|
||||||
return space;
|
return space;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user