mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-10 07:06:26 +00:00
Added accessor in Java to get vectors as ByteBuffers.
Also cleaned up ByteBuffer usage in general: ByteBuffer.position now universally indicates the start of a ByteBuffer. Change-Id: Ic4bfb98f9df9501b8fc82de2c45db7d7311135ac Tested: on Linux.
This commit is contained in:
@@ -60,10 +60,11 @@ Monster monster = Monster.getRootAsMonster(bb);
|
||||
Vec3 pos = monster.pos();
|
||||
</pre><p>Note that whenever you access a new object like in the <code>pos</code> example above, a new temporary accessor object gets created. If your code is very performance sensitive (you iterate through a lot of objects), there's a second <code>pos()</code> method to which you can pass a <code>Vec3</code> object you've already created. This allows you to reuse it across many calls and reduce the amount of object allocation (and thus garbage collection) your program does.</p>
|
||||
<p>Java does not support unsigned scalars. This means that any unsigned types you use in your schema will actually be represented as a signed value. This means all bits are still present, but may represent a negative value when used. For example, to read a <code>byte b</code> as an unsigned number, you can do: <code>(short)(b & 0xFF)</code></p>
|
||||
<p>Sadly the string accessors currently always create a new string when accessed, since FlatBuffer's UTF-8 strings can't be read in-place by Java.</p>
|
||||
<p>The default string accessor (e.g. <code>monster.name()</code>) currently always create a new Java <code>String</code> when accessed, since FlatBuffer's UTF-8 strings can't be used in-place by <code>String</code>. Alternatively, use <code>monster.nameAsByteBuffer()</code> which returns a <code>ByteBuffer</code> referring to the UTF-8 data in the original <code>ByteBuffer</code>, which is much more efficient. The <code>ByteBuffer</code>'s <code>position</code> points to the first character, and its <code>limit</code> to just after the last.</p>
|
||||
<p>Vector access is also a bit different from C++: you pass an extra index to the vector field accessor. Then a second method with the same name suffixed by <code>Length</code> let's you know the number of elements you can access: </p><pre class="fragment">for (int i = 0; i < monster.inventoryLength(); i++)
|
||||
monster.inventory(i); // do something here
|
||||
</pre><p>If you specified a file_indentifier in the schema, you can query if the buffer is of the desired type before accessing it using: </p><pre class="fragment">if (Monster.MonsterBufferHasIdentifier(bb, start)) ...
|
||||
</pre><p>Alternatively, much like strings, you can use <code>monster.inventoryAsByteBuffer()</code> to get a <code>ByteBuffer</code> referring to the whole vector. Use <code>ByteBuffer</code> methods like <code>asFloatBuffer</code> to get specific views if needed.</p>
|
||||
<p>If you specified a file_indentifier in the schema, you can query if the buffer is of the desired type before accessing it using: </p><pre class="fragment">if (Monster.MonsterBufferHasIdentifier(bb)) ...
|
||||
</pre><h2>Buffer construction in Java</h2>
|
||||
<p>You can also construct these buffers in Java using the static methods found in the generated code, and the FlatBufferBuilder class: </p><pre class="fragment">FlatBufferBuilder fbb = new FlatBufferBuilder();
|
||||
</pre><p>Create strings: </p><pre class="fragment">int str = fbb.createString("MyMonster");
|
||||
@@ -86,7 +87,7 @@ int inv = fbb.endVector();
|
||||
</pre><p>You can use the generated method <code>startInventoryVector</code> to conveniently call <code>startVector</code> with the right element size. You pass the number of elements you want to write. You write the elements backwards since the buffer is being constructed back to front.</p>
|
||||
<p>There are <code>add</code> functions for all the scalar types. You use <code>addOffset</code> for any previously constructed objects (such as other tables, strings, vectors). For structs, you use the appropriate <code>create</code> function in-line, as shown above in the <code>Monster</code> example.</p>
|
||||
<p>To finish the buffer, call: </p><pre class="fragment">Monster.finishMonsterBuffer(fbb, mon);
|
||||
</pre><p>The buffer is now ready to be transmitted. It is contained in the <code>ByteBuffer</code> which you can obtain from <code>fbb.dataBuffer()</code>. Importantly, the valid data does not start from offset 0 in this buffer, but from <code>fbb.dataStart()</code> (this is because the data was built backwards in memory). It ends at <code>fbb,capacity()</code>.</p>
|
||||
</pre><p>The buffer is now ready to be transmitted. It is contained in the <code>ByteBuffer</code> which you can obtain from <code>fbb.dataBuffer()</code>. Importantly, the valid data does not start from offset 0 in this buffer, but from <code>fbb.dataBuffer().position()</code> (this is because the data was built backwards in memory). It ends at <code>fbb.capacity()</code>.</p>
|
||||
<h2>Text Parsing</h2>
|
||||
<p>There currently is no support for parsing text (Schema's and JSON) directly from Java, though you could use the C++ parser through JNI. Please see the C++ documentation for more on text parsing. </p>
|
||||
</div></div><!-- contents -->
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Use in Java
|
||||
|
||||
FlatBuffers supports reading and writing binary FlatBuffers in Java. Generate code
|
||||
for Java with the `-j` option to `flatc`.
|
||||
FlatBuffers supports reading and writing binary FlatBuffers in Java. Generate
|
||||
code for Java with the `-j` option to `flatc`.
|
||||
|
||||
See `javaTest.java` for an example. Essentially, you read a FlatBuffer binary
|
||||
file into a `byte[]`, which you then turn into a `ByteBuffer`, which you pass to
|
||||
@@ -19,8 +19,8 @@ Note that whenever you access a new object like in the `pos` example above,
|
||||
a new temporary accessor object gets created. If your code is very performance
|
||||
sensitive (you iterate through a lot of objects), there's a second `pos()`
|
||||
method to which you can pass a `Vec3` object you've already created. This allows
|
||||
you to reuse it across many calls and reduce the amount of object allocation (and
|
||||
thus garbage collection) your program does.
|
||||
you to reuse it across many calls and reduce the amount of object allocation
|
||||
(and thus garbage collection) your program does.
|
||||
|
||||
Java does not support unsigned scalars. This means that any unsigned types you
|
||||
use in your schema will actually be represented as a signed value. This means
|
||||
@@ -28,8 +28,12 @@ all bits are still present, but may represent a negative value when used.
|
||||
For example, to read a `byte b` as an unsigned number, you can do:
|
||||
`(short)(b & 0xFF)`
|
||||
|
||||
Sadly the string accessors currently always create a new string when accessed,
|
||||
since FlatBuffer's UTF-8 strings can't be read in-place by Java.
|
||||
The default string accessor (e.g. `monster.name()`) currently always create
|
||||
a new Java `String` when accessed, since FlatBuffer's UTF-8 strings can't be
|
||||
used in-place by `String`. Alternatively, use `monster.nameAsByteBuffer()`
|
||||
which returns a `ByteBuffer` referring to the UTF-8 data in the original
|
||||
`ByteBuffer`, which is much more efficient. The `ByteBuffer`'s `position`
|
||||
points to the first character, and its `limit` to just after the last.
|
||||
|
||||
Vector access is also a bit different from C++: you pass an extra index
|
||||
to the vector field accessor. Then a second method with the same name
|
||||
@@ -38,10 +42,14 @@ suffixed by `Length` let's you know the number of elements you can access:
|
||||
for (int i = 0; i < monster.inventoryLength(); i++)
|
||||
monster.inventory(i); // do something here
|
||||
|
||||
Alternatively, much like strings, you can use `monster.inventoryAsByteBuffer()`
|
||||
to get a `ByteBuffer` referring to the whole vector. Use `ByteBuffer` methods
|
||||
like `asFloatBuffer` to get specific views if needed.
|
||||
|
||||
If you specified a file_indentifier in the schema, you can query if the
|
||||
buffer is of the desired type before accessing it using:
|
||||
|
||||
if (Monster.MonsterBufferHasIdentifier(bb, start)) ...
|
||||
if (Monster.MonsterBufferHasIdentifier(bb)) ...
|
||||
|
||||
|
||||
## Buffer construction in Java
|
||||
@@ -105,8 +113,9 @@ To finish the buffer, call:
|
||||
|
||||
The buffer is now ready to be transmitted. It is contained in the `ByteBuffer`
|
||||
which you can obtain from `fbb.dataBuffer()`. Importantly, the valid data does
|
||||
not start from offset 0 in this buffer, but from `fbb.dataStart()` (this is
|
||||
because the data was built backwards in memory). It ends at `fbb,capacity()`.
|
||||
not start from offset 0 in this buffer, but from `fbb.dataBuffer().position()`
|
||||
(this is because the data was built backwards in memory).
|
||||
It ends at `fbb.capacity()`.
|
||||
|
||||
|
||||
## Text Parsing
|
||||
|
||||
Reference in New Issue
Block a user