From f9025eeb52110546d5f06f189b63ed084fe78eb0 Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Mon, 10 Oct 2016 17:09:37 -0700 Subject: [PATCH] Clarified tutorial w.r.t reading/writing buffers. Bug: 30736848 Signed-off-by: Wouter van Oortmerssen --- docs/source/Tutorial.md | 77 +++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 41 deletions(-) diff --git a/docs/source/Tutorial.md b/docs/source/Tutorial.md index c71a9fad1..b97906465 100644 --- a/docs/source/Tutorial.md +++ b/docs/source/Tutorial.md @@ -1231,6 +1231,11 @@ like so: ~~~ +Now you can write the bytes to a file, send them over the network.. +**Make sure your file mode (or tranfer protocol) is set to BINARY, not text.** +If you transfer a FlatBuffer in text mode, the buffer will be corrupted, +which will lead to hard to find problems when you read the buffer. + #### Reading Orc FlatBuffers Now that we have successfully created an `Orc` FlatBuffer, the monster data can @@ -1326,92 +1331,82 @@ before: ~~~ -Then, assuming you have a variable containing to the bytes of data from disk, -network, etc., you can create a monster from this data: +Then, assuming you have a buffer of bytes received from disk, +network, etc., you can create start accessing the buffer like so: + +**Again, make sure you read the bytes in BINARY mode, otherwise the code below +won't work**
~~~{.cpp} - // We can access the buffer we just made directly. Pretend this came over a - // network, was read off of disk, etc. - auto buffer_pointer = builder.GetBufferPointer(); + uint8_t *buffer_pointer = /* the data you just read */; - // Deserialize the data from the buffer. + // Get a pointer to the root object inside the buffer. auto monster = GetMonster(buffer_pointer); - // `monster` is of type`Monster *`, and points to somewhere inside the buffer. - + // `monster` is of type `Monster *`. // Note: root object pointers are NOT the same as `buffer_pointer`. ~~~
~~~{.java} - // We can access the buffer we just made directly. Pretend this came over a - // network, was read off of disk, etc. - java.nio.ByteBuffer buf = builder.dataBuffer(); + byte[] bytes = /* the data you just read */ + java.nio.ByteBuffer buf = java.nio.ByteBuffer.wrap(bytes); - // Deserialize the data from the buffer. + // Get an accessor to the root object inside the buffer. Monster monster = Monster.getRootAsMonster(buf); ~~~
~~~{.cs} - // We can access the buffer we just made directly. Pretend this came over a - // network, was read off of disk, etc. - var buf = builder.DataBuffer; + byte[] bytes = /* the data you just read */ + var buf = new ByteBuffer(bytes); - // Deserialize the data from the buffer. + // Get an accessor to the root object inside the buffer. var monster = Monster.GetRootAsMonster(buf); ~~~
~~~{.go} - // We can access the buffer we just made directly. Pretend this came over a - // network, was read off of disk, etc. - buf := builder.FinishedBytes() + var buf []byte = /* the data you just read */ - // Deserialize the data from the buffer. + // Get an accessor to the root object inside the buffer. monster := sample.GetRootAsMonster(buf, 0) - // 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. + // Note: We use `0` for the offset here, which is typical for most buffers + // you would read. If you wanted to read from `builder.Bytes` directly, you + // would need to pass in the offset of `builder.Head()`, as the builder + // constructs the buffer backwards, so may not start at offset 0. ~~~
~~~{.py} - # We can access the buffer we just made directly. Pretend this came over a - # network, was read off of disk, etc. - buf = builder.Output() + buf = /* the data you just read, in an object of type "bytearray" */ - # Deserialize the data from the buffer. + // Get an accessor to the root object inside the buffer. monster = MyGame.Sample.Monster.Monster.GetRootAsMonster(buf, 0) - # 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, + # Note: We use `0` for the offset here, which is typical for most buffers + # you would read. 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. + # constructs the buffer backwards, so may not start at offset 0. ~~~
~~~{.js} - // We can access the buffer we just made directly. Pretend this came over a - // network, was read off of disk, etc. - var buf = builder.dataBuffer(); + var bytes = /* the data you just read, in an object of type "Uint8Array" */ + var buf = new flatbuffers.ByteBuffer(bytes); - // Deserialize the data from the buffer. + // Get an accessor to the root object inside the buffer. var monster = MyGame.Sample.Monster.getRootAsMonster(buf); ~~~
~~~{.php} - // We can access the buffer we just made directly. Pretend this came over a - // network, was read off of disk, etc. - $buf = $builder->dataBuffer(); + $bytes = /* the data you just read, in a string */ + $buf = Google\FlatBuffers\ByteBuffer::wrap($bytes); - // Deserialize the data from the buffer. + // Get an accessor to the root object inside the buffer. $monster = \MyGame\Sample\Monster::GetRootAsMonster($buf); ~~~