aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorWouter van Oortmerssen <wvo@google.com>2015-04-27 16:25:06 -0700
committerWouter van Oortmerssen <wvo@google.com>2015-04-29 10:58:45 -0700
commit3ec5dddb00dac9ae72a2f6808ed28b06cb64cdab (patch)
tree9d2e77ad028bd5d2cd2d6a1cd4249cdf68ca9585 /docs
parenta8d6962ac2fbf5075ee5f58877d488eb74ed32df (diff)
downloadflatbuffers-3ec5dddb00dac9ae72a2f6808ed28b06cb64cdab.tar.gz
Mutable FlatBuffers: in-place updates.
This commit contains the first step in providing mutable FlatBuffers, non-const accessors and mutation functions for existing fields generated from --gen-mutable. Change-Id: Iebee3975f05c1001f8e22824725edeaa6d85fbee Tested: on Linux. Bug: 15777024
Diffstat (limited to 'docs')
-rw-r--r--docs/html/md__compiler.html1
-rw-r--r--docs/html/md__cpp_usage.html16
-rwxr-xr-xdocs/source/Compiler.md3
-rwxr-xr-xdocs/source/CppUsage.md49
4 files changed, 68 insertions, 1 deletions
diff --git a/docs/html/md__compiler.html b/docs/html/md__compiler.html
index 03cae793..e6ee2b06 100644
--- a/docs/html/md__compiler.html
+++ b/docs/html/md__compiler.html
@@ -70,6 +70,7 @@ $(document).ready(function(){initNavTree('md__compiler.html','');});
<li><code>--strict-json</code> : Require &amp; generate strict JSON (field names are enclosed in quotes, no trailing commas in tables/vectors). By default, no quotes are required/generated, and trailing commas are allowed.</li>
<li><code>--no-prefix</code> : Don't prefix enum values in generated C++ by their enum type.</li>
<li><code>--gen-includes</code> : Generate include statements for included schemas the generated file depends on (C++).</li>
+<li><code>--gen-mutable</code> : Generate additional non-const accessors for mutating FlatBuffers in-place.</li>
<li><code>--proto</code>: Expect input files to be .proto files (protocol buffers). Output the corresponding .fbs file. Currently supports: <code>package</code>, <code>message</code>, <code>enum</code>. Does not support, but will skip without error: <code>import</code>, <code>option</code>. Does not support, will generate error: <code>service</code>, <code>extend</code>, <code>extensions</code>, <code>oneof</code>, <code>group</code>, custom options, nested declarations. </li>
</ul>
</div></div><!-- contents -->
diff --git a/docs/html/md__cpp_usage.html b/docs/html/md__cpp_usage.html
index b21e0918..2217273d 100644
--- a/docs/html/md__cpp_usage.html
+++ b/docs/html/md__cpp_usage.html
@@ -102,7 +102,21 @@ $(document).ready(function(){initNavTree('md__cpp_usage.html','');});
<div class="fragment"><div class="line"><span class="keyword">auto</span> inv = monster-&gt;inventory();</div>
<div class="line">assert(inv);</div>
<div class="line">assert(inv-&gt;Get(9) == 9);</div>
-</div><!-- fragment --><h3>Storing maps / dictionaries in a FlatBuffer</h3>
+</div><!-- fragment --><h3>Mutating FlatBuffers</h3>
+<p>As you saw above, typically once you have created a FlatBuffer, it is read-only from that moment on. There are however cases where you have just received a FlatBuffer, and you'd like to modify something about it before sending it on to another recipient. With the above functionality, you'd have to generate an entirely new FlatBuffer, while tracking what you modify in your own data structures. This is inconvenient.</p>
+<p>For this reason FlatBuffers can also be mutated in-place. While this is great for making small fixes to an existing buffer, you generally want to create buffers from scratch whenever possible, since it is much more efficient and the API is much more general purpose.</p>
+<p>To get non-const accessors, invoke <code>flatc</code> with <code>--gen-mutable</code>.</p>
+<p>Similar to the reading API above, you now can:</p>
+<div class="fragment"><div class="line"><span class="keyword">auto</span> monster = GetMutableMonster(buffer_pointer); <span class="comment">// non-const</span></div>
+<div class="line">monster-&gt;mutate_hp(10); <span class="comment">// Set table field.</span></div>
+<div class="line">monster-&gt;mutable_pos()-&gt;mutate_z(4); <span class="comment">// Set struct field.</span></div>
+<div class="line">monster-&gt;mutable_inventory()-&gt;Mutate(0, 1); <span class="comment">// Set vector element.</span></div>
+</div><!-- fragment --><p>We use the somewhat verbose term <code>mutate</code> instead of <code>set</code> to indicate that this is a special use case, not to be confused with the default way of constructing FlatBuffer data.</p>
+<p>After the above mutations, you can send on the FlatBuffer to a new recipient without any further work!</p>
+<p>Note that any <code>mutate_</code> functions on tables return a bool, which is false if the field we're trying to set isn't present in the buffer. Fields are not present if they weren't set, or even if they happen to be equal to the default value. For example, in the creation code above we set the <code>mana</code> field to <code>150</code>, which is the default value, so it was never stored in the buffer. Trying to call mutate_mana() on such data will return false, and the value won't actually be modified!</p>
+<p>There's two ways around this. First, you can call <code>ForceDefaults()</code> on a <code>FlatBufferBuilder</code> to force all fields you set to actually be written. This of course increases the size of the buffer somewhat, but this may be acceptable for a mutable buffer.</p>
+<p>Alternatively, you can use mutation functions that are able to insert fields and change the size of things. These functions are expensive however, since they need to resize the buffer and create new data.</p>
+<h3>Storing maps / dictionaries in a FlatBuffer</h3>
<p>FlatBuffers doesn't support maps natively, but there is support to emulate their behavior with vectors and binary search, which means you can have fast lookups directly from a FlatBuffer without having to unpack your data into a <code>std::map</code> or similar.</p>
<p>To use it:</p><ul>
<li>Designate one of the fields in a table as they "key" field. You do this by setting the <code>key</code> attribute on this field, e.g. <code>name:string (key)</code>. You may only have one key field, and it must be of string or scalar type.</li>
diff --git a/docs/source/Compiler.md b/docs/source/Compiler.md
index f6ae0813..6a73bb7c 100755
--- a/docs/source/Compiler.md
+++ b/docs/source/Compiler.md
@@ -51,6 +51,9 @@ be generated for each file processed:
- `--gen-includes` : Generate include statements for included schemas the
generated file depends on (C++).
+- `--gen-mutable` : Generate additional non-const accessors for mutating
+ FlatBuffers in-place.
+
- `--proto`: Expect input files to be .proto files (protocol buffers).
Output the corresponding .fbs file.
Currently supports: `package`, `message`, `enum`.
diff --git a/docs/source/CppUsage.md b/docs/source/CppUsage.md
index 9112b392..01576e20 100755
--- a/docs/source/CppUsage.md
+++ b/docs/source/CppUsage.md
@@ -163,6 +163,55 @@ Similarly, we can access elements of the inventory array:
assert(inv->Get(9) == 9);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+### Mutating FlatBuffers
+
+As you saw above, typically once you have created a FlatBuffer, it is
+read-only from that moment on. There are however cases where you have just
+received a FlatBuffer, and you'd like to modify something about it before
+sending it on to another recipient. With the above functionality, you'd have
+to generate an entirely new FlatBuffer, while tracking what you modify in your
+own data structures. This is inconvenient.
+
+For this reason FlatBuffers can also be mutated in-place. While this is great
+for making small fixes to an existing buffer, you generally want to create
+buffers from scratch whenever possible, since it is much more efficient and
+the API is much more general purpose.
+
+To get non-const accessors, invoke `flatc` with `--gen-mutable`.
+
+Similar to the reading API above, you now can:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
+ auto monster = GetMutableMonster(buffer_pointer); // non-const
+ monster->mutate_hp(10); // Set table field.
+ monster->mutable_pos()->mutate_z(4); // Set struct field.
+ monster->mutable_inventory()->Mutate(0, 1); // Set vector element.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We use the somewhat verbose term `mutate` instead of `set` to indicate that
+this is a special use case, not to be confused with the default way of
+constructing FlatBuffer data.
+
+After the above mutations, you can send on the FlatBuffer to a new recipient
+without any further work!
+
+Note that any `mutate_` functions on tables return a bool, which is false
+if the field we're trying to set isn't present in the buffer. Fields are not
+present if they weren't set, or even if they happen to be equal to the
+default value. For example, in the creation code above we set the `mana` field
+to `150`, which is the default value, so it was never stored in the buffer.
+Trying to call mutate_mana() on such data will return false, and the value won't
+actually be modified!
+
+There's two ways around this. First, you can call `ForceDefaults()` on a
+`FlatBufferBuilder` to force all fields you set to actually be written. This
+of course increases the size of the buffer somewhat, but this may be
+acceptable for a mutable buffer.
+
+Alternatively, you can use mutation functions that are able to insert fields
+and change the size of things. These functions are expensive however, since
+they need to resize the buffer and create new data.
+
### Storing maps / dictionaries in a FlatBuffer
FlatBuffers doesn't support maps natively, but there is support to