T *GetMutableRoot(void *buf) {
EndianCheck();
@@ -1286,6 +1388,7 @@ volatile __attribute__((weak)) const char *flatbuffer_version_string =
#endif // !defined(_WIN32) && !defined(__CYGWIN__)
+/// @endcond
} // namespace flatbuffers
#endif // FLATBUFFERS_H_
diff --git a/java/com/google/flatbuffers/Constants.java b/java/com/google/flatbuffers/Constants.java
index 67585d728..ac0593ae6 100644
--- a/java/com/google/flatbuffers/Constants.java
+++ b/java/com/google/flatbuffers/Constants.java
@@ -16,12 +16,19 @@
package com.google.flatbuffers;
-// Class that holds shared constants.
+/// @cond FLATBUFFERS_INTERNAL
+/**
+ * Class that holds shared constants
+ */
public class Constants {
// Java doesn't seem to have these.
+ /** The number of bytes in a `short`. */
static final int SIZEOF_SHORT = 2;
+ /** The number of bytes in an `int`. */
static final int SIZEOF_INT = 4;
+ /** The number of bytes in a file identifier. */
static final int FILE_IDENTIFIER_LENGTH = 4;
}
+/// @endcond
diff --git a/java/com/google/flatbuffers/FlatBufferBuilder.java b/java/com/google/flatbuffers/FlatBufferBuilder.java
index a6234ca63..e86471397 100644
--- a/java/com/google/flatbuffers/FlatBufferBuilder.java
+++ b/java/com/google/flatbuffers/FlatBufferBuilder.java
@@ -22,30 +22,36 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
+/// @file
+/// @addtogroup flatbuffers_java_api
+/// @{
+
/**
* Class that helps you build a FlatBuffer. See the section
- * "Use in Java" in the
+ * @ref flatbuffers_guide_use_java_c-sharp "Use in Java/C#" in the
* main FlatBuffers documentation.
*/
public class FlatBufferBuilder {
- ByteBuffer bb; // Where we construct the FlatBuffer.
- int space; // Remaining space in the ByteBuffer.
- static final Charset utf8charset = Charset.forName("UTF-8");
- int minalign = 1; // Minimum alignment encountered so far.
- int[] vtable = null; // The vtable for the current table.
- int vtable_in_use = 0; // The amount of fields we're actually using.
- 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[] vtables = new int[16]; // List of offsets of all vtables.
- int num_vtables = 0; // Number of entries in `vtables` in use.
- int vector_num_elems = 0; // For the current vector being built.
- boolean force_defaults = false; // False omits default values from the serialized data
+ /// @cond FLATBUFFERS_INTERNAL
+ ByteBuffer bb; // Where we construct the FlatBuffer.
+ int space; // Remaining space in the ByteBuffer.
+ static final Charset utf8charset = Charset.forName("UTF-8"); // The UTF-8 character set used by FlatBuffers.
+ int minalign = 1; // Minimum alignment encountered so far.
+ int[] vtable = null; // The vtable for the current table.
+ int vtable_in_use = 0; // The amount of fields we're actually using.
+ 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[] vtables = new int[16]; // List of offsets of all vtables.
+ int num_vtables = 0; // Number of entries in `vtables` in use.
+ int vector_num_elems = 0; // For the current vector being built.
+ boolean force_defaults = false; // False omits default values from the serialized data.
+ /// @endcond
/**
- * Start with a buffer of size {@code initial_size}, then grow as required.
+ * Start with a buffer of size `initial_size`, then grow as required.
*
- * @param initial_size The initial size of the internal buffer to use
+ * @param initial_size The initial size of the internal buffer to use.
*/
public FlatBufferBuilder(int initial_size) {
if (initial_size <= 0) initial_size = 1;
@@ -63,9 +69,9 @@ public class FlatBufferBuilder {
/**
* Alternative constructor allowing reuse of {@link ByteBuffer}s. The builder
* can still grow the buffer as necessary. User classes should make sure
- * to call {@link #dataBuffer()} to obtain the resulting encoded message
+ * to call {@link #dataBuffer()} to obtain the resulting encoded message.
*
- * @param existing_bb The byte buffer to reuse
+ * @param existing_bb The byte buffer to reuse.
*/
public FlatBufferBuilder(ByteBuffer existing_bb) {
init(existing_bb);
@@ -73,11 +79,11 @@ public class FlatBufferBuilder {
/**
* Alternative initializer that allows reusing this object on an existing
- * ByteBuffer. This method resets the builder's internal state, but keeps
+ * `ByteBuffer`. This method resets the builder's internal state, but keeps
* objects that have been allocated for temporary storage.
*
- * @param existing_bb The byte buffer to reuse
- * @return this
+ * @param existing_bb The byte buffer to reuse.
+ * @return Returns `this`.
*/
public FlatBufferBuilder init(ByteBuffer existing_bb){
bb = existing_bb;
@@ -94,6 +100,13 @@ public class FlatBufferBuilder {
return this;
}
+ /// @cond FLATBUFFERS_INTERNAL
+ /**
+ * Create a `ByteBuffer` with a given capacity.
+ *
+ * @param capacity The size of the `ByteBuffer` to allocate.
+ * @return Returns the new `ByteBuffer` that was allocated.
+ */
static ByteBuffer newByteBuffer(int capacity) {
ByteBuffer newbb = ByteBuffer.allocate(capacity);
newbb.order(ByteOrder.LITTLE_ENDIAN);
@@ -101,10 +114,10 @@ public class FlatBufferBuilder {
}
/**
- * Doubles the size of the backing {link ByteBuffer} and copies the old data towards the
+ * Doubles the size of the backing {@link ByteBuffer} and copies the old data towards the
* end of the new buffer (since we build the buffer backwards).
*
- * @param bb The current buffer with the existing data
+ * @param bb The current buffer with the existing data.
* @return A new byte buffer with the old data copied copied to it. The data is
* located at the end of the buffer.
*/
@@ -130,7 +143,7 @@ public class FlatBufferBuilder {
}
/**
- * Add zero valued bytes to prepare a new entry to be added
+ * Add zero valued bytes to prepare a new entry to be added.
*
* @param byte_size Number of bytes to add.
*/
@@ -139,14 +152,14 @@ public class FlatBufferBuilder {
}
/**
- * Prepare to write an element of {@code size} after {@code additional_bytes}
+ * Prepare to write an element of `size` after `additional_bytes`
* have been written, e.g. if you write a string, you need to align such
* the int length field is aligned to {@link com.google.flatbuffers.Constants#SIZEOF_INT}, and
- * the string data follows it directly. If all you need to do is alignment, {@code additional_bytes}
+ * the string data follows it directly. If all you need to do is alignment, `additional_bytes`
* will be 0.
*
- * @param size This is the of the new element to write
- * @param additional_bytes The padding size
+ * @param size This is the of the new element to write.
+ * @param additional_bytes The padding size.
*/
public void prep(int size, int additional_bytes) {
// Track the biggest thing we've ever aligned to.
@@ -163,30 +176,116 @@ public class FlatBufferBuilder {
pad(align_size);
}
- // Add a scalar to the buffer, backwards from the current location.
- // Doesn't align nor check for space.
+ /**
+ * Add a `boolean` to the buffer, backwards from the current location. Doesn't align nor
+ * check for space.
+ *
+ * @param x A `boolean` to put into the buffer.
+ */
public void putBoolean(boolean x) { bb.put (space -= 1, (byte)(x ? 1 : 0)); }
- public void putByte (byte x) { bb.put (space -= 1, x); }
- public void putShort (short x) { bb.putShort (space -= 2, x); }
- public void putInt (int x) { bb.putInt (space -= 4, x); }
- public void putLong (long x) { bb.putLong (space -= 8, x); }
- public void putFloat (float x) { bb.putFloat (space -= 4, x); }
- public void putDouble (double x) { bb.putDouble(space -= 8, x); }
- // Adds a scalar to the buffer, properly aligned, and the buffer grown
- // if needed.
+ /**
+ * Add a `byte` to the buffer, backwards from the current location. Doesn't align nor
+ * check for space.
+ *
+ * @param x A `byte` to put into the buffer.
+ */
+ public void putByte (byte x) { bb.put (space -= 1, x); }
+
+ /**
+ * Add a `short` to the buffer, backwards from the current location. Doesn't align nor
+ * check for space.
+ *
+ * @param x A `short` to put into the buffer.
+ */
+ public void putShort (short x) { bb.putShort (space -= 2, x); }
+
+ /**
+ * Add an `int` to the buffer, backwards from the current location. Doesn't align nor
+ * check for space.
+ *
+ * @param x An `int` to put into the buffer.
+ */
+ public void putInt (int x) { bb.putInt (space -= 4, x); }
+
+ /**
+ * Add a `long` to the buffer, backwards from the current location. Doesn't align nor
+ * check for space.
+ *
+ * @param x A `long` to put into the buffer.
+ */
+ public void putLong (long x) { bb.putLong (space -= 8, x); }
+
+ /**
+ * Add a `float` to the buffer, backwards from the current location. Doesn't align nor
+ * check for space.
+ *
+ * @param x A `float` to put into the buffer.
+ */
+ public void putFloat (float x) { bb.putFloat (space -= 4, x); }
+
+ /**
+ * Add a `double` to the buffer, backwards from the current location. Doesn't align nor
+ * check for space.
+ *
+ * @param x A `double` to put into the buffer.
+ */
+ public void putDouble (double x) { bb.putDouble(space -= 8, x); }
+ /// @endcond
+
+ /**
+ * Add a `boolean` to the buffer, properly aligned, and grows the buffer (if necessary).
+ *
+ * @param x A `boolean` to put into the buffer.
+ */
public void addBoolean(boolean x) { prep(1, 0); putBoolean(x); }
+
+ /**
+ * Add a `byte` to the buffer, properly aligned, and grows the buffer (if necessary).
+ *
+ * @param x A `byte` to put into the buffer.
+ */
public void addByte (byte x) { prep(1, 0); putByte (x); }
+
+ /**
+ * Add a `short` to the buffer, properly aligned, and grows the buffer (if necessary).
+ *
+ * @param x A `short` to put into the buffer.
+ */
public void addShort (short x) { prep(2, 0); putShort (x); }
+
+ /**
+ * Add an `int` to the buffer, properly aligned, and grows the buffer (if necessary).
+ *
+ * @param x An `int` to put into the buffer.
+ */
public void addInt (int x) { prep(4, 0); putInt (x); }
+
+ /**
+ * Add a `long` to the buffer, properly aligned, and grows the buffer (if necessary).
+ *
+ * @param x A `long` to put into the buffer.
+ */
public void addLong (long x) { prep(8, 0); putLong (x); }
+
+ /**
+ * Add a `float` to the buffer, properly aligned, and grows the buffer (if necessary).
+ *
+ * @param x A `float` to put into the buffer.
+ */
public void addFloat (float x) { prep(4, 0); putFloat (x); }
+
+ /**
+ * Add a `double` to the buffer, properly aligned, and grows the buffer (if necessary).
+ *
+ * @param x A `double` to put into the buffer.
+ */
public void addDouble (double x) { prep(8, 0); putDouble (x); }
/**
* Adds on offset, relative to where it will be written.
*
- * @param off The offset to add
+ * @param off The offset to add.
*/
public void addOffset(int off) {
prep(SIZEOF_INT, 0); // Ensure alignment is already done.
@@ -195,15 +294,16 @@ public class FlatBufferBuilder {
putInt(off);
}
+ /// @cond FLATBUFFERS_INTERNAL
/**
* Start a new array/vector of objects. Users usually will not call
- * this directly. The {@code FlatBuffers} compiler will create a start/end
+ * this directly. The `FlatBuffers` compiler will create a start/end
* method for vector types in generated code.
*
* The expected sequence of calls is:
*
* - Start the array using this method.
- * - Call {@link #addOffset(int)} {@code num_elems} number of times to set
+ *
- Call {@link #addOffset(int)} `num_elems` number of times to set
* the offset of each element in the array.
* - Call {@link #endVector()} to retrieve the offset of the array.
*
@@ -233,9 +333,9 @@ public class FlatBufferBuilder {
* int offsetOfTheVector = fbb.endVector();
* }
*
- * @param elem_size The size of each element in the array
- * @param num_elems The number of elements in the array
- * @param alignment The alignment of the array
+ * @param elem_size The size of each element in the array.
+ * @param num_elems The number of elements in the array.
+ * @param alignment The alignment of the array.
*/
public void startVector(int elem_size, int num_elems, int alignment) {
notNested();
@@ -259,12 +359,13 @@ public class FlatBufferBuilder {
putInt(vector_num_elems);
return offset();
}
+ /// @endcond
/**
- * Encode the string {@code s} in the buffer using UTF-8.
+ * Encode the string `s` in the buffer using UTF-8.
*
- * @param s The string to encode
- * @return The offset in the buffer where the encoded string starts
+ * @param s The string to encode.
+ * @return The offset in the buffer where the encoded string starts.
*/
public int createString(String s) {
byte[] utf8 = s.getBytes(utf8charset);
@@ -276,10 +377,10 @@ public class FlatBufferBuilder {
}
/**
- * Encode the string {@code s} in the buffer using UTF-8.
+ * Create a string in the buffer from an already encoded UTF-8 string in a ByteBuffer.
*
- * @param s An already encoded UTF-8 string
- * @return The offset in the buffer where the encoded string starts
+ * @param s An already encoded UTF-8 string as a `ByteBuffer`.
+ * @return The offset in the buffer where the encoded string starts.
*/
public int createString(ByteBuffer s) {
int length = s.remaining();
@@ -290,6 +391,7 @@ public class FlatBufferBuilder {
return endVector();
}
+ /// @cond FLATBUFFERS_INTERNAL
/**
* Should not be accessing the final buffer before it is finished.
*/
@@ -302,7 +404,7 @@ public class FlatBufferBuilder {
/**
* Should not be creating any other object, string or vector
- * while an object is being constructed
+ * while an object is being constructed.
*/
public void notNested() {
if (nested)
@@ -314,7 +416,7 @@ public class FlatBufferBuilder {
* where they're used. You'll get this assertion failure if you
* created it elsewhere.
*
- * @param obj The offset of the created object
+ * @param obj The offset of the created object.
*/
public void Nested(int obj) {
if (obj != offset())
@@ -323,12 +425,12 @@ public class FlatBufferBuilder {
/**
* Start encoding a new object in the buffer. Users will not usually need to
- * call this directly. The {@code FlatBuffers} compiler will generate helper methods
+ * call this directly. The `FlatBuffers` compiler will generate helper methods
* that call this method internally.
*
* For example, using the "Monster" code found on the
- * landing page. An
- * object of type {@code Monster} can be created using the following code:
+ * @ref flatbuffers_guide_use_java_c-sharp "landing page". An
+ * object of type `Monster` can be created using the following code:
*
*
{@code
* int testArrayOfString = Monster.createTestarrayofstringVector(fbb, new int[] {
@@ -351,14 +453,14 @@ public class FlatBufferBuilder {
*
* Here:
*
- * - The call to {@code Monster#startMonster(FlatBufferBuilder)} will call this
+ *
- The call to `Monster#startMonster(FlatBufferBuilder)` will call this
* method with the right number of fields set.
- * - {@code Monster#endMonster(FlatBufferBuilder)} will ensure {@link #endObject()} is called.
+ * - `Monster#endMonster(FlatBufferBuilder)` will ensure {@link #endObject()} is called.
*
*
* It's not recommended to call this method directly. If it's called manually, you must ensure
* to audit all calls to it whenever fields are added or removed from your schema. This is
- * automatically done by the code generated by the {@code FlatBuffers} compiler.
+ * automatically done by the code generated by the `FlatBuffers` compiler.
*
* @param numfields The number of fields found in this object.
*/
@@ -371,17 +473,101 @@ public class FlatBufferBuilder {
object_start = offset();
}
- // Add a scalar to a table at `o` into its vtable, with value `x` and default `d`
+ /**
+ * Add a `boolean` to a table at `o` into its vtable, with value `x` and default `d`.
+ *
+ * @param o The index into the vtable.
+ * @param x A `boolean` to put into the buffer, depending on how defaults are handled. If
+ * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+ * default value, it can be skipped.
+ * @param d A `boolean` default value to compare against when `force_defaults` is `false`.
+ */
public void addBoolean(int o, boolean x, boolean d) { if(force_defaults || x != d) { addBoolean(x); slot(o); } }
+
+ /**
+ * Add a `byte` to a table at `o` into its vtable, with value `x` and default `d`.
+ *
+ * @param o The index into the vtable.
+ * @param x A `byte` to put into the buffer, depending on how defaults are handled. If
+ * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+ * default value, it can be skipped.
+ * @param d A `byte` default value to compare against when `force_defaults` is `false`.
+ */
public void addByte (int o, byte x, int d) { if(force_defaults || x != d) { addByte (x); slot(o); } }
+
+ /**
+ * Add a `short` to a table at `o` into its vtable, with value `x` and default `d`.
+ *
+ * @param o The index into the vtable.
+ * @param x A `short` to put into the buffer, depending on how defaults are handled. If
+ * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+ * default value, it can be skipped.
+ * @param d A `short` default value to compare against when `force_defaults` is `false`.
+ */
public void addShort (int o, short x, int d) { if(force_defaults || x != d) { addShort (x); slot(o); } }
+
+ /**
+ * Add an `int` to a table at `o` into its vtable, with value `x` and default `d`.
+ *
+ * @param o The index into the vtable.
+ * @param x An `int` to put into the buffer, depending on how defaults are handled. If
+ * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+ * default value, it can be skipped.
+ * @param d An `int` default value to compare against when `force_defaults` is `false`.
+ */
public void addInt (int o, int x, int d) { if(force_defaults || x != d) { addInt (x); slot(o); } }
+
+ /**
+ * Add a `long` to a table at `o` into its vtable, with value `x` and default `d`.
+ *
+ * @param o The index into the vtable.
+ * @param x A `long` to put into the buffer, depending on how defaults are handled. If
+ * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+ * default value, it can be skipped.
+ * @param d A `long` default value to compare against when `force_defaults` is `false`.
+ */
public void addLong (int o, long x, long d) { if(force_defaults || x != d) { addLong (x); slot(o); } }
+
+ /**
+ * Add a `float` to a table at `o` into its vtable, with value `x` and default `d`.
+ *
+ * @param o The index into the vtable.
+ * @param x A `float` to put into the buffer, depending on how defaults are handled. If
+ * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+ * default value, it can be skipped.
+ * @param d A `float` default value to compare against when `force_defaults` is `false`.
+ */
public void addFloat (int o, float x, double d) { if(force_defaults || x != d) { addFloat (x); slot(o); } }
+
+ /**
+ * Add a `double` to a table at `o` into its vtable, with value `x` and default `d`.
+ *
+ * @param o The index into the vtable.
+ * @param x A `double` to put into the buffer, depending on how defaults are handled. If
+ * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+ * default value, it can be skipped.
+ * @param d A `double` default value to compare against when `force_defaults` is `false`.
+ */
public void addDouble (int o, double x, double d) { if(force_defaults || x != d) { addDouble (x); slot(o); } }
+
+ /**
+ * Add an `offset` to a table at `o` into its vtable, with value `x` and default `d`.
+ *
+ * @param o The index into the vtable.
+ * @param x An `offset` to put into the buffer, depending on how defaults are handled. If
+ * `force_defaults` is `false`, compare `x` against the default value `d`. If `x` contains the
+ * default value, it can be skipped.
+ * @param d An `offset` default value to compare against when `force_defaults` is `false`.
+ */
public void addOffset (int o, int x, int d) { if(force_defaults || x != d) { addOffset (x); slot(o); } }
- // Structs are stored inline, so nothing additional is being added. `d` is always 0.
+ /**
+ * Add a struct to the table. Structs are stored inline, so nothing additional is being added.
+ *
+ * @param voffset The index into the vtable.
+ * @param x The offset of the created struct.
+ * @param d The default value is always `0`.
+ */
public void addStruct(int voffset, int x, int d) {
if(x != d) {
Nested(x);
@@ -389,7 +575,12 @@ public class FlatBufferBuilder {
}
}
- // Set the current vtable at `voffset` to the current location in the buffer.
+ /**
+ * Set the current vtable at `voffset` to the current location in the buffer.
+ *
+ * @param voffset The index into the vtable to store the offset relative to the end of the
+ * buffer.
+ */
public void slot(int voffset) {
vtable[voffset] = offset();
}
@@ -397,7 +588,7 @@ public class FlatBufferBuilder {
/**
* Finish off writing the object that is under construction.
*
- * @return The offset to the object inside {@link #dataBuffer()}
+ * @return The offset to the object inside {@link #dataBuffer()}.
* @see #startObject(int)
*/
public int endObject() {
@@ -453,8 +644,13 @@ public class FlatBufferBuilder {
return vtableloc;
}
- // This checks a required field has been set in a given table that has
- // just been constructed.
+ /**
+ * Checks that a required field has been set in a given table that has
+ * just been constructed.
+ *
+ * @param table The offset to the start of the table from the `ByteBuffer` capacity.
+ * @param field The offset to the field in the vtable.
+ */
public void required(int table, int field) {
int table_start = bb.capacity() - table;
int vtable_start = table_start - bb.getInt(table_start);
@@ -463,7 +659,13 @@ public class FlatBufferBuilder {
if (!ok)
throw new AssertionError("FlatBuffers: field " + field + " must be set");
}
+ /// @endcond
+ /**
+ * Finalize a buffer, pointing to the given `root_table`.
+ *
+ * @param root_table An offset to be added to the buffer.
+ */
public void finish(int root_table) {
prep(minalign, SIZEOF_INT);
addOffset(root_table);
@@ -471,6 +673,13 @@ public class FlatBufferBuilder {
finished = true;
}
+ /**
+ * Finalize a buffer, pointing to the given `root_table`.
+ *
+ * @param root_table An offset to be added to the buffer.
+ * @param file_identifier A FlatBuffer file identifier to be added to the buffer before
+ * `root_table`.
+ */
public void finish(int root_table, String file_identifier) {
prep(minalign, SIZEOF_INT + FILE_IDENTIFIER_LENGTH);
if (file_identifier.length() != FILE_IDENTIFIER_LENGTH)
@@ -487,17 +696,19 @@ public class FlatBufferBuilder {
* don't get serialized into the buffer. Forcing defaults provides a
* way to manually disable this optimization.
*
- * @param forceDefaults true always serializes default values
- * @return this
+ * @param forceDefaults When set to `true`, always serializes default values.
+ * @return Returns `this`.
*/
public FlatBufferBuilder forceDefaults(boolean forceDefaults){
this.force_defaults = forceDefaults;
return this;
}
- // Get the ByteBuffer representing the FlatBuffer. Only call this after you've
- // called finish(). The actual data starts at the ByteBuffer's current position,
- // not necessarily at 0.
+ /**
+ * Get the ByteBuffer representing the FlatBuffer. Only call this after you've
+ * called `finish()`. The actual data starts at the ByteBuffer's current position,
+ * not necessarily at `0`.
+ */
public ByteBuffer dataBuffer() {
finished();
return bb;
@@ -518,13 +729,13 @@ public class FlatBufferBuilder {
}
/**
- * Utility function for copying a byte array from {@code start} to
- * {@code start} + {@code length}
+ * A utility function to copy and return the ByteBuffer data from `start` to
+ * `start` + `length` as a `byte[]`.
*
- * @param start Start copying at this offset
- * @param length How many bytes to copy
- * @return A range copy of the {@link #dataBuffer() data buffer}
- * @throws IndexOutOfBoundsException If the range of bytes is ouf of bound
+ * @param start Start copying at this offset.
+ * @param length How many bytes to copy.
+ * @return A range copy of the {@link #dataBuffer() data buffer}.
+ * @throws IndexOutOfBoundsException If the range of bytes is ouf of bound.
*/
public byte[] sizedByteArray(int start, int length){
finished();
@@ -535,11 +746,13 @@ public class FlatBufferBuilder {
}
/**
- * Utility function for copying a byte array that starts at 0.
+ * A utility function to copy and return the ByteBuffer data as a `byte[]`.
*
- * @return A full copy of the {@link #dataBuffer() data buffer}
+ * @return A full copy of the {@link #dataBuffer() data buffer}.
*/
public byte[] sizedByteArray() {
return sizedByteArray(space, bb.capacity() - space);
}
}
+
+/// @}
diff --git a/java/com/google/flatbuffers/Struct.java b/java/com/google/flatbuffers/Struct.java
index 9e6fe4a24..ae3155314 100644
--- a/java/com/google/flatbuffers/Struct.java
+++ b/java/com/google/flatbuffers/Struct.java
@@ -18,8 +18,16 @@ package com.google.flatbuffers;
import java.nio.ByteBuffer;
-// All structs in the generated code derive from this class, and add their own accessors.
+/// @cond FLATBUFFERS_INTERNAL
+
+/**
+ * All structs in the generated code derive from this class, and add their own accessors.
+ */
public class Struct {
+ /** Used to hold the position of the `bb` buffer. */
protected int bb_pos;
+ /** The underlying ByteBuffer to hold the data of the Struct. */
protected ByteBuffer bb;
}
+
+/// @endcond
diff --git a/java/com/google/flatbuffers/Table.java b/java/com/google/flatbuffers/Table.java
index c4a93756e..3d10012a8 100644
--- a/java/com/google/flatbuffers/Table.java
+++ b/java/com/google/flatbuffers/Table.java
@@ -20,34 +20,61 @@ import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-// All tables in the generated code derive from this class, and add their own accessors.
+/// @cond FLATBUFFERS_INTERNAL
+
+/**
+ * All tables in the generated code derive from this class, and add their own accessors.
+ */
public class Table {
+ /** Used to hold the position of the `bb` buffer. */
protected int bb_pos;
+ /** The underlying ByteBuffer to hold the data of the Table. */
protected ByteBuffer bb;
+ /**
+ * Get the underlying ByteBuffer.
+ *
+ * @return Returns the Table's ByteBuffer.
+ */
public ByteBuffer getByteBuffer() { return bb; }
- // Look up a field in the vtable, return an offset into the object, or 0 if the field is not
- // present.
+ /**
+ * Look up a field in the vtable.
+ *
+ * @param vtable_offset An `int` offset to the vtable in the Table's ByteBuffer.
+ * @return Returns an offset into the object, or `0` if the field is not present.
+ */
protected int __offset(int vtable_offset) {
int vtable = bb_pos - bb.getInt(bb_pos);
return vtable_offset < bb.getShort(vtable) ? bb.getShort(vtable + vtable_offset) : 0;
}
- // Retrieve the relative offset stored at "offset"
+ /**
+ * Retrieve a relative offset.
+ *
+ * @param offset An `int` index into the Table's ByteBuffer containing the relative offset.
+ * @return Returns the relative offset stored at `offset`.
+ */
protected int __indirect(int offset) {
return offset + bb.getInt(offset);
}
- // Create a java String from UTF-8 data stored inside the flatbuffer.
- // This allocates a new string and converts to wide chars upon each access,
- // which is not very efficient. Instead, each FlatBuffer string also comes with an
- // accessor based on __vector_as_bytebuffer below, which is much more efficient,
- // assuming your Java program can handle UTF-8 data directly.
+ /**
+ * Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
+ *
+ * This allocates a new string and converts to wide chars upon each access,
+ * which is not very efficient. Instead, each FlatBuffer string also comes with an
+ * accessor based on __vector_as_bytebuffer below, which is much more efficient,
+ * assuming your Java program can handle UTF-8 data directly.
+ *
+ * @param offset An `int` index into the Table's ByteBuffer.
+ * @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
+ */
protected String __string(int offset) {
offset += bb.getInt(offset);
if (bb.hasArray()) {
- return new String(bb.array(), bb.arrayOffset() + offset + SIZEOF_INT, bb.getInt(offset), FlatBufferBuilder.utf8charset);
+ return new String(bb.array(), bb.arrayOffset() + offset + SIZEOF_INT, bb.getInt(offset),
+ FlatBufferBuilder.utf8charset);
} else {
// We can't access .array(), since the ByteBuffer is read-only,
// off-heap or a memory map
@@ -60,23 +87,36 @@ public class Table {
}
}
- // Get the length of a vector whose offset is stored at "offset" in this object.
+ /**
+ * Get the length of a vector.
+ *
+ * @param offset An `int` index into the Table's ByteBuffer.
+ * @return Returns the length of the vector whose offset is stored at `offset`.
+ */
protected int __vector_len(int offset) {
offset += bb_pos;
offset += bb.getInt(offset);
return bb.getInt(offset);
}
- // Get the start of data of a vector whose offset is stored at "offset" in this object.
+ /**
+ * Get the start data of a vector.
+ *
+ * @param offset An `int` index into the Table's ByteBuffer.
+ * @return Returns the start of the vector data whose offset is stored at `offset`.
+ */
protected int __vector(int offset) {
offset += bb_pos;
return offset + bb.getInt(offset) + SIZEOF_INT; // data starts after the length
}
- // Get a whole vector as a ByteBuffer. This is efficient, since it only allocates a new
- // bytebuffer object, but does not actually copy the data, it still refers to the same
- // bytes as the original ByteBuffer.
- // Also useful with nested FlatBuffers etc.
+ /**
+ * Get a whole vector as a ByteBuffer.
+ *
+ * This is efficient, since it only allocates a new bytebuffer object, but does not actually copy
+ * the data, it still refers to the same bytes as the original ByteBuffer. Also useful with nested
+ * FlatBuffers, etc.
+ */
protected ByteBuffer __vector_as_bytebuffer(int vector_offset, int elem_size) {
int o = __offset(vector_offset);
if (o == 0) return null;
@@ -87,7 +127,13 @@ public class Table {
return bb;
}
- // Initialize any Table-derived type to point to the union at the given offset.
+ /**
+ * Initialize any Table-derived type to point to the union at the given `offset`.
+ *
+ * @param t A `Table`-derived type that should point to the union at `offset`.
+ * @param offset An `int` index into the Table's ByteBuffer.
+ * @return Returns the Table that points to the union at `offset`.
+ */
protected Table __union(Table t, int offset) {
offset += bb_pos;
t.bb_pos = offset + bb.getInt(offset);
@@ -95,6 +141,12 @@ public class Table {
return t;
}
+ /**
+ * Check if a ByteBuffer contains a file identifier.
+ *
+ * @param bb A `ByteBuffer` to check if it contains the identifier `ident`.
+ * @param ident A `String` identifier of the flatbuffer file.
+ */
protected static boolean __has_identifier(ByteBuffer bb, String ident) {
if (ident.length() != FILE_IDENTIFIER_LENGTH)
throw new AssertionError("FlatBuffers: file identifier must be length " +
@@ -105,3 +157,5 @@ public class Table {
return true;
}
}
+
+/// @endcond
diff --git a/js/flatbuffers.js b/js/flatbuffers.js
index efa76d946..f3c483425 100644
--- a/js/flatbuffers.js
+++ b/js/flatbuffers.js
@@ -1,3 +1,7 @@
+/// @file
+/// @addtogroup flatbuffers_javascript_api
+/// @{
+/// @cond FLATBUFFERS_INTERNAL
var flatbuffers = {};
/**
@@ -105,9 +109,11 @@ flatbuffers.Long.prototype.equals = function(other) {
*/
flatbuffers.Long.ZERO = new flatbuffers.Long(0, 0);
+/// @endcond
////////////////////////////////////////////////////////////////////////////////
-
/**
+ * Create a FlatBufferBuilder.
+ *
* @constructor
* @param {number=} initial_size
*/
@@ -228,6 +234,7 @@ flatbuffers.Builder.prototype.asUint8Array = function() {
return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset());
};
+/// @cond FLATBUFFERS_INTERNAL
/**
* Prepare to write an element of `size` after `additional_bytes` have been
* written, e.g. if you write a string, you need to align such the int length
@@ -307,9 +314,11 @@ flatbuffers.Builder.prototype.writeFloat32 = function(value) {
flatbuffers.Builder.prototype.writeFloat64 = function(value) {
this.bb.writeFloat64(this.space -= 8, value);
};
+/// @endcond
/**
- * @param {number} value
+ * Add an `int8` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {number} value The `int8` to add the the buffer.
*/
flatbuffers.Builder.prototype.addInt8 = function(value) {
this.prep(1, 0);
@@ -317,7 +326,8 @@ flatbuffers.Builder.prototype.addInt8 = function(value) {
};
/**
- * @param {number} value
+ * Add an `int16` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {number} value The `int16` to add the the buffer.
*/
flatbuffers.Builder.prototype.addInt16 = function(value) {
this.prep(2, 0);
@@ -325,7 +335,8 @@ flatbuffers.Builder.prototype.addInt16 = function(value) {
};
/**
- * @param {number} value
+ * Add an `int32` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {number} value The `int32` to add the the buffer.
*/
flatbuffers.Builder.prototype.addInt32 = function(value) {
this.prep(4, 0);
@@ -333,7 +344,8 @@ flatbuffers.Builder.prototype.addInt32 = function(value) {
};
/**
- * @param {flatbuffers.Long} value
+ * Add an `int64` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {flatbuffers.Long} value The `int64` to add the the buffer.
*/
flatbuffers.Builder.prototype.addInt64 = function(value) {
this.prep(8, 0);
@@ -341,7 +353,8 @@ flatbuffers.Builder.prototype.addInt64 = function(value) {
};
/**
- * @param {number} value
+ * Add a `float32` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {number} value The `float32` to add the the buffer.
*/
flatbuffers.Builder.prototype.addFloat32 = function(value) {
this.prep(4, 0);
@@ -349,13 +362,15 @@ flatbuffers.Builder.prototype.addFloat32 = function(value) {
};
/**
- * @param {number} value
+ * Add a `float64` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {number} value The `float64` to add the the buffer.
*/
flatbuffers.Builder.prototype.addFloat64 = function(value) {
this.prep(8, 0);
this.writeFloat64(value);
};
+/// @cond FLATBUFFERS_INTERNAL
/**
* @param {number} voffset
* @param {number} value
@@ -515,17 +530,19 @@ flatbuffers.Builder.growByteBuffer = function(bb) {
nbb.bytes().set(bb.bytes(), new_buf_size - old_buf_size);
return nbb;
};
+/// @endcond
/**
* Adds on offset, relative to where it will be written.
*
- * @param {flatbuffers.Offset} offset The offset to add
+ * @param {flatbuffers.Offset} offset The offset to add.
*/
flatbuffers.Builder.prototype.addOffset = function(offset) {
this.prep(flatbuffers.SIZEOF_INT, 0); // Ensure alignment is already done.
this.writeInt32(this.offset() - offset + flatbuffers.SIZEOF_INT);
};
+/// @cond FLATBUFFERS_INTERNAL
/**
* Start encoding a new object in the buffer. Users will not usually need to
* call this directly. The FlatBuffers compiler will generate helper methods
@@ -606,8 +623,11 @@ outer_loop:
this.isNested = false;
return vtableloc;
};
+/// @endcond
/**
+ * Finalize a buffer, poiting to the given `root_table`.
+ *
* @param {flatbuffers.Offset} root_table
* @param {string=} file_identifier
*/
@@ -628,6 +648,7 @@ flatbuffers.Builder.prototype.finish = function(root_table, file_identifier) {
this.bb.setPosition(this.space);
};
+/// @cond FLATBUFFERS_INTERNAL
/**
* This checks a required field has been set in a given table that has
* just been constructed.
@@ -673,6 +694,7 @@ flatbuffers.Builder.prototype.endVector = function() {
this.writeInt32(this.vector_num_elems);
return this.offset();
};
+/// @endcond
/**
* Encode the string `s` in the buffer using UTF-8. If a Uint8Array is passed
@@ -729,10 +751,11 @@ flatbuffers.Builder.prototype.createString = function(s) {
}
return this.endVector();
};
-
////////////////////////////////////////////////////////////////////////////////
-
+/// @cond FLATBUFFERS_INTERNAL
/**
+ * Create a new ByteBuffer with a given array of bytes (`Uint8Array`).
+ *
* @constructor
* @param {Uint8Array} bytes
*/
@@ -751,6 +774,8 @@ flatbuffers.ByteBuffer = function(bytes) {
};
/**
+ * Create and allocate a new ByteBuffer with a given size.
+ *
* @param {number} byte_size
* @returns {flatbuffers.ByteBuffer}
*/
@@ -759,6 +784,8 @@ flatbuffers.ByteBuffer.allocate = function(byte_size) {
};
/**
+ * Get the underlying `Uint8Array`.
+ *
* @returns {Uint8Array}
*/
flatbuffers.ByteBuffer.prototype.bytes = function() {
@@ -766,6 +793,8 @@ flatbuffers.ByteBuffer.prototype.bytes = function() {
};
/**
+ * Get the buffer's position.
+ *
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.position = function() {
@@ -773,6 +802,8 @@ flatbuffers.ByteBuffer.prototype.position = function() {
};
/**
+ * Set the buffer's position.
+ *
* @param {number} position
*/
flatbuffers.ByteBuffer.prototype.setPosition = function(position) {
@@ -780,6 +811,8 @@ flatbuffers.ByteBuffer.prototype.setPosition = function(position) {
};
/**
+ * Get the buffer's capacity.
+ *
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.capacity = function() {
@@ -1070,3 +1103,6 @@ flatbuffers.ByteBuffer.prototype.__has_identifier = function(ident) {
// Exports for Node.js and RequireJS
this.flatbuffers = flatbuffers;
+
+/// @endcond
+/// @}
diff --git a/net/FlatBuffers/FlatBufferBuilder.cs b/net/FlatBuffers/FlatBufferBuilder.cs
index 7d2115885..1f9f9d5f3 100644
--- a/net/FlatBuffers/FlatBufferBuilder.cs
+++ b/net/FlatBuffers/FlatBufferBuilder.cs
@@ -18,12 +18,15 @@
using System;
using System.Text;
+/// @file
+/// @addtogroup flatbuffers_csharp_api
+/// @{
namespace FlatBuffers
{
///
- /// Responsible for building up and accessing a flatbuffer formatted byte
- /// array (via ByteBuffer)
+ /// Responsible for building up and accessing a FlatBuffer formatted byte
+ /// array (via ByteBuffer).
///
public class FlatBufferBuilder
{
@@ -44,6 +47,12 @@ namespace FlatBuffers
// For the current vector being built.
private int _vectorNumElems = 0;
+ ///
+ /// Create a FlatBufferBuilder with a given initial size.
+ ///
+ ///
+ /// The initial size to use for the internal buffer.
+ ///
public FlatBufferBuilder(int initialSize)
{
if (initialSize <= 0)
@@ -53,6 +62,9 @@ namespace FlatBuffers
_bb = new ByteBuffer(new byte[initialSize]);
}
+ ///
+ /// Reset the FlatBufferBuilder by purging all data that it holds.
+ ///
public void Clear()
{
_space = _bb.Length;
@@ -65,6 +77,8 @@ namespace FlatBuffers
_vectorNumElems = 0;
}
+ /// @cond FLATBUFFERS_INTERNAL
+
public int Offset { get { return _bb.Length - _space; } }
public void Pad(int size)
@@ -171,25 +185,79 @@ namespace FlatBuffers
{
_bb.PutDouble(_space -= sizeof(double), x);
}
+ /// @endcond
- // Adds a scalar to the buffer, properly aligned, and the buffer grown
- // if needed.
+ ///
+ /// Add a `bool` to the buffer (aligns the data and grows if necessary).
+ ///
+ /// The `bool` to add to the buffer.
public void AddBool(bool x) { Prep(sizeof(byte), 0); PutBool(x); }
+
+ ///
+ /// Add a `sbyte` to the buffer (aligns the data and grows if necessary).
+ ///
+ /// The `sbyte` to add to the buffer.
public void AddSbyte(sbyte x) { Prep(sizeof(sbyte), 0); PutSbyte(x); }
+
+ ///
+ /// Add a `byte` to the buffer (aligns the data and grows if necessary).
+ ///
+ /// The `byte` to add to the buffer.
public void AddByte(byte x) { Prep(sizeof(byte), 0); PutByte(x); }
+
+ ///
+ /// Add a `short` to the buffer (aligns the data and grows if necessary).
+ ///
+ /// The `short` to add to the buffer.
public void AddShort(short x) { Prep(sizeof(short), 0); PutShort(x); }
+
+ ///
+ /// Add an `ushort` to the buffer (aligns the data and grows if necessary).
+ ///
+ /// The `ushort` to add to the buffer.
public void AddUshort(ushort x) { Prep(sizeof(ushort), 0); PutUshort(x); }
+
+ ///
+ /// Add an `int` to the buffer (aligns the data and grows if necessary).
+ ///
+ /// The `int` to add to the buffer.
public void AddInt(int x) { Prep(sizeof(int), 0); PutInt(x); }
+
+ ///
+ /// Add an `uint` to the buffer (aligns the data and grows if necessary).
+ ///
+ /// The `uint` to add to the buffer.
public void AddUint(uint x) { Prep(sizeof(uint), 0); PutUint(x); }
+
+ ///
+ /// Add a `long` to the buffer (aligns the data and grows if necessary).
+ ///
+ /// The `long` to add to the buffer.
public void AddLong(long x) { Prep(sizeof(long), 0); PutLong(x); }
+
+ ///
+ /// Add an `ulong` to the buffer (aligns the data and grows if necessary).
+ ///
+ /// The `ulong` to add to the buffer.
public void AddUlong(ulong x) { Prep(sizeof(ulong), 0); PutUlong(x); }
+
+ ///
+ /// Add a `float` to the buffer (aligns the data and grows if necessary).
+ ///
+ /// The `float` to add to the buffer.
public void AddFloat(float x) { Prep(sizeof(float), 0); PutFloat(x); }
+
+ ///
+ /// Add a `double` to the buffer (aligns the data and grows if necessary).
+ ///
+ /// The `double` to add to the buffer.
public void AddDouble(double x) { Prep(sizeof(double), 0);
PutDouble(x); }
-
-
- // Adds on offset, relative to where it will be written.
+ ///
+ /// Adds an offset, relative to where it will be written.
+ ///
+ /// The offset to add to the buffer.
public void AddOffset(int off)
{
Prep(sizeof(int), 0); // Ensure alignment is already done.
@@ -200,6 +268,7 @@ namespace FlatBuffers
PutInt(off);
}
+ /// @cond FLATBUFFERS_INTERNAL
public void StartVector(int elemSize, int count, int alignment)
{
NotNested();
@@ -207,13 +276,18 @@ namespace FlatBuffers
Prep(sizeof(int), elemSize * count);
Prep(alignment, elemSize * count); // Just in case alignment > int.
}
+ /// @endcond
+ ///
+ /// Writes data necessary to finish a vector construction.
+ ///
public VectorOffset EndVector()
{
PutInt(_vectorNumElems);
return new VectorOffset(Offset);
}
+ /// @cond FLATBUFFERS_INTENRAL
public void Nested(int obj)
{
// Structs are always stored inline, so need to be created right
@@ -271,10 +345,18 @@ namespace FlatBuffers
public void AddFloat(int o, float x, double d) { if (x != d) { AddFloat(x); Slot(o); } }
public void AddDouble(int o, double x, double d) { if (x != d) { AddDouble(x); Slot(o); } }
public void AddOffset(int o, int x, int d) { if (x != d) { AddOffset(x); Slot(o); } }
+ /// @endcond
+ ///
+ /// Encode the string `s` in the buffer using UTF-8.
+ ///
+ /// The string to encode.
+ ///
+ /// The offset in the buffer where the encoded string starts.
+ ///
public StringOffset CreateString(string s)
{
- NotNested();
+ NotNested();
AddByte(0);
var utf8StringLen = Encoding.UTF8.GetByteCount(s);
StartVector(1, utf8StringLen, 1);
@@ -282,6 +364,7 @@ namespace FlatBuffers
return new StringOffset(EndVector().Value);
}
+ /// @cond FLATBUFFERS_INTERNAL
// Structs are stored inline, so nothing additional is being added.
// `d` is always 0.
public void AddStruct(int voffset, int x, int d)
@@ -376,7 +459,14 @@ namespace FlatBuffers
throw new InvalidOperationException("FlatBuffers: field " + field +
" must be set");
}
+ /// @endcond
+ ///
+ /// Finalize a buffer, pointing to the given `root_table`.
+ ///
+ ///
+ /// An offset to be added to the buffer.
+ ///
public void Finish(int rootTable)
{
Prep(_minAlign, sizeof(int));
@@ -384,9 +474,24 @@ namespace FlatBuffers
_bb.Position = _space;
}
+ ///
+ /// Get the ByteBuffer representing the FlatBuffer.
+ ///
+ ///
+ /// This is typically only called after you call `Finish()`.
+ ///
+ ///
+ /// Returns the ByteBuffer for this FlatBuffer.
+ ///
public ByteBuffer DataBuffer { get { return _bb; } }
- // Utility function for copying a byte array that starts at 0.
+ ///
+ /// A utility function to copy and return the ByteBuffer data as a
+ /// `byte[]`.
+ ///
+ ///
+ /// A full copy of the FlatBuffer data.
+ ///
public byte[] SizedByteArray()
{
var newArray = new byte[_bb.Data.Length - _bb.Position];
@@ -395,6 +500,16 @@ namespace FlatBuffers
return newArray;
}
+ ///
+ /// Finalize a buffer, pointing to the given `rootTable`.
+ ///
+ ///
+ /// An offset to be added to the buffer.
+ ///
+ ///
+ /// A FlatBuffer file identifier to be added to the buffer before
+ /// `root_table`.
+ ///
public void Finish(int rootTable, string fileIdentifier)
{
Prep(_minAlign, sizeof(int) +
@@ -416,3 +531,5 @@ namespace FlatBuffers
}
}
+
+/// @}
diff --git a/php/FlatbufferBuilder.php b/php/FlatbufferBuilder.php
index b72a6d653..3738582e2 100644
--- a/php/FlatbufferBuilder.php
+++ b/php/FlatbufferBuilder.php
@@ -15,15 +15,21 @@
* limitations under the License.
*/
+/// @file
+/// @addtogroup flatbuffers_php_api
+/// @{
+
namespace Google\FlatBuffers;
class FlatbufferBuilder
{
/**
+ * Internal ByteBuffer for the FlatBuffer data.
* @var ByteBuffer $bb
*/
public $bb;
+ /// @cond FLATBUFFERS_INTERNAL
/**
* @var int $space
*/
@@ -73,9 +79,10 @@ class FlatbufferBuilder
* @var bool $force_defaults
*/
protected $force_defaults = false;
+ /// @endcond
/**
- * create flatbuffers builder
+ * Create a FlatBufferBuilder with a given initial size.
*
* @param $initial_size initial byte buffer size.
*/
@@ -88,6 +95,7 @@ class FlatbufferBuilder
$this->bb = $this->newByteBuffer($initial_size);
}
+ /// @cond FLATBUFFERS_INTERNAL
/**
* create new bytebuffer
*
@@ -100,7 +108,7 @@ class FlatbufferBuilder
}
/**
- * returns current bytebuffer offset
+ * Returns the current ByteBuffer offset.
*
* @return int
*/
@@ -270,9 +278,11 @@ class FlatbufferBuilder
{
$this->bb->putDouble($this->space -= 8, $x);
}
+ /// @endcond
/**
- * @param $x
+ * Add a `bool` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param $x The `bool` to add to the buffer.
*/
public function addBool($x)
{
@@ -281,7 +291,8 @@ class FlatbufferBuilder
}
/**
- * @param $x
+ * Add a `byte` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param $x The `byte` to add to the buffer.
*/
public function addByte($x)
{
@@ -290,7 +301,8 @@ class FlatbufferBuilder
}
/**
- * @param $x
+ * Add a `signed byte` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param $x The `signed byte` to add to the buffer.
*/
public function addSbyte($x)
{
@@ -299,7 +311,8 @@ class FlatbufferBuilder
}
/**
- * @param $x
+ * Add a `short` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param $x The `short` to add to the buffer.
*/
public function addShort($x)
{
@@ -308,7 +321,8 @@ class FlatbufferBuilder
}
/**
- * @param $x
+ * Add an `unsigned short` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param $x The `unsigned short` to add to the buffer.
*/
public function addUshort($x)
{
@@ -317,7 +331,8 @@ class FlatbufferBuilder
}
/**
- * @param $x
+ * Add an `int` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param $x The `int` to add to the buffer.
*/
public function addInt($x)
{
@@ -326,7 +341,8 @@ class FlatbufferBuilder
}
/**
- * @param $x
+ * Add an `unsigned int` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param $x The `unsigned int` to add to the buffer.
*/
public function addUint($x)
{
@@ -334,9 +350,9 @@ class FlatbufferBuilder
$this->putUint($x);
}
-
/**
- * @param $x
+ * Add a `long` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param $x The `long` to add to the buffer.
*/
public function addLong($x)
{
@@ -345,7 +361,8 @@ class FlatbufferBuilder
}
/**
- * @param $x
+ * Add an `unsigned long` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param $x The `unsigned long` to add to the buffer.
*/
public function addUlong($x)
{
@@ -354,7 +371,8 @@ class FlatbufferBuilder
}
/**
- * @param $x
+ * Add a `float` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param $x The `float` to add to the buffer.
*/
public function addFloat($x)
{
@@ -363,7 +381,8 @@ class FlatbufferBuilder
}
/**
- * @param $x
+ * Add a `double` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param $x The `double` to add to the buffer.
*/
public function addDouble($x)
{
@@ -371,6 +390,7 @@ class FlatbufferBuilder
$this->putDouble($x);
}
+ /// @cond FLATBUFFERS_INTERNAL
/**
* @param $o
* @param $x
@@ -528,10 +548,13 @@ class FlatbufferBuilder
$this->slot($o);
}
}
+ /// @endcond
/**
- * @param $off
- * @throws \Exception
+ * Adds on offset, relative to where it will be written.
+ * @param $off The offset to add to the buffer.
+ * @throws \Exception Throws an exception if `$off` is greater than the underlying ByteBuffer's
+ * offest.
*/
public function addOffset($off)
{
@@ -544,6 +567,7 @@ class FlatbufferBuilder
$this->putInt($off);
}
+ /// @cond FLATBUFFERS_INTERNAL
/**
* @param $elem_size
* @param $num_elems
@@ -668,12 +692,14 @@ class FlatbufferBuilder
return true;
}
-
+ /// @endcond
/**
- * @param $s
- * @return int
- * @throws \Exception
+ * Encode the string `$s` in the buffer using UTF-8.
+ * @param string $s The string to encode.
+ * @return int The offset in the buffer where the encoded string starts.
+ * @throws InvalidArgumentException Thrown if the input string `$s` is not
+ * UTF-8.
*/
public function createString($s)
{
@@ -691,6 +717,7 @@ class FlatbufferBuilder
return $this->endVector();
}
+ /// @cond FLATBUFFERS_INTERNAL
/**
* @throws \Exception
*/
@@ -850,10 +877,16 @@ class FlatbufferBuilder
throw new \Exception("FlatBuffers: field " . $field . " must be set");
}
}
+ /// @endcond
/**
- * @param $root_table
- * @throws \Exception
+ * Finalize a buffer, pointing to the given `$root_table`.
+ * @param $root_table An offest to be added to the buffer.
+ * @param $file_identifier A FlatBuffer file identifier to be added to the
+ * buffer before `$root_table`. This defaults to `null`.
+ * @throws InvalidArgumentException Thrown if an invalid `$identifier` is
+ * given, where its length is not equal to
+ * `Constants::FILE_IDENTIFIER_LENGTH`.
*/
public function finish($root_table, $identifier = null)
{
@@ -878,7 +911,10 @@ class FlatbufferBuilder
}
/**
- * @param bool $forceDefaults
+ * In order to save space, fields that are set to their default value don't
+ * get serialized into the buffer.
+ * @param bool $forceDefaults When set to `true`, always serializes default
+ * values.
*/
public function forceDefaults($forceDefaults)
{
@@ -886,13 +922,15 @@ class FlatbufferBuilder
}
/**
- * @return ByteBuffer
+ * Get the ByteBuffer representing the FlatBuffer.
+ * @return ByteBuffer The ByteBuffer containing the FlatBuffer data.
*/
public function dataBuffer()
{
return $this->bb;
}
+ /// @cond FLATBUFFERS_INTERNAL
/**
* @return int
*/
@@ -900,9 +938,13 @@ class FlatbufferBuilder
{
return $this->space;
}
+ /// @endcond
/**
- * @return string
+ * Utility function to copy and return the FlatBuffer data from the
+ * underlying ByteBuffer.
+ * @return string A string (representing a byte[]) that contains a copy
+ * of the FlatBuffer data.
*/
public function sizedByteArray()
{
@@ -916,3 +958,5 @@ class FlatbufferBuilder
return $result;
}
}
+
+/// @}
diff --git a/python/flatbuffers/builder.py b/python/flatbuffers/builder.py
index 6e3465913..7d4222e18 100644
--- a/python/flatbuffers/builder.py
+++ b/python/flatbuffers/builder.py
@@ -23,6 +23,11 @@ from .compat import range_func
from .compat import memoryview_type
+## @file
+## @addtogroup flatbuffers_python_api
+## @{
+
+## @cond FLATBUFFERS_INTERNAL
class OffsetArithmeticError(RuntimeError):
"""
Error caused by an Offset arithmetic error. Probably caused by bad
@@ -72,12 +77,13 @@ class BuilderNotFinishedError(RuntimeError):
# VtableMetadataFields is the count of metadata fields in each vtable.
VtableMetadataFields = 2
-
+## @endcond
class Builder(object):
- """
- A Builder is used to construct one or more FlatBuffers. Typically, Builder
- objects will be used from code generated by the `flatc` compiler.
+ """ A Builder is used to construct one or more FlatBuffers.
+
+ Typically, Builder objects will be used from code generated by the `flatc`
+ compiler.
A Builder constructs byte buffers in a last-first manner for simplicity and
performance during reading.
@@ -85,24 +91,30 @@ class Builder(object):
Internally, a Builder is a state machine for creating FlatBuffer objects.
It holds the following internal state:
- Bytes: an array of bytes.
- current_vtable: a list of integers.
- vtables: a list of vtable entries (i.e. a list of list of integers).
+ - Bytes: an array of bytes.
+ - current_vtable: a list of integers.
+ - vtables: a list of vtable entries (i.e. a list of list of integers).
+
+ Attributes:
+ Bytes: The internal `bytearray` for the Builder.
+ finished: A boolean determining if the Builder has been finalized.
"""
+ ## @cond FLATBUFFERS_INTENRAL
__slots__ = ("Bytes", "current_vtable", "head", "minalign", "objectEnd",
"vtables", "nested", "finished")
- """
- Maximum buffer size constant, in bytes.
+ """Maximum buffer size constant, in bytes.
+
Builder will never allow it's buffer grow over this size.
Currently equals 2Gb.
"""
MAX_BUFFER_SIZE = 2**31
+ ## @endcond
def __init__(self, initialSize):
- """
- Initializes a Builder of size `initial_size`.
+ """Initializes a Builder of size `initial_size`.
+
The internal buffer is grown as needed.
"""
@@ -111,19 +123,27 @@ class Builder(object):
raise BuilderSizeError(msg)
self.Bytes = bytearray(initialSize)
+ ## @cond FLATBUFFERS_INTERNAL
self.current_vtable = None
self.head = UOffsetTFlags.py_type(initialSize)
self.minalign = 1
self.objectEnd = None
self.vtables = []
self.nested = False
+ ## @endcond
self.finished = False
+
def Output(self):
- """
- Output returns the portion of the buffer that has been used for
- writing data. It raises BuilderNotFinishedError if the buffer has not
- been finished with `Finish`.
+ """Return the portion of the buffer that has been used for writing data.
+
+ This is the typical way to access the FlatBuffer data inside the
+ builder. If you try to access `Builder.Bytes` directly, you would need
+ to manually index it with `Head()`, since the buffer is constructed
+ backwards.
+
+ It raises BuilderNotFinishedError if the buffer has not been finished
+ with `Finish`.
"""
if not self.finished:
@@ -131,6 +151,7 @@ class Builder(object):
return self.Bytes[self.Head():]
+ ## @cond FLATBUFFERS_INTERNAL
def StartObject(self, numfields):
"""StartObject initializes bookkeeping for writing a new object."""
@@ -266,14 +287,19 @@ class Builder(object):
bytes2 = bytearray(newSize)
bytes2[newSize-len(self.Bytes):] = self.Bytes
self.Bytes = bytes2
+ ## @endcond
def Head(self):
- """
- Head gives the start of useful data in the underlying byte buffer.
- Note: unlike other functions, this value is interpreted as from the left.
- """
- return self.head
+ """Get the start of useful data in the underlying byte buffer.
+ Note: unlike other functions, this value is interpreted as from the
+ left.
+ """
+ ## @cond FLATBUFFERS_INTERNAL
+ return self.head
+ ## @endcond
+
+ ## @cond FLATBUFFERS_INTERNAL
def Offset(self):
"""Offset relative to the end of the buffer."""
return UOffsetTFlags.py_type(len(self.Bytes) - self.Head())
@@ -322,10 +348,10 @@ class Builder(object):
raise OffsetArithmeticError(msg)
off2 = self.Offset() - off + N.SOffsetTFlags.bytewidth
self.PlaceSOffsetT(off2)
+ ## @endcond
def PrependUOffsetTRelative(self, off):
- """
- PrependUOffsetTRelative prepends an UOffsetT, relative to where it
+ """Prepends an unsigned offset into vector data, relative to where it
will be written.
"""
@@ -337,13 +363,14 @@ class Builder(object):
off2 = self.Offset() - off + N.UOffsetTFlags.bytewidth
self.PlaceUOffsetT(off2)
+ ## @cond FLATBUFFERS_INTERNAL
def StartVector(self, elemSize, numElems, alignment):
"""
StartVector initializes bookkeeping for writing a new vector.
A vector has the following format:
-
- +, where T is the type of elements of this vector.
+ -
+ - +, where T is the type of elements of this vector.
"""
self.assertNotNested()
@@ -351,12 +378,15 @@ class Builder(object):
self.Prep(N.Uint32Flags.bytewidth, elemSize*numElems)
self.Prep(alignment, elemSize*numElems) # In case alignment > int.
return self.Offset()
+ ## @endcond
def EndVector(self, vectorNumElems):
"""EndVector writes data necessary to finish vector construction."""
self.assertNested()
+ ## @cond FLATBUFFERS_INTERNAL
self.nested = False
+ ## @endcond
# we already made space for this, so write without PrependUint32
self.PlaceUOffsetT(vectorNumElems)
return self.Offset()
@@ -365,7 +395,9 @@ class Builder(object):
"""CreateString writes a null-terminated byte string as a vector."""
self.assertNotNested()
+ ## @cond FLATBUFFERS_INTERNAL
self.nested = True
+ ## @endcond
if isinstance(s, compat.string_types):
x = s.encode()
@@ -378,12 +410,14 @@ class Builder(object):
self.Place(0, N.Uint8Flags)
l = UOffsetTFlags.py_type(len(s))
-
+ ## @cond FLATBUFFERS_INTERNAL
self.head = UOffsetTFlags.py_type(self.Head() - l)
+ ## @endcond
self.Bytes[self.Head():self.Head()+l] = x
return self.EndVector(len(x))
+ ## @cond FLATBUFFERS_INTERNAL
def assertNested(self):
"""
Check that we are in the process of building an object.
@@ -422,6 +456,7 @@ class Builder(object):
"""
self.assertNested()
self.current_vtable[slotnum] = self.Offset()
+ ## @endcond
def Finish(self, rootTable):
"""Finish finalizes a buffer, pointing to the given `rootTable`."""
@@ -431,6 +466,7 @@ class Builder(object):
self.finished = True
return self.Head()
+ ## @cond FLATBUFFERS_INTERNAL
def Prepend(self, flags, off):
self.Prep(flags.bytewidth, 0)
self.Place(off, flags)
@@ -491,30 +527,95 @@ class Builder(object):
self.assertStructIsInline(x)
self.Slot(v)
- def PrependBool(self, x): self.Prepend(N.BoolFlags, x)
+ ## @endcond
- def PrependByte(self, x): self.Prepend(N.Uint8Flags, x)
+ def PrependBool(self, x):
+ """Prepend a `bool` to the Builder buffer.
- def PrependUint8(self, x): self.Prepend(N.Uint8Flags, x)
+ Note: aligns and checks for space.
+ """
+ self.Prepend(N.BoolFlags, x)
- def PrependUint16(self, x): self.Prepend(N.Uint16Flags, x)
+ def PrependByte(self, x):
+ """Prepend a `byte` to the Builder buffer.
- def PrependUint32(self, x): self.Prepend(N.Uint32Flags, x)
+ Note: aligns and checks for space.
+ """
+ self.Prepend(N.Uint8Flags, x)
- def PrependUint64(self, x): self.Prepend(N.Uint64Flags, x)
+ def PrependUint8(self, x):
+ """Prepend an `uint8` to the Builder buffer.
- def PrependInt8(self, x): self.Prepend(N.Int8Flags, x)
+ Note: aligns and checks for space.
+ """
+ self.Prepend(N.Uint8Flags, x)
- def PrependInt16(self, x): self.Prepend(N.Int16Flags, x)
+ def PrependUint16(self, x):
+ """Prepend an `uint16` to the Builder buffer.
- def PrependInt32(self, x): self.Prepend(N.Int32Flags, x)
+ Note: aligns and checks for space.
+ """
+ self.Prepend(N.Uint16Flags, x)
- def PrependInt64(self, x): self.Prepend(N.Int64Flags, x)
+ def PrependUint32(self, x):
+ """Prepend an `uint32` to the Builder buffer.
- def PrependFloat32(self, x): self.Prepend(N.Float32Flags, x)
+ Note: aligns and checks for space.
+ """
+ self.Prepend(N.Uint32Flags, x)
- def PrependFloat64(self, x): self.Prepend(N.Float64Flags, x)
+ def PrependUint64(self, x):
+ """Prepend an `uint64` to the Builder buffer.
+ Note: aligns and checks for space.
+ """
+ self.Prepend(N.Uint64Flags, x)
+
+ def PrependInt8(self, x):
+ """Prepend an `int8` to the Builder buffer.
+
+ Note: aligns and checks for space.
+ """
+ self.Prepend(N.Int8Flags, x)
+
+ def PrependInt16(self, x):
+ """Prepend an `int16` to the Builder buffer.
+
+ Note: aligns and checks for space.
+ """
+ self.Prepend(N.Int16Flags, x)
+
+ def PrependInt32(self, x):
+ """Prepend an `int32` to the Builder buffer.
+
+ Note: aligns and checks for space.
+ """
+ self.Prepend(N.Int32Flags, x)
+
+ def PrependInt64(self, x):
+ """Prepend an `int64` to the Builder buffer.
+
+ Note: aligns and checks for space.
+ """
+ self.Prepend(N.Int64Flags, x)
+
+ def PrependFloat32(self, x):
+ """Prepend a `float32` to the Builder buffer.
+
+ Note: aligns and checks for space.
+ """
+ self.Prepend(N.Float32Flags, x)
+
+ def PrependFloat64(self, x):
+ """Prepend a `float64` to the Builder buffer.
+
+ Note: aligns and checks for space.
+ """
+ self.Prepend(N.Float64Flags, x)
+
+##############################################################
+
+ ## @cond FLATBUFFERS_INTERNAL
def PrependVOffsetT(self, x): self.Prepend(N.VOffsetTFlags, x)
def Place(self, x, flags):
@@ -528,33 +629,31 @@ class Builder(object):
encode.Write(flags.packer_type, self.Bytes, self.Head(), x)
def PlaceVOffsetT(self, x):
- """
- PlaceVOffsetT prepends a VOffsetT to the Builder, without checking for
- space.
+ """PlaceVOffsetT prepends a VOffsetT to the Builder, without checking
+ for space.
"""
N.enforce_number(x, N.VOffsetTFlags)
self.head = self.head - N.VOffsetTFlags.bytewidth
encode.Write(packer.voffset, self.Bytes, self.Head(), x)
def PlaceSOffsetT(self, x):
- """
- PlaceSOffsetT prepends a SOffsetT to the Builder, without checking for
- space.
+ """PlaceSOffsetT prepends a SOffsetT to the Builder, without checking
+ for space.
"""
N.enforce_number(x, N.SOffsetTFlags)
self.head = self.head - N.SOffsetTFlags.bytewidth
encode.Write(packer.soffset, self.Bytes, self.Head(), x)
def PlaceUOffsetT(self, x):
- """
- PlaceUOffsetT prepends a UOffsetT to the Builder, without checking for
- space.
+ """PlaceUOffsetT prepends a UOffsetT to the Builder, without checking
+ for space.
"""
N.enforce_number(x, N.UOffsetTFlags)
self.head = self.head - N.UOffsetTFlags.bytewidth
encode.Write(packer.uoffset, self.Bytes, self.Head(), x)
+ ## @endcond
-
+## @cond FLATBUFFERS_INTERNAL
def vtableEqual(a, objectStart, b):
"""vtableEqual compares an unwritten vtable to a written vtable."""
@@ -574,3 +673,5 @@ def vtableEqual(a, objectStart, b):
if x != y:
return False
return True
+## @endcond
+## @}
diff --git a/readme.md b/readme.md
index 9a4bd5598..eb3b565cd 100755
--- a/readme.md
+++ b/readme.md
@@ -1,4 +1,4 @@
-FlatBuffers Version 1.1.0
+FlatBuffers Version 1.2.0
# Welcome to FlatBuffers!
@@ -20,6 +20,8 @@ Discuss FlatBuffers with other developers and users on the
[FlatBuffers Google Group][]. File issues on the [FlatBuffers Issues Tracker][]
or post your questions to [stackoverflow.com][] using the [`flatbuffers` tag][].
+To contribute to this project, see [CONTRIBUTING][].
+
For applications on Google Play that integrate this tool, usage is tracked.
This tracking is done automatically using the embedded version string
(flatbuffer_version_string), and helps us continue to optimize it. Aside from
@@ -29,8 +31,11 @@ is useful and if we should continue to invest in it. Since this is open
source, you are free to remove the version string but we would appreciate if
you would leave it in.
- [FlatBuffers Google Group]: http://group.google.com/group/flatbuffers
- [FlatBuffers Issues Tracker]: http://github.com/google/flatbuffers/issues
- [stackoverflow.com]: http://www.stackoverflow.com
- [landing page]: http://google.github.io/flatbuffers
- [`flatbuffers` tag]: https://stackoverflow.com/questions/tagged/flatbuffers
+
+
+ [CONTRIBUTING]: http://github.com/google/flatbuffers/blob/master/CONTRIBUTING
+ [`flatbuffers` tag]: https://stackoverflow.com/questions/tagged/flatbuffers
+ [FlatBuffers Google Group]: http://group.google.com/group/flatbuffers
+ [FlatBuffers Issues Tracker]: http://github.com/google/flatbuffers/issues
+ [stackoverflow.com]: http://www.stackoverflow.com
+ [landing page]: http://google.github.io/flatbuffers
diff --git a/samples/SampleBinary.cs b/samples/SampleBinary.cs
new file mode 100644
index 000000000..16128c4f6
--- /dev/null
+++ b/samples/SampleBinary.cs
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2015 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// To run, use the `csharp_sample.sh` script.
+
+using System;
+using FlatBuffers;
+using MyGame.Sample;
+
+class SampleBinary
+{
+ // Example how to use FlatBuffers to create and read binary buffers.
+ static void Main()
+ {
+ var builder = new FlatBufferBuilder(1);
+
+ // Create some weapons for our Monster ('Sword' and 'Axe').
+ var weapon1Name = builder.CreateString("Sword");
+ var weapon1Damage = 3;
+ var weapon2Name = builder.CreateString("Axe");
+ var weapon2Damage = 5;
+
+ // Use the `CreateWeapon()` helper function to create the weapons, since we set every field.
+ var weaps = new Offset[2];
+ weaps[0] = Weapon.CreateWeapon(builder, weapon1Name, (short)weapon1Damage);
+ weaps[1] = Weapon.CreateWeapon(builder, weapon2Name, (short)weapon2Damage);
+
+ // Serialize the FlatBuffer data.
+ var name = builder.CreateString("Orc");
+ var treasure = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ var inv = Monster.CreateInventoryVector(builder, treasure);
+ var weapons = Monster.CreateWeaponsVector(builder, weaps);
+ var pos = Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f);
+
+ Monster.StartMonster(builder);
+ Monster.AddPos(builder, pos);
+ Monster.AddHp(builder, (short)300);
+ Monster.AddName(builder, name);
+ Monster.AddInventory(builder, inv);
+ Monster.AddColor(builder, Color.Red);
+ Monster.AddWeapons(builder, weapons);
+ Monster.AddEquippedType(builder, Equipment.Weapon);
+ Monster.AddEquipped(builder, weaps[1].Value);
+ var orc = Monster.EndMonster(builder);
+
+ builder.Finish(orc.Value); // You could also call `Monster.FinishMonsterBuffer(builder, orc);`.
+
+ // We now have a FlatBuffer that we could store on disk or send over a network.
+
+ // ...Code to store to disk or send over a network goes here...
+
+ // Instead, we are going to access it right away, as if we just received it.
+
+ var buf = builder.DataBuffer;
+
+ // Get access to the root:
+ var monster = Monster.GetRootAsMonster(buf);
+
+ // For C#, unlike other languages, most values (except for vectors and unions) are available as
+ // properties instead of accessor methods.
+
+ // Note: We did not set the `Mana` field explicitly, so we get back the default value.
+ Assert(monster.Mana == 150, "monster.Mana", Convert.ToString(monster.Mana),
+ Convert.ToString(150));
+ Assert(monster.Hp == 300, "monster.Hp", Convert.ToString(monster.Hp), Convert.ToString(30));
+ Assert(monster.Name.Equals("Orc", StringComparison.Ordinal), "monster.Name", monster.Name,
+ "Orc");
+ Assert(monster.Color == Color.Red, "monster.Color", Convert.ToString(monster.Color),
+ Convert.ToString(Color.Red));
+
+ // C# also allows you to use performance-enhanced methods to fill an object that has already
+ // been created. These functions are prefixed with "Get". For example: `monster.GetPos()`.
+ var myAlreadyCreatedVector = new Vec3();
+ monster.GetPos(myAlreadyCreatedVector); // Instead of `var myNewVec3 = monster.Pos`.
+ Assert(myAlreadyCreatedVector.X == 1.0f, "myAlreadyCreatedVector.X",
+ Convert.ToString(myAlreadyCreatedVector.X), Convert.ToString(1.0f));
+ Assert(myAlreadyCreatedVector.Y == 2.0f, "myAlreadyCreatedVector.Y",
+ Convert.ToString(myAlreadyCreatedVector.Y), Convert.ToString(2.0f));
+ Assert(myAlreadyCreatedVector.Z == 3.0f, "myAlreadyCreatedVector.Z",
+ Convert.ToString(myAlreadyCreatedVector.Z), Convert.ToString(3.0f));
+
+ // Get and test the `Inventory` FlatBuffer `vector`.
+ for (int i = 0; i < monster.InventoryLength; i++)
+ {
+ Assert(monster.GetInventory(i) == i, "monster.GetInventory",
+ Convert.ToString(monster.GetInventory(i)), Convert.ToString(i));
+ }
+
+ // Get and test the `Weapons` FlatBuffer `vector` of `table`s.
+ var expectedWeaponNames = new string[] {"Sword", "Axe"};
+ var expectedWeaponDamages = new short[] {3, 5};
+ for (int i = 0; i < monster.WeaponsLength; i++)
+ {
+ Assert(monster.GetWeapons(i).Name.Equals(expectedWeaponNames[i], StringComparison.Ordinal),
+ "monster.GetWeapons", monster.GetWeapons(i).Name, expectedWeaponNames[i]);
+ Assert(monster.GetWeapons(i).Damage == expectedWeaponDamages[i], "monster.GetWeapons",
+ Convert.ToString(monster.GetWeapons(i).Damage),
+ Convert.ToString(expectedWeaponDamages[i]));
+ }
+
+ // Get and test the `Equipped` FlatBuffer `union`.
+ Assert(monster.EquippedType == Equipment.Weapon, "monster.EquippedType",
+ Convert.ToString(monster.EquippedType), Convert.ToString(Equipment.Weapon));
+ var equipped = (Weapon)monster.GetEquipped(new Weapon());
+ Assert(equipped.Name.Equals("Axe", StringComparison.Ordinal), "equipped.Name", equipped.Name,
+ "Axe");
+ Assert(equipped.Damage == 5, "equipped.Damage", Convert.ToString(equipped.Damage),
+ Convert.ToString(5));
+
+ Console.WriteLine("The FlatBuffer was successfully created and verified!");
+ }
+
+ // A helper function to handle assertions.
+ static void Assert(bool assertPassed, string codeExecuted, string actualValue,
+ string expectedValue)
+ {
+ if (assertPassed == false)
+ {
+ Console.WriteLine("Assert failed! " + codeExecuted + " (" + actualValue +
+ ") was not equal to " + expectedValue + ".");
+ System.Environment.Exit(1);
+ }
+ }
+}
diff --git a/samples/SampleBinary.java b/samples/SampleBinary.java
new file mode 100644
index 000000000..555194f31
--- /dev/null
+++ b/samples/SampleBinary.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2015 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Run this file with the `java_sample.sh` script.
+
+import MyGame.Sample.Color;
+import MyGame.Sample.Equipment;
+import MyGame.Sample.Monster;
+import MyGame.Sample.Vec3;
+import MyGame.Sample.Weapon;
+
+import com.google.flatbuffers.FlatBufferBuilder;
+
+import java.nio.ByteBuffer;
+
+class SampleBinary {
+ // Example how to use FlatBuffers to create and read binary buffers.
+ public static void main(String[] args) {
+ FlatBufferBuilder builder = new FlatBufferBuilder(0);
+
+ // Create some weapons for our Monster ('Sword' and 'Axe').
+ int weaponOneName = builder.createString("Sword");
+ short weaponOneDamage = 3;
+ int weaponTwoName = builder.createString("Axe");
+ short weaponTwoDamage = 5;
+
+ // Use the `createWeapon()` helper function to create the weapons, since we set every field.
+ int[] weaps = new int[2];
+ weaps[0] = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage);
+ weaps[1] = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage);
+
+ // Serialize the FlatBuffer data.
+ int name = builder.createString("Orc");
+ byte[] treasure = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ int inv = Monster.createInventoryVector(builder, treasure);
+ int weapons = Monster.createWeaponsVector(builder, weaps);
+ int pos = Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f);
+
+ Monster.startMonster(builder);
+ Monster.addPos(builder, pos);
+ Monster.addName(builder, name);
+ Monster.addColor(builder, Color.Red);
+ Monster.addHp(builder, (short)300);
+ Monster.addInventory(builder, inv);
+ Monster.addWeapons(builder, weapons);
+ Monster.addEquippedType(builder, Equipment.Weapon);
+ Monster.addEquipped(builder, weaps[1]);
+ int orc = Monster.endMonster(builder);
+
+ builder.finish(orc); // You could also call `Monster.finishMonsterBuffer(builder, orc);`.
+
+ // We now have a FlatBuffer that can be stored on disk or sent over a network.
+
+ // ...Code to store to disk or send over a network goes here...
+
+ // Instead, we are going to access it right away, as if we just received it.
+
+ ByteBuffer buf = builder.dataBuffer();
+
+ // Get access to the root:
+ Monster monster = Monster.getRootAsMonster(buf);
+
+ // Note: We did not set the `mana` field explicitly, so we get back the default value.
+ assert monster.mana() == (short)150;
+ assert monster.hp() == (short)300;
+ assert monster.name().equals("Orc");
+ assert monster.color() == Color.Red;
+ assert monster.pos().x() == 1.0f;
+ assert monster.pos().y() == 2.0f;
+ assert monster.pos().z() == 3.0f;
+
+ // Get and test the `inventory` FlatBuffer `vector`.
+ for (int i = 0; i < monster.inventoryLength(); i++) {
+ assert monster.inventory(i) == (byte)i;
+ }
+
+ // Get and test the `weapons` FlatBuffer `vector` of `table`s.
+ String[] expectedWeaponNames = {"Sword", "Axe"};
+ int[] expectedWeaponDamages = {3, 5};
+ for (int i = 0; i < monster.weaponsLength(); i++) {
+ assert monster.weapons(i).name().equals(expectedWeaponNames[i]);
+ assert monster.weapons(i).damage() == expectedWeaponDamages[i];
+ }
+
+ // Get and test the `equipped` FlatBuffer `union`.
+ assert monster.equippedType() == Equipment.Weapon;
+ Weapon equipped = (Weapon)monster.equipped(new Weapon());
+ assert equipped.name().equals("Axe");
+ assert equipped.damage() == 5;
+
+ System.out.println("The FlatBuffer was successfully created and verified!");
+ }
+}
diff --git a/samples/SampleBinary.php b/samples/SampleBinary.php
new file mode 100644
index 000000000..d28ffa333
--- /dev/null
+++ b/samples/SampleBinary.php
@@ -0,0 +1,115 @@
+createString("Sword");
+ $sword = \MyGame\Sample\Weapon::CreateWeapon($builder, $weapon_one, 3);
+ $weapon_two = $builder->createString("Axe");
+ $axe = \MyGame\Sample\Weapon::CreateWeapon($builder, $weapon_two, 5);
+
+ // Serialize the FlatBuffer data.
+ $name = $builder->createString("Orc");
+
+ $treasure = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ $inv = \MyGame\Sample\Monster::CreateInventoryVector($builder, $treasure);
+
+ $weaps = array($sword, $axe);
+ $weapons = \MyGame\Sample\Monster::CreateWeaponsVector($builder, $weaps);
+
+ $pos = \MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0);
+
+ \MyGame\Sample\Monster::StartMonster($builder);
+ \MyGame\Sample\Monster::AddPos($builder, $pos);
+ \MyGame\Sample\Monster::AddHp($builder, 300);
+ \MyGame\Sample\Monster::AddName($builder, $name);
+ \MyGame\Sample\Monster::AddInventory($builder, $inv);
+ \MyGame\Sample\Monster::AddColor($builder, \MyGame\Sample\Color::Red);
+ \MyGame\Sample\Monster::AddWeapons($builder, $weapons);
+ \MyGame\Sample\Monster::AddEquippedType($builder, \MyGame\Sample\Equipment::Weapon);
+ \MyGame\Sample\Monster::AddEquipped($builder, $weaps[1]);
+ $orc = \MyGame\Sample\Monster::EndMonster($builder);
+
+ $builder->finish($orc); // You may also call `\MyGame\Sample\Monster::FinishMonsterBuffer($builder, $orc);`.
+
+ // We now have a FlatBuffer that can be stored on disk or sent over a network.
+
+ // ...Code to store to disk or send over a network goes here...
+
+ // Instead, we are going to access it right away, as if we just received it.
+
+ $buf = $builder->dataBuffer();
+
+ // Get access to the root:
+ $monster = \MyGame\Sample\Monster::GetRootAsMonster($buf);
+
+ $success = true; // Tracks if an assert occurred.
+
+ // Note: We did not set the `mana` field explicitly, so we get back the default value.
+ $success &= assert($monster->getMana() == 150);
+ $success &= assert($monster->getHp() == 300);
+ $success &= assert($monster->getName() == "Orc");
+ $success &= assert($monster->getColor() == \MyGame\Sample\Color::Red);
+ $success &= assert($monster->getPos()->getX() == 1.0);
+ $success &= assert($monster->getPos()->getY() == 2.0);
+ $success &= assert($monster->getPos()->getZ() == 3.0);
+
+ // Get and test the `inventory` FlatBuffer `vector`.
+ for ($i = 0; $i < $monster->getInventoryLength(); $i++) {
+ $success &= assert($monster->getInventory($i) == $i);
+ }
+
+ // Get and test the `weapons` FlatBuffer `vector` of `table`s.
+ $expected_weapon_names = array("Sword", "Axe");
+ $expected_weapon_damages = array(3, 5);
+ for ($i = 0; $i < $monster->getWeaponsLength(); $i++) {
+ $success &= assert($monster->getWeapons($i)->getName() == $expected_weapon_names[$i]);
+ $success &= assert($monster->getWeapons($i)->getDamage() == $expected_weapon_damages[$i]);
+ }
+
+ // Get and test the `equipped` FlatBuffer `union`.
+ $success &= assert($monster->getEquippedType() == \MyGame\Sample\Equipment::Weapon);
+ $success &= assert($monster->getEquipped(new \MyGame\Sample\Weapon())->getName() == "Axe");
+ $success &= assert($monster->getEquipped(new \MyGame\Sample\Weapon())->getDamage() == 5);
+
+ if ($success) {
+ print("The FlatBuffer was successfully created and verified!\n");
+ }
+}
+
+main();
+?>
diff --git a/samples/android/AndroidManifest.xml b/samples/android/AndroidManifest.xml
new file mode 100755
index 000000000..0fa3dcfc0
--- /dev/null
+++ b/samples/android/AndroidManifest.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/android/build_apk.sh b/samples/android/build_apk.sh
new file mode 100755
index 000000000..4967ee6dd
--- /dev/null
+++ b/samples/android/build_apk.sh
@@ -0,0 +1,510 @@
+#!/bin/bash -eu
+# Copyright (c) 2013 Google, Inc.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty. In no event will the authors be held liable for any damages
+# arising from the use of this software.
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+# 1. The origin of this software must not be misrepresented; you must not
+# claim that you wrote the original software. If you use this software
+# in a product, an acknowledgment in the product documentation would be
+# appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+# misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+#
+# Build, deploy, debug / execute a native Android package based upon
+# NativeActivity.
+
+declare -r script_directory=$(dirname $0)
+declare -r android_root=${script_directory}/../../../../../../
+declare -r script_name=$(basename $0)
+declare -r android_manifest=AndroidManifest.xml
+declare -r os_name=$(uname -s)
+
+# Minimum Android target version supported by this project.
+: ${BUILDAPK_ANDROID_TARGET_MINVERSION:=10}
+# Directory containing the Android SDK
+# (http://developer.android.com/sdk/index.html).
+: ${ANDROID_SDK_HOME:=}
+# Directory containing the Android NDK
+# (http://developer.android.com/tools/sdk/ndk/index.html).
+: ${NDK_HOME:=}
+
+# Display script help and exit.
+usage() {
+ echo "
+Build the Android package in the current directory and deploy it to a
+connected device.
+
+Usage: ${script_name} \\
+ [ADB_DEVICE=serial_number] [BUILD=0] [DEPLOY=0] [RUN_DEBUGGER=1] \
+ [LAUNCH=0] [SWIG_BIN=swig_binary_directory] [SWIG_LIB=swig_include_directory] [ndk-build arguments ...]
+
+ADB_DEVICE=serial_number:
+ serial_number specifies the device to deploy the built apk to if multiple
+ Android devices are connected to the host.
+BUILD=0:
+ Disables the build of the package.
+DEPLOY=0:
+ Disables the deployment of the built apk to the Android device.
+RUN_DEBUGGER=1:
+ Launches the application in gdb after it has been deployed. To debug in
+ gdb, NDK_DEBUG=1 must also be specified on the command line to build a
+ debug apk.
+LAUNCH=0:
+ Disable the launch of the apk on the Android device.
+SWIG_BIN=swig_binary_directory:
+ The directory where the SWIG binary lives. No need to set this if SWIG is
+ installed and point to from your PATH variable.
+SWIG_LIB=swig_include_directory:
+ The directory where SWIG shared include files are, usually obtainable from
+ commandline with \"swig -swiglib\". No need to set this if SWIG is installed
+ and point to from your PATH variable.
+ndk-build arguments...:
+ Additional arguments for ndk-build. See ndk-build -h for more information.
+" >&2
+ exit 1
+}
+
+# Get the number of CPU cores present on the host.
+get_number_of_cores() {
+ case ${os_name} in
+ Darwin)
+ sysctl hw.ncpu | awk '{ print $2 }'
+ ;;
+ CYGWIN*|Linux)
+ awk '/^processor/ { n=$3 } END { print n + 1 }' /proc/cpuinfo
+ ;;
+ *)
+ echo 1
+ ;;
+ esac
+}
+
+# Get the package name from an AndroidManifest.xml file.
+get_package_name_from_manifest() {
+ xmllint --xpath 'string(/manifest/@package)' "${1}"
+}
+
+# Get the library name from an AndroidManifest.xml file.
+get_library_name_from_manifest() {
+ echo "\
+setns android=http://schemas.android.com/apk/res/android
+xpath string(/manifest/application/activity\
+[@android:name=\"android.app.NativeActivity\"]/meta-data\
+[@android:name=\"android.app.lib_name\"]/@android:value)" |
+ xmllint --shell "${1}" | awk '/Object is a string/ { print $NF }'
+}
+
+# Get the number of Android devices connected to the system.
+get_number_of_devices_connected() {
+ adb devices -l | \
+ awk '/^..*$/ { if (p) { print $0 } }
+ /List of devices attached/ { p = 1 }' | \
+ wc -l
+ return ${PIPESTATUS[0]}
+}
+
+# Kill a process and its' children. This is provided for cygwin which
+# doesn't ship with pkill.
+kill_process_group() {
+ local parent_pid="${1}"
+ local child_pid=
+ for child_pid in $(ps -f | \
+ awk '{ if ($3 == '"${parent_pid}"') { print $2 } }'); do
+ kill_process_group "${child_pid}"
+ done
+ kill "${parent_pid}" 2>/dev/null
+}
+
+# Find and run "adb".
+adb() {
+ local adb_path=
+ for path in "$(which adb 2>/dev/null)" \
+ "${ANDROID_SDK_HOME}/sdk/platform-tools/adb" \
+ "${android_root}/prebuilts/sdk/platform-tools/adb"; do
+ if [[ -e "${path}" ]]; then
+ adb_path="${path}"
+ break
+ fi
+ done
+ if [[ "${adb_path}" == "" ]]; then
+ echo -e "Unable to find adb." \
+ "\nAdd the Android ADT sdk/platform-tools directory to the" \
+ "PATH." >&2
+ exit 1
+ fi
+ "${adb_path}" "$@"
+}
+
+# Find and run "android".
+android() {
+ local android_executable=android
+ if echo "${os_name}" | grep -q CYGWIN; then
+ android_executable=android.bat
+ fi
+ local android_path=
+ for path in "$(which ${android_executable})" \
+ "${ANDROID_SDK_HOME}/sdk/tools/${android_executable}" \
+ "${android_root}/prebuilts/sdk/tools/${android_executable}"; do
+ if [[ -e "${path}" ]]; then
+ android_path="${path}"
+ break
+ fi
+ done
+ if [[ "${android_path}" == "" ]]; then
+ echo -e "Unable to find android tool." \
+ "\nAdd the Android ADT sdk/tools directory to the PATH." >&2
+ exit 1
+ fi
+ # Make sure ant is installed.
+ if [[ "$(which ant)" == "" ]]; then
+ echo -e "Unable to find ant." \
+ "\nPlease install ant and add to the PATH." >&2
+ exit 1
+ fi
+
+ "${android_path}" "$@"
+}
+
+# Find and run "ndk-build"
+ndkbuild() {
+ local ndkbuild_path=
+ for path in "$(which ndk-build 2>/dev/null)" \
+ "${NDK_HOME}/ndk-build" \
+ "${android_root}/prebuilts/ndk/current/ndk-build"; do
+ if [[ -e "${path}" ]]; then
+ ndkbuild_path="${path}"
+ break
+ fi
+ done
+ if [[ "${ndkbuild_path}" == "" ]]; then
+ echo -e "Unable to find ndk-build." \
+ "\nAdd the Android NDK directory to the PATH." >&2
+ exit 1
+ fi
+ "${ndkbuild_path}" "$@"
+}
+
+# Get file modification time of $1 in seconds since the epoch.
+stat_mtime() {
+ local filename="${1}"
+ case ${os_name} in
+ Darwin) stat -f%m "${filename}" 2>/dev/null || echo 0 ;;
+ *) stat -c%Y "${filename}" 2>/dev/null || echo 0 ;;
+ esac
+}
+
+# Build the native (C/C++) build targets in the current directory.
+build_native_targets() {
+ # Save the list of output modules in the install directory so that it's
+ # possible to restore their timestamps after the build is complete. This
+ # works around a bug in ndk/build/core/setup-app.mk which results in the
+ # unconditional execution of the clean-installed-binaries rule.
+ restore_libraries="$(find libs -type f 2>/dev/null | \
+ sed -E 's@^libs/(.*)@\1@')"
+
+ # Build native code.
+ ndkbuild -j$(get_number_of_cores) "$@"
+
+ # Restore installed libraries.
+ # Obviously this is a nasty hack (along with ${restore_libraries} above) as
+ # it assumes it knows where the NDK will be placing output files.
+ (
+ IFS=$'\n'
+ for libpath in ${restore_libraries}; do
+ source_library="obj/local/${libpath}"
+ target_library="libs/${libpath}"
+ if [[ -e "${source_library}" ]]; then
+ cp -a "${source_library}" "${target_library}"
+ fi
+ done
+ )
+}
+
+# Select the oldest installed android build target that is at least as new as
+# BUILDAPK_ANDROID_TARGET_MINVERSION. If a suitable build target isn't found,
+# this function prints an error message and exits with an error.
+select_android_build_target() {
+ local -r android_targets_installed=$( \
+ android list targets | \
+ awk -F'"' '/^id:.*android/ { print $2 }')
+ local android_build_target=
+ for android_target in $(echo "${android_targets_installed}" | \
+ awk -F- '{ print $2 }' | sort -n); do
+ local isNumber='^[0-9]+$'
+ # skip preview API releases e.g. 'android-L'
+ if [[ $android_target =~ $isNumber ]]; then
+ if [[ $((android_target)) -ge \
+ $((BUILDAPK_ANDROID_TARGET_MINVERSION)) ]]; then
+ android_build_target="android-${android_target}"
+ break
+ fi
+ # else
+ # The API version is a letter, so skip it.
+ fi
+ done
+ if [[ "${android_build_target}" == "" ]]; then
+ echo -e \
+ "Found installed Android targets:" \
+ "$(echo ${android_targets_installed} | sed 's/ /\n /g;s/^/\n /;')" \
+ "\nAndroid SDK platform" \
+ "android-$((BUILDAPK_ANDROID_TARGET_MINVERSION))" \
+ "must be installed to build this project." \
+ "\nUse the \"android\" application to install API" \
+ "$((BUILDAPK_ANDROID_TARGET_MINVERSION)) or newer." >&2
+ exit 1
+ fi
+ echo "${android_build_target}"
+}
+
+# Sign unsigned apk $1 and write the result to $2 with key store file $3 and
+# password $4.
+# If a key store file $3 and password $4 aren't specified, a temporary
+# (60 day) key is generated and used to sign the package.
+sign_apk() {
+ local unsigned_apk="${1}"
+ local signed_apk="${2}"
+ if [[ $(stat_mtime "${unsigned_apk}") -gt \
+ $(stat_mtime "${signed_apk}") ]]; then
+ local -r key_alias=$(basename ${signed_apk} .apk)
+ local keystore="${3}"
+ local key_password="${4}"
+ [[ "${keystore}" == "" ]] && keystore="${unsigned_apk}.keystore"
+ [[ "${key_password}" == "" ]] && \
+ key_password="${key_alias}123456"
+ if [[ ! -e ${keystore} ]]; then
+ keytool -genkey -v -dname "cn=, ou=${key_alias}, o=fpl" \
+ -storepass ${key_password} \
+ -keypass ${key_password} -keystore ${keystore} \
+ -alias ${key_alias} -keyalg RSA -keysize 2048 -validity 60
+ fi
+ cp "${unsigned_apk}" "${signed_apk}"
+ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 \
+ -keystore ${keystore} -storepass ${key_password} \
+ -keypass ${key_password} "${signed_apk}" ${key_alias}
+ fi
+}
+
+# Build the apk $1 for package filename $2 in the current directory using the
+# ant build target $3.
+build_apk() {
+ local -r output_apk="${1}"
+ local -r package_filename="${2}"
+ local -r ant_target="${3}"
+ # Get the list of installed android targets and select the oldest target
+ # that is at least as new as BUILDAPK_ANDROID_TARGET_MINVERSION.
+ local -r android_build_target=$(select_android_build_target)
+ [[ "${android_build_target}" == "" ]] && exit 1
+ echo "Building ${output_apk} for target ${android_build_target}" >&2
+
+ # Create / update build.xml and local.properties files.
+ if [[ $(stat_mtime "${android_manifest}") -gt \
+ $(stat_mtime build.xml) ]]; then
+ android update project --target "${android_build_target}" \
+ -n ${package_filename} --path .
+ fi
+
+ # Use ant to build the apk.
+ ant -quiet ${ant_target}
+
+ # Sign release apks with a temporary key as these packages will not be
+ # redistributed.
+ local unsigned_apk="bin/${package_filename}-${ant_target}-unsigned.apk"
+ if [[ "${ant_target}" == "release" ]]; then
+ sign_apk "${unsigned_apk}" "${output_apk}" "" ""
+ fi
+}
+
+# Uninstall package $1 and install apk $2 on device $3 where $3 is "-s device"
+# or an empty string. If $3 is an empty string adb will fail when multiple
+# devices are connected to the host system.
+install_apk() {
+ local -r uninstall_package_name="${1}"
+ local -r install_apk="${2}"
+ local -r adb_device="${3}"
+ # Uninstall the package if it's already installed.
+ adb ${adb_device} uninstall "${uninstall_package_name}" 1>&2 > /dev/null || \
+ true # no error check
+
+ # Install the apk.
+ # NOTE: The following works around adb not returning an error code when
+ # it fails to install an apk.
+ echo "Install ${install_apk}" >&2
+ local -r adb_install_result=$(adb ${adb_device} install "${install_apk}")
+ echo "${adb_install_result}"
+ if echo "${adb_install_result}" | grep -qF 'Failure ['; then
+ exit 1
+ fi
+}
+
+# Launch previously installed package $1 on device $2.
+# If $2 is an empty string adb will fail when multiple devices are connected
+# to the host system.
+launch_package() {
+ (
+ # Determine the SDK version of Android on the device.
+ local -r android_sdk_version=$(
+ adb ${adb_device} shell cat system/build.prop | \
+ awk -F= '/ro.build.version.sdk/ {
+ v=$2; sub(/[ \r\n]/, "", v); print v
+ }')
+
+ # Clear logs from previous runs.
+ # Note that logcat does not just 'tail' the logs, it dumps the entire log
+ # history.
+ adb ${adb_device} logcat -c
+
+ local finished_msg='Displayed '"${package_name}"
+ local timeout_msg='Activity destroy timeout.*'"${package_name}"
+ # Maximum time to wait before stopping log monitoring. 0 = infinity.
+ local launch_timeout=0
+ # If this is a Gingerbread device, kill log monitoring after 10 seconds.
+ if [[ $((android_sdk_version)) -le 10 ]]; then
+ launch_timeout=10
+ fi
+ # Display logcat in the background.
+ # Stop displaying the log when the app launch / execution completes or the
+ # logcat
+ (
+ adb ${adb_device} logcat | \
+ awk "
+ {
+ print \$0
+ }
+
+ /ActivityManager.*: ${finished_msg}/ {
+ exit 0
+ }
+
+ /ActivityManager.*: ${timeout_msg}/ {
+ exit 0
+ }" &
+ adb_logcat_pid=$!;
+ if [[ $((launch_timeout)) -gt 0 ]]; then
+ sleep $((launch_timeout));
+ kill ${adb_logcat_pid};
+ else
+ wait ${adb_logcat_pid};
+ fi
+ ) &
+ logcat_pid=$!
+ # Kill adb logcat if this shell exits.
+ trap "kill_process_group ${logcat_pid}" SIGINT SIGTERM EXIT
+
+ # If the SDK is newer than 10, "am" supports stopping an activity.
+ adb_stop_activity=
+ if [[ $((android_sdk_version)) -gt 10 ]]; then
+ adb_stop_activity=-S
+ fi
+
+ # Launch the activity and wait for it to complete.
+ adb ${adb_device} shell am start ${adb_stop_activity} -n \
+ ${package_name}/android.app.NativeActivity
+
+ wait "${logcat_pid}"
+ )
+}
+
+# See usage().
+main() {
+ # Parse arguments for this script.
+ local adb_device=
+ local ant_target=release
+ local disable_deploy=0
+ local disable_build=0
+ local run_debugger=0
+ local launch=1
+ local build_package=1
+ for opt; do
+ case ${opt} in
+ # NDK_DEBUG=0 tells ndk-build to build this as debuggable but to not
+ # modify the underlying code whereas NDK_DEBUG=1 also builds as debuggable
+ # but does modify the code
+ NDK_DEBUG=1) ant_target=debug ;;
+ NDK_DEBUG=0) ant_target=debug ;;
+ ADB_DEVICE*) adb_device="$(\
+ echo "${opt}" | sed -E 's/^ADB_DEVICE=([^ ]+)$/-s \1/;t;s/.*//')" ;;
+ BUILD=0) disable_build=1 ;;
+ DEPLOY=0) disable_deploy=1 ;;
+ RUN_DEBUGGER=1) run_debugger=1 ;;
+ LAUNCH=0) launch=0 ;;
+ clean) build_package=0 disable_deploy=1 launch=0 ;;
+ -h|--help|help) usage ;;
+ esac
+ done
+
+ # If a target device hasn't been specified and multiple devices are connected
+ # to the host machine, display an error.
+ local -r devices_connected=$(get_number_of_devices_connected)
+ if [[ "${adb_device}" == "" && $((devices_connected)) -gt 1 && \
+ ($((disable_deploy)) -eq 0 || $((launch)) -ne 0 || \
+ $((run_debugger)) -ne 0) ]]; then
+ if [[ $((disable_deploy)) -ne 0 ]]; then
+ echo "Deployment enabled, disable using DEPLOY=0" >&2
+ fi
+ if [[ $((launch)) -ne 0 ]]; then
+ echo "Launch enabled." >&2
+ fi
+ if [[ $((disable_deploy)) -eq 0 ]]; then
+ echo "Deployment enabled." >&2
+ fi
+ if [[ $((run_debugger)) -ne 0 ]]; then
+ echo "Debugger launch enabled." >&2
+ fi
+ echo "
+Multiple Android devices are connected to this host. Either disable deployment
+and execution of the built .apk using:
+ \"${script_name} DEPLOY=0 LAUNCH=0\"
+
+or specify a device to deploy to using:
+ \"${script_name} ADB_DEVICE=\${device_serial}\".
+
+The Android devices connected to this machine are:
+$(adb devices -l)
+" >&2
+ exit 1
+ fi
+
+ if [[ $((disable_build)) -eq 0 ]]; then
+ # Build the native target.
+ build_native_targets "$@"
+ fi
+
+ # Get the package name from the manifest.
+ local -r package_name=$(get_package_name_from_manifest "${android_manifest}")
+ if [[ "${package_name}" == "" ]]; then
+ echo -e "No package name specified in ${android_manifest},"\
+ "skipping apk build, deploy"
+ "\nand launch steps." >&2
+ exit 0
+ fi
+ local -r package_basename=${package_name/*./}
+ local package_filename=$(get_library_name_from_manifest ${android_manifest})
+ [[ "${package_filename}" == "" ]] && package_filename="${package_basename}"
+
+ # Output apk name.
+ local -r output_apk="bin/${package_filename}-${ant_target}.apk"
+
+ if [[ $((disable_build)) -eq 0 && $((build_package)) -eq 1 ]]; then
+ # Build the apk.
+ build_apk "${output_apk}" "${package_filename}" "${ant_target}"
+ fi
+
+ # Deploy to the device.
+ if [[ $((disable_deploy)) -eq 0 ]]; then
+ install_apk "${package_name}" "${output_apk}" "${adb_device}"
+ fi
+
+ if [[ "${ant_target}" == "debug" && $((run_debugger)) -eq 1 ]]; then
+ # Start debugging.
+ ndk-gdb ${adb_device} --start
+ elif [[ $((launch)) -eq 1 ]]; then
+ launch_package "${package_name}" "${adb_device}"
+ fi
+}
+
+main "$@"
diff --git a/samples/android/jni/Android.mk b/samples/android/jni/Android.mk
index b9c7a1952..6f22d2852 100755
--- a/samples/android/jni/Android.mk
+++ b/samples/android/jni/Android.mk
@@ -23,7 +23,7 @@ include $(CLEAR_VARS)
# Include the FlatBuffer utility function to generate header files from schemas.
include $(FLATBUFFERS_ROOT_DIR)/android/jni/include.mk
-LOCAL_MODULE := sample_android_project
+LOCAL_MODULE := FlatBufferSample
# Set up some useful variables to identify schema and output directories and
# schema files.
diff --git a/samples/android/jni/main.cpp b/samples/android/jni/main.cpp
index d03655ca5..87580272f 100644
--- a/samples/android/jni/main.cpp
+++ b/samples/android/jni/main.cpp
@@ -12,9 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include
+
#include "android_native_app_glue.h"
-#include "animal_generated.h"
-#include "flatbuffers/flatbuffers.h"
+#include "animal_generated.h" // Includes "flatbuffers/flatbuffers.h".
void android_main(android_app *app) {
app_dummy();
@@ -24,5 +25,19 @@ void android_main(android_app *app) {
auto sound = builder.CreateString("Bark");
auto animal_buffer = sample::CreateAnimal(builder, name, sound);
builder.Finish(animal_buffer);
-}
+ // We now have a FlatBuffer that can be stored on disk or sent over a network.
+
+ // ...Code to store on disk or send over a network goes here...
+
+ // Instead, we're going to access it immediately, as if we just recieved this.
+
+ auto animal = sample::GetAnimal(builder.GetBufferPointer());
+
+ assert(animal->name()->str() == "Dog");
+ assert(animal->sound()->str() == "Bark");
+ (void)animal; // To silence "Unused Variable" warnings.
+
+ __android_log_print(ANDROID_LOG_INFO, "FlatBufferSample",
+ "FlatBuffer successfully created and verified.");
+}
diff --git a/samples/android/res/values/strings.xml b/samples/android/res/values/strings.xml
new file mode 100755
index 000000000..57ddaf4e1
--- /dev/null
+++ b/samples/android/res/values/strings.xml
@@ -0,0 +1,20 @@
+
+
+
+ FlatBufferSample
+
diff --git a/samples/android_sample.sh b/samples/android_sample.sh
new file mode 100755
index 000000000..9e746fb2a
--- /dev/null
+++ b/samples/android_sample.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# Copyright 2015 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Note: This script requires the Android NDK and Android SDK to be installed.
+# It also requires an Android device to be connected for installing and
+# running the applicaton.
+
+sampledir=$(readlink -fn `dirname $0`)
+currentdir=$(readlink -fn `pwd`)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+ echo Error: This script must be run from inside the $sampledir directory.
+ echo You executed it from the $currentdir directory.
+ exit 1
+fi
+
+# Execute `build_apk.sh` to build and run the android app.
+cd android
+./build_apk.sh
+
+# Cleanup the temporary files.
+rm build.xml local.properties proguard-project.txt project.properties
+rm -rf bin libs obj
diff --git a/samples/csharp_sample.sh b/samples/csharp_sample.sh
new file mode 100755
index 000000000..5c86f7b78
--- /dev/null
+++ b/samples/csharp_sample.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# Copyright 2015 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Note: This script runs on Mac and Linux. It requires `mono` to be installed
+# and `flatc` to be built (using `cmake` in the root directory).
+
+sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
+rootidr=$(cd $sampledir/.. && pwd)
+currentdir=$(pwd)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+ echo Error: This script must be run from inside the $sampledir directory.
+ echo You executed it from the $currentdir directory.
+ exit 1
+fi
+
+# Run `flatc`. Note: This requires you to compile using `cmake` from the
+# root `/flatbuffers` directory.
+if [ -e ../flatc ]; then
+ ../flatc --csharp --gen-mutable monster.fbs
+elif [ -e ../Debug/flatc ]; then
+ ../Debug/flatc --csharp --gen-mutable monster.fbs
+else
+ echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
+ $rootdir directory.
+ exit 1
+fi
+
+echo Compiling and running the C# sample.
+
+# Compile and execute the sample.
+mcs SampleBinary.cs MyGame/Sample/*.cs ../net/FlatBuffers/*.cs
+mono SampleBinary.exe
+
+# Cleanup temporary files.
+rm SampleBinary.exe
+rm -rf MyGame/
diff --git a/samples/go_sample.sh b/samples/go_sample.sh
new file mode 100755
index 000000000..2a0605f20
--- /dev/null
+++ b/samples/go_sample.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+# Copyright 2015 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Note: This script runs on Mac and Linux. It requires `go` to be installed
+# and 'flatc' to be built (using `cmake` in the root directory).
+
+sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
+rootdir=$(cd $sampledir/.. && pwd)
+currentdir=$(pwd)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+ echo Error: This script must be run from inside the $sampledir directory.
+ echo You executed it from the $currentdir directory.
+ exit 1
+fi
+
+# Run `flatc`. Note: This requires you to compile using `cmake` from the
+# root `/flatbuffers` directory.
+if [ -e ../flatc ]; then
+ ../flatc --go monster.fbs
+elif [ -e ../Debug/flatc ]; then
+ ../Debug/flatc --go monster.fbs
+else
+ echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
+ $rootdir directory.
+ exit 1
+fi
+
+echo Compiling and running the Go sample.
+
+# Go requires a particular layout of files in order to link the necessary
+# packages. Copy these files to the respective directores to compile the
+# sample.
+mkdir -p ${sampledir}/go_gen/src/MyGame/Sample
+mkdir -p ${sampledir}/go_gen/src/github.com/google/flatbuffers/go
+cp MyGame/Sample/*.go ${sampledir}/go_gen/src/MyGame/Sample/
+cp ${sampledir}/../go/* ${sampledir}/go_gen/src/github.com/google/flatbuffers/go
+
+# Export the `GOPATH`, so that `go` will know which directories to search for
+# the libraries.
+export GOPATH=${sampledir}/go_gen/
+
+# Compile and execute the sample.
+go build -o go_sample sample_binary.go
+./go_sample
+
+# Clean up the temporary files.
+rm -rf MyGame/
+rm -rf ${sampledir}/go_gen/
+rm go_sample
diff --git a/samples/java_sample.sh b/samples/java_sample.sh
new file mode 100755
index 000000000..3e7ebcfe1
--- /dev/null
+++ b/samples/java_sample.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+# Copyright 2015 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Note: This script runs on Mac and Linux. It requires `java` to be installed
+# and `flatc` to be built (using `cmake` in the root directory).
+
+sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
+rootdir=$(cd $sampledir/.. && pwd)
+currentdir=$(pwd)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+ echo Error: This script must be run from inside the $sampledir directory.
+ echo You executed it from the $currentdir directory.
+ exit 1
+fi
+
+# Run `flatc`. Note: This requires you to compile using `cmake` from the
+# root `/flatbuffers` directory.
+if [ -e ../flatc ]; then
+ ../flatc --java --gen-mutable monster.fbs
+elif [ -e ../Debug/flatc ]; then
+ ../Debug/flatc --java --gen-mutable monster.fbs
+else
+ echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
+ $rootdir directory.
+ exit 1
+fi
+
+echo Compiling and running the Java sample.
+
+# Compile and execute the sample.
+javac -classpath ${sampledir}/../java:${sampledir} SampleBinary.java
+java -classpath ${sampledir}/../java:${sampledir} SampleBinary
+
+# Cleanup temporary files.
+rm -rf MyGame/
+rm ${sampledir}/../java/com/google/flatbuffers/*.class
+rm *.class
diff --git a/samples/javascript_sample.sh b/samples/javascript_sample.sh
new file mode 100755
index 000000000..794ec4b7c
--- /dev/null
+++ b/samples/javascript_sample.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# Copyright 2015 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Note: This script runs on Mac and Linux. It requires `Node.js` to be installed
+# and `flatc` to be built (using `cmake` in the root directory).
+
+sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
+rootdir=$(cd $sampledir/.. && pwd)
+currentdir=$(pwd)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+ echo Error: This script must be run from inside the $sampledir directory.
+ echo You executed it from the $currentdir directory.
+ exit 1
+fi
+
+# Run `flatc`. Note: This requires you to compile using `cmake` from the
+# root `/flatbuffers` directory.
+if [ -e ../flatc ]; then
+ ../flatc --js monster.fbs
+elif [ -e ../Debug/flatc ]; then
+ ../Debug/flatc --js monster.fbs
+else
+ echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
+ $rootdir directory.
+ exit 1
+fi
+
+echo Running the JavaScript sample.
+
+# Execute the sample.
+node samplebinary.js
+
+# Cleanup temporary files.
+rm monster_generated.js
diff --git a/samples/monster.fbs b/samples/monster.fbs
index 2ad0c926d..247b81771 100755
--- a/samples/monster.fbs
+++ b/samples/monster.fbs
@@ -1,10 +1,10 @@
-// example IDL file
+// Example IDL file for our monster's schema.
namespace MyGame.Sample;
enum Color:byte { Red = 0, Green, Blue = 2 }
-union Any { Monster } // add more elements..
+union Equipment { Weapon } // Optionally add more tables.
struct Vec3 {
x:float;
@@ -20,6 +20,13 @@ table Monster {
friendly:bool = false (deprecated);
inventory:[ubyte];
color:Color = Blue;
+ weapons:[Weapon];
+ equipped:Equipment;
+}
+
+table Weapon {
+ name:string;
+ damage:short;
}
root_type Monster;
diff --git a/samples/monster_generated.h b/samples/monster_generated.h
deleted file mode 100644
index e27b69117..000000000
--- a/samples/monster_generated.h
+++ /dev/null
@@ -1,153 +0,0 @@
-// automatically generated by the FlatBuffers compiler, do not modify
-
-#ifndef FLATBUFFERS_GENERATED_MONSTER_MYGAME_SAMPLE_H_
-#define FLATBUFFERS_GENERATED_MONSTER_MYGAME_SAMPLE_H_
-
-#include "flatbuffers/flatbuffers.h"
-
-
-namespace MyGame {
-namespace Sample {
-
-struct Vec3;
-struct Monster;
-
-enum Color {
- Color_Red = 0,
- Color_Green = 1,
- Color_Blue = 2,
- Color_MIN = Color_Red,
- Color_MAX = Color_Blue
-};
-
-inline const char **EnumNamesColor() {
- static const char *names[] = { "Red", "Green", "Blue", nullptr };
- return names;
-}
-
-inline const char *EnumNameColor(Color e) { return EnumNamesColor()[static_cast(e)]; }
-
-enum Any {
- Any_NONE = 0,
- Any_Monster = 1,
- Any_MIN = Any_NONE,
- Any_MAX = Any_Monster
-};
-
-inline const char **EnumNamesAny() {
- static const char *names[] = { "NONE", "Monster", nullptr };
- return names;
-}
-
-inline const char *EnumNameAny(Any e) { return EnumNamesAny()[static_cast(e)]; }
-
-inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *union_obj, Any type);
-
-MANUALLY_ALIGNED_STRUCT(4) Vec3 FLATBUFFERS_FINAL_CLASS {
- private:
- float x_;
- float y_;
- float z_;
-
- public:
- Vec3(float _x, float _y, float _z)
- : x_(flatbuffers::EndianScalar(_x)), y_(flatbuffers::EndianScalar(_y)), z_(flatbuffers::EndianScalar(_z)) { }
-
- float x() const { return flatbuffers::EndianScalar(x_); }
- void mutate_x(float _x) { flatbuffers::WriteScalar(&x_, _x); }
- float y() const { return flatbuffers::EndianScalar(y_); }
- void mutate_y(float _y) { flatbuffers::WriteScalar(&y_, _y); }
- float z() const { return flatbuffers::EndianScalar(z_); }
- void mutate_z(float _z) { flatbuffers::WriteScalar(&z_, _z); }
-};
-STRUCT_END(Vec3, 12);
-
-struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
- enum {
- VT_POS = 4,
- VT_MANA = 6,
- VT_HP = 8,
- VT_NAME = 10,
- VT_INVENTORY = 14,
- VT_COLOR = 16
- };
- const Vec3 *pos() const { return GetStruct(VT_POS); }
- Vec3 *mutable_pos() { return GetStruct(VT_POS); }
- int16_t mana() const { return GetField(VT_MANA, 150); }
- bool mutate_mana(int16_t _mana) { return SetField(VT_MANA, _mana); }
- int16_t hp() const { return GetField(VT_HP, 100); }
- bool mutate_hp(int16_t _hp) { return SetField(VT_HP, _hp); }
- const flatbuffers::String *name() const { return GetPointer(VT_NAME); }
- flatbuffers::String *mutable_name() { return GetPointer(VT_NAME); }
- const flatbuffers::Vector *inventory() const { return GetPointer *>(VT_INVENTORY); }
- flatbuffers::Vector *mutable_inventory() { return GetPointer *>(VT_INVENTORY); }
- Color color() const { return static_cast(GetField(VT_COLOR, 2)); }
- bool mutate_color(Color _color) { return SetField(VT_COLOR, static_cast(_color)); }
- bool Verify(flatbuffers::Verifier &verifier) const {
- return VerifyTableStart(verifier) &&
- VerifyField(verifier, VT_POS) &&
- VerifyField(verifier, VT_MANA) &&
- VerifyField(verifier, VT_HP) &&
- VerifyField(verifier, VT_NAME) &&
- verifier.Verify(name()) &&
- VerifyField(verifier, VT_INVENTORY) &&
- verifier.Verify(inventory()) &&
- VerifyField(verifier, VT_COLOR) &&
- verifier.EndTable();
- }
-};
-
-struct MonsterBuilder {
- flatbuffers::FlatBufferBuilder &fbb_;
- flatbuffers::uoffset_t start_;
- void add_pos(const Vec3 *pos) { fbb_.AddStruct(Monster::VT_POS, pos); }
- void add_mana(int16_t mana) { fbb_.AddElement(Monster::VT_MANA, mana, 150); }
- void add_hp(int16_t hp) { fbb_.AddElement(Monster::VT_HP, hp, 100); }
- void add_name(flatbuffers::Offset name) { fbb_.AddOffset(Monster::VT_NAME, name); }
- void add_inventory(flatbuffers::Offset> inventory) { fbb_.AddOffset(Monster::VT_INVENTORY, inventory); }
- void add_color(Color color) { fbb_.AddElement(Monster::VT_COLOR, static_cast(color), 2); }
- MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
- MonsterBuilder &operator=(const MonsterBuilder &);
- flatbuffers::Offset Finish() {
- auto o = flatbuffers::Offset(fbb_.EndTable(start_, 7));
- return o;
- }
-};
-
-inline flatbuffers::Offset CreateMonster(flatbuffers::FlatBufferBuilder &_fbb,
- const Vec3 *pos = 0,
- int16_t mana = 150,
- int16_t hp = 100,
- flatbuffers::Offset name = 0,
- flatbuffers::Offset> inventory = 0,
- Color color = Color_Blue) {
- MonsterBuilder builder_(_fbb);
- builder_.add_inventory(inventory);
- builder_.add_name(name);
- builder_.add_pos(pos);
- builder_.add_hp(hp);
- builder_.add_mana(mana);
- builder_.add_color(color);
- return builder_.Finish();
-}
-
-inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *union_obj, Any type) {
- switch (type) {
- case Any_NONE: return true;
- case Any_Monster: return verifier.VerifyTable(reinterpret_cast(union_obj));
- default: return false;
- }
-}
-
-inline const MyGame::Sample::Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot(buf); }
-
-inline Monster *GetMutableMonster(void *buf) { return flatbuffers::GetMutableRoot(buf); }
-
-inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer(); }
-
-inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset root) { fbb.Finish(root); }
-
-} // namespace Sample
-} // namespace MyGame
-
-#endif // FLATBUFFERS_GENERATED_MONSTER_MYGAME_SAMPLE_H_
diff --git a/samples/monsterdata.json b/samples/monsterdata.json
index 06bb57af9..8d669146d 100755
--- a/samples/monsterdata.json
+++ b/samples/monsterdata.json
@@ -4,6 +4,6 @@
y: 2,
z: 3
},
- hp: 80,
- name: "MyMonster"
+ hp: 300,
+ name: "Orc"
}
diff --git a/samples/php_sample.sh b/samples/php_sample.sh
new file mode 100755
index 000000000..8a55e2a05
--- /dev/null
+++ b/samples/php_sample.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# Copyright 2015 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Note: This script runs on Mac and Linux. It requires `php` to be installed
+# and `flatc` to be built (using `cmake` in the root directory).
+
+sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
+rootdir=$(cd $sampledir/.. && pwd)
+currentdir=$(pwd)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+ echo Error: This script must be run from inside the $sampledir directory.
+ echo You executed it from the $currentdir directory.
+ exit 1
+fi
+
+# Run `flatc`. Note: This requires you to compile using `cmake` from the
+# root `/flatbuffers` directory.
+if [ -e ../flatc ]; then
+ ../flatc --php monster.fbs
+elif [ -e ../Debug/flatc ]; then
+ ../Debug/flatc --php monster.fbs
+else
+ echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
+ $rootdir directory.
+ exit 1
+fi
+
+echo Running the PHP sample.
+
+# Execute the sample.
+php SampleBinary.php
+
+# Clean up temporary files.
+rm -rf MyGame/
diff --git a/samples/python_sample.sh b/samples/python_sample.sh
new file mode 100755
index 000000000..9148c7d81
--- /dev/null
+++ b/samples/python_sample.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# Copyright 2015 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Note: This script runs on Mac and Linux. It requires `python` to be installed
+# and `flatc` to be built (using `cmake` in the root directory).
+
+sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
+rootdir=$(cd $sampledir/.. && pwd)
+currentdir=$(pwd)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+ echo Error: This script must be run from inside the $sampledir directory.
+ echo You executed it from the $currentdir directory.
+ exit 1
+fi
+
+# Run `flatc`. Note: This requires you to compile using `cmake` from the
+# root `/flatbuffers` directory.
+if [ -e ../flatc ]; then
+ ../flatc --python monster.fbs
+elif [ -e ../Debug/flatc ]; then
+ ../Debug/flatc --python monster.fbs
+else
+ echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
+ $rootdir directory.
+ exit 1
+fi
+
+echo Running the Python sample.
+
+# Execute the sample.
+python sample_binary.py
+
+# Clean up the temporary files.
+rm -rf MyGame
diff --git a/samples/sample_binary.cpp b/samples/sample_binary.cpp
index 3b6d0fbe4..5b2f603a0 100644
--- a/samples/sample_binary.cpp
+++ b/samples/sample_binary.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 Google Inc. All rights reserved.
+ * Copyright 2015 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,9 +14,7 @@
* limitations under the License.
*/
-#include "flatbuffers/flatbuffers.h"
-
-#include "monster_generated.h"
+#include "monster_generated.h" // Already includes "flatbuffers/flatbuffers.h".
using namespace MyGame::Sample;
@@ -26,7 +24,25 @@ int main(int /*argc*/, const char * /*argv*/[]) {
// Build up a serialized buffer algorithmically:
flatbuffers::FlatBufferBuilder builder;
- auto vec = Vec3(1, 2, 3);
+ // First, lets serialize some weapons for the Monster: A 'sword' and an 'axe'.
+ auto weapon_one_name = builder.CreateString("Sword");
+ short weapon_one_damage = 3;
+
+ auto weapon_two_name = builder.CreateString("Axe");
+ short weapon_two_damage = 5;
+
+ // Use the `CreateWeapon` shortcut to create Weapons with all fields set.
+ auto sword = CreateWeapon(builder, weapon_one_name, weapon_one_damage);
+ auto axe = CreateWeapon(builder, weapon_two_name, weapon_two_damage);
+
+ // Create a FlatBuffer's `vector` from the `std::vector`.
+ std::vector> weapons_vector;
+ weapons_vector.push_back(sword);
+ weapons_vector.push_back(axe);
+ auto weapons = builder.CreateVector(weapons_vector);
+
+ // Second, serialize the rest of the objects needed by the Monster.
+ auto position = Vec3(1.0f, 2.0f, 3.0f);
auto name = builder.CreateString("MyMonster");
@@ -34,31 +50,53 @@ int main(int /*argc*/, const char * /*argv*/[]) {
auto inventory = builder.CreateVector(inv_data, 10);
// Shortcut for creating monster with all fields set:
- auto mloc = CreateMonster(builder, &vec, 150, 80, name, inventory,
- Color_Blue);
+ auto orc = CreateMonster(builder, &position, 150, 80, name, inventory,
+ Color_Red, weapons, Equipment_Weapon, axe.Union());
- builder.Finish(mloc);
- // We now have a FlatBuffer we can store or send somewhere.
+ builder.Finish(orc); // Serialize the root of the object.
+
+ // We now have a FlatBuffer we can store on disk or send over a network.
// ** file/network code goes here :) **
// access builder.GetBufferPointer() for builder.GetSize() bytes
- // Instead, we're going to access it straight away.
+ // Instead, we're going to access it right away (as if we just received it).
+
// Get access to the root:
auto monster = GetMonster(builder.GetBufferPointer());
+ // Get and test some scalar types from the FlatBuffer.
assert(monster->hp() == 80);
assert(monster->mana() == 150); // default
assert(monster->name()->str() == "MyMonster");
+ // Get and test a field of the FlatBuffer's `struct`.
auto pos = monster->pos();
assert(pos);
- assert(pos->z() == 3);
+ assert(pos->z() == 3.0f);
(void)pos;
+ // Get a test an element from the `inventory` FlatBuffer's `vector`.
auto inv = monster->inventory();
assert(inv);
assert(inv->Get(9) == 9);
(void)inv;
+
+ // Get and test the `weapons` FlatBuffers's `vector`.
+ std::string expected_weapon_names[] = {"Sword", "Axe"};
+ short expected_weapon_damages[] = {3, 5};
+ auto weps = monster->weapons();
+ for (unsigned int i = 0; i < weps->size(); i++) {
+ assert(weps->Get(i)->name()->str() == expected_weapon_names[i]);
+ assert(weps->Get(i)->damage() == expected_weapon_damages[i]);
+ }
+
+ // Get and test the `Equipment` union (`equipped` field).
+ assert(monster->equipped_type() == Equipment_Weapon);
+ auto equipped = static_cast(monster->equipped());
+ assert(equipped->name()->str() == "Axe");
+ assert(equipped->damage() == 5);
+
+ printf("The FlatBuffer was successfully created and verified!\n");
}
diff --git a/samples/sample_binary.go b/samples/sample_binary.go
new file mode 100644
index 000000000..7a36e6a8a
--- /dev/null
+++ b/samples/sample_binary.go
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2015 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// To run, use the `go_sample.sh` script.
+
+package main
+
+import (
+ flatbuffers "github.com/google/flatbuffers/go"
+ "fmt"
+ "strconv"
+ sample "MyGame/Sample"
+)
+
+// Example how to use Flatbuffers to create and read binary buffers.
+func main() {
+ builder := flatbuffers.NewBuilder(0)
+
+ // Create some weapons for our Monster ("Sword" and "Axe").
+ weaponOne := builder.CreateString("Sword")
+ weaponTwo := builder.CreateString("Axe")
+
+ sample.WeaponStart(builder)
+ sample.WeaponAddName(builder, weaponOne)
+ sample.WeaponAddDamage(builder, 3)
+ sword := sample.WeaponEnd(builder)
+
+ sample.WeaponStart(builder)
+ sample.WeaponAddName(builder, weaponTwo)
+ sample.WeaponAddDamage(builder, 5)
+ axe := sample.WeaponEnd(builder)
+
+ // Serialize the FlatBuffer data.
+ name := builder.CreateString("Orc")
+
+ sample.MonsterStartInventoryVector(builder, 10)
+ // Note: Since we prepend the bytes, this loop iterates in reverse.
+ for i := 9; i >= 0; i-- {
+ builder.PrependByte(byte(i))
+ }
+ inv := builder.EndVector(10)
+
+ sample.MonsterStartWeaponsVector(builder, 2)
+ // Note: Since we prepend the weapons, prepend in reverse order.
+ builder.PrependUOffsetT(axe)
+ builder.PrependUOffsetT(sword)
+ weapons := builder.EndVector(2)
+
+ pos := sample.CreateVec3(builder, 1.0, 2.0, 3.0)
+
+ sample.MonsterStart(builder)
+ sample.MonsterAddPos(builder, pos)
+ sample.MonsterAddHp(builder, 300)
+ sample.MonsterAddName(builder, name)
+ sample.MonsterAddInventory(builder, inv)
+ sample.MonsterAddColor(builder, sample.ColorRed)
+ sample.MonsterAddWeapons(builder, weapons)
+ sample.MonsterAddEquippedType(builder, sample.EquipmentWeapon)
+ sample.MonsterAddEquipped(builder, axe)
+ orc := sample.MonsterEnd(builder)
+
+ builder.Finish(orc)
+
+ // We now have a FlatBuffer that we could store on disk or send over a network.
+
+ // ...Saving to file or sending over a network code goes here...
+
+ // Instead, we are going to access this buffer right away (as if we just received it).
+
+ buf := builder.FinishedBytes()
+
+ // Note: We use `0` for the offset here, since we got the data using the
+ // `builder.FinishedBytes()` method. This simulates the data you would store/receive in your
+ // FlatBuffer. If you wanted to read from the `builder.Bytes` directly, you would need to
+ // pass in the offset of `builder.Head()`, as the builder actually constructs the buffer
+ // backwards.
+ monster := sample.GetRootAsMonster(buf, 0)
+
+ // Note: We did not set the `mana` field explicitly, so we get the
+ // default value.
+ assert(monster.Mana() == 150, "`monster.Mana()`", strconv.Itoa(int(monster.Mana())), "150")
+ assert(monster.Hp() == 300, "`monster.Hp()`", strconv.Itoa(int(monster.Hp())), "300")
+ assert(string(monster.Name()) == "Orc", "`string(monster.Name())`", string(monster.Name()),
+ "\"Orc\"")
+ assert(monster.Color() == sample.ColorRed, "`monster.Color()`",
+ strconv.Itoa(int(monster.Color())), strconv.Itoa(int(sample.ColorRed)))
+
+ // Note: Whenever you access a new object, like in `Pos()`, a new temporary accessor object
+ // gets created. If your code is very performance sensitive, you can pass in a pointer to an
+ // existing `Vec3` instead of `nil`. This allows you to reuse it across many calls to reduce
+ // the amount of object allocation/garbage collection.
+ assert(monster.Pos(nil).X() == 1.0, "`monster.Pos(nil).X()`",
+ strconv.FormatFloat(float64(monster.Pos(nil).X()), 'f', 1, 32), "1.0")
+ assert(monster.Pos(nil).Y() == 2.0, "`monster.Pos(nil).Y()`",
+ strconv.FormatFloat(float64(monster.Pos(nil).Y()), 'f', 1, 32), "2.0")
+ assert(monster.Pos(nil).Z() == 3.0, "`monster.Pos(nil).Z()`",
+ strconv.FormatFloat(float64(monster.Pos(nil).Z()), 'f', 1, 32), "3.0")
+
+ // For vectors, like `Inventory`, they have a method suffixed with 'Length' that can be used
+ // to query the length of the vector. You can index the vector by passing an index value
+ // into the accessor.
+ for i := 0; i < monster.InventoryLength(); i++ {
+ assert(monster.Inventory(i) == byte(i), "`monster.Inventory(i)`",
+ strconv.Itoa(int(monster.Inventory(i))), strconv.Itoa(int(byte(i))))
+ }
+
+ expectedWeaponNames := []string{"Sword", "Axe"}
+ expectedWeaponDamages := []int{3, 5}
+ weapon := new(sample.Weapon) // We need a `sample.Weapon` to pass into `monster.Weapons()`
+ // to capture the output of that function.
+ for i := 0; i < monster.WeaponsLength(); i++ {
+ if monster.Weapons(weapon, i) {
+ assert(string(weapon.Name()) == expectedWeaponNames[i], "`weapon.Name()`",
+ string(weapon.Name()), expectedWeaponNames[i])
+ assert(int(weapon.Damage()) == expectedWeaponDamages[i],
+ "`weapon.Damage()`", strconv.Itoa(int(weapon.Damage())),
+ strconv.Itoa(expectedWeaponDamages[i]))
+ }
+ }
+
+ // For FlatBuffer `union`s, you can get the type of the union, as well as the union
+ // data itself.
+ assert(monster.EquippedType() == sample.EquipmentWeapon, "`monster.EquippedType()`",
+ strconv.Itoa(int(monster.EquippedType())), strconv.Itoa(int(sample.EquipmentWeapon)))
+
+ unionTable := new(flatbuffers.Table)
+ if monster.Equipped(unionTable) {
+ // An example of how you can appropriately convert the table depending on the
+ // FlatBuffer `union` type. You could add `else if` and `else` clauses to handle
+ // other FlatBuffer `union` types for this field. (Similarly, this could be
+ // done in a switch statement.)
+ if monster.EquippedType() == sample.EquipmentWeapon {
+ unionWeapon := new(sample.Weapon)
+ unionWeapon.Init(unionTable.Bytes, unionTable.Pos)
+
+ assert(string(unionWeapon.Name()) == "Axe", "`unionWeapon.Name()`",
+ string(unionWeapon.Name()), "Axe")
+ assert(int(unionWeapon.Damage()) == 5, "`unionWeapon.Damage()`",
+ strconv.Itoa(int(unionWeapon.Damage())), strconv.Itoa(5))
+ }
+ }
+
+ fmt.Printf("The FlatBuffer was successfully created and verified!\n")
+}
+
+// A helper function to print out if an assertion failed.
+func assert(assertPassed bool, codeExecuted string, actualValue string, expectedValue string) {
+ if assertPassed == false {
+ panic("Assert failed! " + codeExecuted + " (" + actualValue +
+ ") was not equal to " + expectedValue + ".")
+ }
+}
diff --git a/samples/sample_binary.py b/samples/sample_binary.py
new file mode 100644
index 000000000..96711fb45
--- /dev/null
+++ b/samples/sample_binary.py
@@ -0,0 +1,137 @@
+#!/usr/bin/python
+# Copyright 2015 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# To run this file, use `python_sample.sh`.
+
+# Append paths to the `flatbuffers` and `MyGame` modules. This is necessary
+# to facilitate executing this script in the `samples` folder, and to root
+# folder (where it gets placed when using `cmake`).
+import os
+import sys
+sys.path.append(os.path.join(os.path.dirname(__file__), '../python'))
+
+import flatbuffers
+import MyGame.Sample.Color
+import MyGame.Sample.Equipment
+import MyGame.Sample.Monster
+import MyGame.Sample.Vec3
+import MyGame.Sample.Weapon
+
+# Example of how to use FlatBuffers to create and read binary buffers.
+
+def main():
+ builder = flatbuffers.Builder(0)
+
+ # Create some weapons for our Monster ('Sword' and 'Axe').
+ weapon_one = builder.CreateString('Sword')
+ weapon_two = builder.CreateString('Axe')
+
+ MyGame.Sample.Weapon.WeaponStart(builder)
+ MyGame.Sample.Weapon.WeaponAddName(builder, weapon_one)
+ MyGame.Sample.Weapon.WeaponAddDamage(builder, 3)
+ sword = MyGame.Sample.Weapon.WeaponEnd(builder)
+
+ MyGame.Sample.Weapon.WeaponStart(builder)
+ MyGame.Sample.Weapon.WeaponAddName(builder, weapon_two)
+ MyGame.Sample.Weapon.WeaponAddDamage(builder, 5)
+ axe = MyGame.Sample.Weapon.WeaponEnd(builder)
+
+ # Serialize the FlatBuffer data.
+ name = builder.CreateString('Orc')
+
+ MyGame.Sample.Monster.MonsterStartInventoryVector(builder, 10)
+ # Note: Since we prepend the bytes, this loop iterates in reverse order.
+ for i in reversed(range(0, 10)):
+ builder.PrependByte(i)
+ inv = builder.EndVector(10)
+
+ MyGame.Sample.Monster.MonsterStartWeaponsVector(builder, 2)
+ # Note: Since we prepend the data, prepend the weapons in reverse order.
+ builder.PrependUOffsetTRelative(axe)
+ builder.PrependUOffsetTRelative(sword)
+ weapons = builder.EndVector(2)
+
+ pos = MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0)
+
+ MyGame.Sample.Monster.MonsterStart(builder)
+ MyGame.Sample.Monster.MonsterAddPos(builder, pos)
+ MyGame.Sample.Monster.MonsterAddHp(builder, 300)
+ MyGame.Sample.Monster.MonsterAddName(builder, name)
+ MyGame.Sample.Monster.MonsterAddInventory(builder, inv)
+ MyGame.Sample.Monster.MonsterAddColor(builder,
+ MyGame.Sample.Color.Color().Red)
+ MyGame.Sample.Monster.MonsterAddWeapons(builder, weapons)
+ MyGame.Sample.Monster.MonsterAddEquippedType(
+ builder, MyGame.Sample.Equipment.Equipment().Weapon)
+ MyGame.Sample.Monster.MonsterAddEquipped(builder, axe)
+ orc = MyGame.Sample.Monster.MonsterEnd(builder)
+
+ builder.Finish(orc)
+
+ # We now have a FlatBuffer that we could store on disk or send over a network.
+
+ # ...Saving to file or sending over a network code goes here...
+
+ # Instead, we are going to access this buffer right away (as if we just
+ # received it).
+
+ buf = builder.Output()
+
+ # Note: We use `0` for the offset here, since we got the data using the
+ # `builder.Output()` method. This simulates the data you would store/receive
+ # in your FlatBuffer. If you wanted to read from the `builder.Bytes` directly,
+ # you would need to pass in the offset of `builder.Head()`, as the builder
+ # actually constructs the buffer backwards.
+ monster = MyGame.Sample.Monster.Monster.GetRootAsMonster(buf, 0)
+
+ # Note: We did not set the `Mana` field explicitly, so we get a default value.
+ assert monster.Mana() == 150
+ assert monster.Hp() == 300
+ assert monster.Name() == 'Orc'
+ assert monster.Color() == MyGame.Sample.Color.Color().Red
+ assert monster.Pos().X() == 1.0
+ assert monster.Pos().Y() == 2.0
+ assert monster.Pos().Z() == 3.0
+
+ # Get and test the `inventory` FlatBuffer `vector`.
+ for i in xrange(monster.InventoryLength()):
+ assert monster.Inventory(i) == i
+
+ # Get and test the `weapons` FlatBuffer `vector` of `table`s.
+ expected_weapon_names = ['Sword', 'Axe']
+ expected_weapon_damages = [3, 5]
+ for i in xrange(monster.WeaponsLength()):
+ assert monster.Weapons(i).Name() == expected_weapon_names[i]
+ assert monster.Weapons(i).Damage() == expected_weapon_damages[i]
+
+ # Get and test the `equipped` FlatBuffer `union`.
+ assert monster.EquippedType() == MyGame.Sample.Equipment.Equipment().Weapon
+
+ # An example of how you can appropriately convert the table depending on the
+ # FlatBuffer `union` type. You could add `elif` and `else` clauses to handle
+ # the other FlatBuffer `union` types for this field.
+ if monster.EquippedType() == MyGame.Sample.Equipment.Equipment().Weapon:
+ # `monster.Equipped()` returns a `flatbuffers.Table`, which can be used
+ # to initialize a `MyGame.Sample.Weapon.Weapon()`, in this case.
+ union_weapon = MyGame.Sample.Weapon.Weapon()
+ union_weapon.Init(monster.Equipped().Bytes, monster.Equipped().Pos)
+
+ assert union_weapon.Name() == "Axe"
+ assert union_weapon.Damage() == 5
+
+ print 'The FlatBuffer was successfully created and verified!'
+
+if __name__ == '__main__':
+ main()
diff --git a/samples/sample_text.cpp b/samples/sample_text.cpp
index e1a3bf7e7..557077d4b 100644
--- a/samples/sample_text.cpp
+++ b/samples/sample_text.cpp
@@ -14,11 +14,10 @@
* limitations under the License.
*/
-#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
-#include "monster_generated.h"
+#include "monster_generated.h" // Already includes "flatbuffers/flatbuffers.h".
using namespace MyGame::Sample;
@@ -52,4 +51,6 @@ int main(int /*argc*/, const char * /*argv*/[]) {
if (jsongen != jsonfile) {
printf("%s----------------\n%s", jsongen.c_str(), jsonfile.c_str());
}
+
+ printf("The FlatBuffer has been parsed from JSON successfully.\n");
}
diff --git a/samples/samplebinary.js b/samples/samplebinary.js
new file mode 100644
index 000000000..9c8c90892
--- /dev/null
+++ b/samples/samplebinary.js
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2015 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// To run, use the `javascript_sample.sh` script.
+
+var assert = require('assert');
+var flatbuffers = require('../js/flatbuffers').flatbuffers;
+var MyGame = require('./monster_generated').MyGame;
+
+// Example how to use FlatBuffers to create and read binary buffers.
+function main() {
+ var builder = new flatbuffers.Builder(0);
+
+ // Create some weapons for our Monster ('Sword' and 'Axe').
+ var weaponOne = builder.createString('Sword');
+ var weaponTwo = builder.createString('Axe');
+
+ MyGame.Sample.Weapon.startWeapon(builder);
+ MyGame.Sample.Weapon.addName(builder, weaponOne);
+ MyGame.Sample.Weapon.addDamage(builder, 3);
+ var sword = MyGame.Sample.Weapon.endWeapon(builder);
+
+ MyGame.Sample.Weapon.startWeapon(builder);
+ MyGame.Sample.Weapon.addName(builder, weaponTwo);
+ MyGame.Sample.Weapon.addDamage(builder, 5);
+ var axe = MyGame.Sample.Weapon.endWeapon(builder);
+
+ // Serialize the FlatBuffer data.
+ var name = builder.createString('Orc');
+
+ var treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ var inv = MyGame.Sample.Monster.createInventoryVector(builder, treasure);
+
+ var weaps = [sword, axe];
+ var weapons = MyGame.Sample.Monster.createWeaponsVector(builder, weaps);
+
+ var pos = MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0);
+
+ MyGame.Sample.Monster.startMonster(builder);
+ MyGame.Sample.Monster.addPos(builder, pos);
+ MyGame.Sample.Monster.addHp(builder, 300);
+ MyGame.Sample.Monster.addColor(builder, MyGame.Sample.Color.Red)
+ MyGame.Sample.Monster.addName(builder, name);
+ MyGame.Sample.Monster.addInventory(builder, inv);
+ MyGame.Sample.Monster.addWeapons(builder, weapons);
+ MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Equipment.Weapon);
+ MyGame.Sample.Monster.addEquipped(builder, weaps[1]);
+ var orc = MyGame.Sample.Monster.endMonster(builder);
+
+ builder.finish(orc); // You may also call 'MyGame.Example.Monster.finishMonsterBuffer(builder, orc);'.
+
+ // We now have a FlatBuffer that can be stored on disk or sent over a network.
+
+ // ...Code to store to disk or send over a network goes here...
+
+ // Instead, we are going to access it right away, as if we just received it.
+
+ var buf = builder.dataBuffer();
+
+ // Get access to the root:
+ var monster = MyGame.Sample.Monster.getRootAsMonster(buf);
+
+ // Note: We did not set the `mana` field explicitly, so we get back the default value.
+ assert.equal(monster.mana(), 150);
+ assert.equal(monster.hp(), 300);
+ assert.equal(monster.name(), 'Orc');
+ assert.equal(monster.color(), MyGame.Sample.Color.Red);
+ assert.equal(monster.pos().x(), 1.0);
+ assert.equal(monster.pos().y(), 2.0);
+ assert.equal(monster.pos().z(), 3.0);
+
+ // Get and test the `inventory` FlatBuffer `vector`.
+ for (var i = 0; i < monster.inventoryLength(); i++) {
+ assert.equal(monster.inventory(i), i);
+ }
+
+ // Get and test the `weapons` FlatBuffer `vector` of `table`s.
+ var expectedWeaponNames = ['Sword', 'Axe'];
+ var expectedWeaponDamages = [3, 5];
+ for (var i = 0; i < monster.weaponsLength(); i++) {
+ assert.equal(monster.weapons(i).name(), expectedWeaponNames[i]);
+ assert.equal(monster.weapons(i).damage(), expectedWeaponDamages[i]);
+ }
+
+ // Get and test the `equipped` FlatBuffer `union`.
+ assert.equal(monster.equippedType(), MyGame.Sample.Equipment.Weapon);
+ assert.equal(monster.equipped(new MyGame.Sample.Weapon()).name(), 'Axe');
+ assert.equal(monster.equipped(new MyGame.Sample.Weapon()).damage(), 5);
+
+ console.log('The FlatBuffer was successfully created and verified!');
+}
+
+main();
diff --git a/tests/FlatBuffers.Test/Resources/monsterdata_test.mon b/tests/FlatBuffers.Test/Resources/monsterdata_test.mon
new file mode 100644
index 000000000..2bf6d1586
Binary files /dev/null and b/tests/FlatBuffers.Test/Resources/monsterdata_test.mon differ