This commit is contained in:
Piper Merriam 2019-03-20 09:04:55 -06:00
parent 1ab501975c
commit ca98d752d2
No known key found for this signature in database
GPG Key ID: 8D2265D5CEBE822F
1 changed files with 23 additions and 29 deletions

View File

@ -81,7 +81,7 @@ return b"\x01" if value is True else b"\x00"
### Composite Types (Vectors, Containers and Lists) ### Composite Types (Vectors, Containers and Lists)
The serialized representation of composite types is comprised of two binary segments. The serialized representation of composite types is comprised of two binary sections.
* The first section is *fixed size* for all types, containing the concatenation of *either* * The first section is *fixed size* for all types, containing the concatenation of *either*
- The serialized representation for each of the *fixed size* elements of value - The serialized representation for each of the *fixed size* elements of value
@ -97,41 +97,35 @@ An implementation of the `serialize` function for `"Vector"`, `"Container"` and
```python ```python
# The second section is just the concatenation of the serialized *variable size* elements # The second section is just the concatenation of the serialized *variable size* elements
section_2_parts = [serialize(element) for element in value if is_variable_size(element)] section_2_parts = [
serialize(element) if is_variable_size(element)
else ''
for element in value
]
section_2_lengths = [len(part) for part in section_2_parts] section_2_lengths = [len(part) for part in section_2_parts]
section_2 ''.join(section_2_parts) section_2 = ''.join(section_2_parts)
# Serialize the *fixed size* elements # Compute the length of the first section (can also be extracted from the type directly)
section_1_fixed_parts = [serialize(element) for element in value if is_fixed_size(element)] section_1_length = sum(
len(serialize(element)) if is_fixed_size(element)
# Compute the length of the first section else 4
section_1_length = sum(len(part) for part in section_1_fixed_parts) + 4 * len(section_2_parts) for element in value
)
# Compute the offset values for each part of the second section # Compute the offset values for each part of the second section
section_1_offsets = [ section_1_offsets = [
section_1_length + sum(section_2_lengths[:index]) section_1_length + sum(section_2_lengths[:element_index]) if is_variable_size(element)
for index in range(len(section_2_parts)) else None
for element_index, element in enumerate(value)
] ]
assert all(offset < 2**32 for offset in section_1_offsets) assert all(offset is None or offset < 2**32 for offset in section_1_offsets)
# compute the appropriate indices for *fixed size* elements for the first section # The first section is the concatenation of the serialized static size elements and offsets
fixed_size_element_indices = [index for index, element in enumerate(value) if is_fixed_size(element)] section_1_parts = [
serialize(element) if is_fixed_size(element)
# compute the appropriate indices for the offsets of the *variable size* elements else serialize(section_1_offsets[element_index])
variable_size_element_indices = [index for index, element in enumerate(value) if is_variable_size(element)] for element_index, element in enumerate(value)
]
# create a list with placeholders for all values
section_1_parts = [None] * len(value)
# populate all of the serialized *fixed size* elements
for index, data in zip(fixed_size_element_indices, section_1_fixed_parts):
section_1_parts[index] = data
# populate all of the serialized offsets for the *variable size* elements
for index, offset in zip(variable_size_element_indices, section_1_offsets):
section_1_parts[index] = serialize(offset)
assert not any(part is None for part in section_1_parts)
section_1 = ''.join(section_1_parts) section_1 = ''.join(section_1_parts)
return ''.join([section_1, section_2]) return ''.join([section_1, section_2])