Browse Source

WIP: Examples of FAST

master
Julio Biason 2 years ago
parent
commit
9389ed667c
  1. 79
      content/research/decoding-fast-examples.md

79
content/research/decoding-fast-examples.md

@ -1,6 +1,6 @@
+++
title = "Decoding the FAST Protocol: Examples"
date = 2022-01-10
date = 2022-01-11
draft = true
[taxonomies]
@ -98,7 +98,7 @@ Let's expand our example to have a sequence and a few more operators:
<length name="NoInnerSequence" id="25"/>
<string name="Username" id="4"/>
<uInt32 name="ID" id="32" presence="optional">
<delta/>
<increment/>
</uInt32>
</sequence>
</sequence>
@ -114,7 +114,80 @@ list of users and their IDs.
## Incoming Data
```
1100_0000 1000_0010
1100_0000 1000_0010 1000_0011 0000_0011
0010_0011 0001_1000 1110_0111 1000_0010
1100_0000 0101_0101 0111_0011 0110_0101
0111_0010 1011_0001 1000_0100 1000_0000
0101_0101 0111_0011 0110_0101 0111_0010
1011_0010
```
## Processing
As mentioned before, the first byte, `1100_0000` is the Presence Map of the
root element with the leading Template ID. There is only one bit set, which
means the Template ID is present.
The second byte, `1000_0010` is the Template ID. Because it have the stop bit,
that's the only byte for it. Removing the high order bit gives us `000_0010`,
which is "2", so we know we are dealing with the "SequenceOfSequences"
template.
Now that we have the template and know the fields, we know what to read. The
first field in our template is the sequence. The first thing we have in the
sequence (and this is the first thing for *every* sequence) is the length of
it. So we read the next byte, `1000_0011`, which is the only byte we need to
read. It represents an unsigned int, which is "3", so this sequence have 3
elements -- and using our description in the previous sections, we know now
that we have 3 groups.
One point here: Because all fields in this sequence don't have any operators,
it means the Presence Map doesn't exist. For sequences, every start of a new
record contains a Presence Map only if at least one of the fields in the
sequence require a Presence Map. That's not the case here.
Because there is no Presence Map for the "OuterSequence", the next bytes are
the "GroupID" field. We should read everything till we find the stop bit, so we
get `0000_0011`, `0010_0011`, `0001_1000` and `1110_0111`. For every byte we
remove the high order bit and then join everything into a single thing, in this
case `000_0011 010_0011 001_1000 110_0111` or simply
`0000_0110_1000_1100_1100_0110_0111`; this value, being an unsigned int, is
"6868070". Here is a good point to remind that, because the field is mandatory,
it means that's actually the value of "GroupID"; if the field as optional, the
actual value would be "6868069".
Now for he "InnerSequence" field. The first step is to gather the number of
elements (the length of the sequence). That's the `1000_0010` byte, which is
"2". So there are two users in this group.
Because "InnerSequence" has a field that uses the Presence Map ("ID" uses the
Increment operator, so we need to check if there is an incoming value for it or
we should just increment the value), the first thing after the length is the
Presence Map for this record. The byte `1100_0000` indicates that the first
field that requires a Presence Map is present.
But that's not the time to use the Presence Map yet. The field after the length
is the "Username", which is a mandatory string. Mandatory strings with no
operators are always present and we don't need to check the map. Same as we did
with "String" in the example for Hello World, we read the bytes till the stop
bit, but don't merge them: `0101_0101` (85), `0111_0011` (115), `0110_0101`
(101), `0111_0010` (114) and `1011_0001` (49, if we remove the stop bit, that
is), which converted by the ASCII table gives us "User1".
Remember that we jumped the Presence Map? Now it is the time to use it, since
we are reading "ID" and it has an operator that requires the Presence Map. The
Presence Map we read before was `100_0000` (with the stop bit removed), so
yeah, the "ID" is present. We read the next byte, `1000_0100`, which is "4".
But there is a gotcha here: The field is optional. So although we read "4", the
actual value is "3" -- if the value read was "0" it meant that the ID is Null.
Good. We just finished reading the first record of "InnerSequence". Now we read
the second record.
We don't need to read the length again, but we need to read the Presence Map
for this record. It is the byte `1000_0000`, a Presence Map indicating that
none of the fields with operators are present. But, again, it is not the time
for the Presence Map, but for the "Username". The bytes for the field are
`0101_0101` (85), `0111_0011` (115), `0110_0101` (101), `0111_0010` (114) and
`1011_0001` (50), which is "User2".

Loading…
Cancel
Save