Structure¶
KonFoo has a Structure
class and many field classes to
declare the mapping part of a byte stream mapper.
The order how you declare the members in the
structure defines the order how the members are
deserialized and serialized by the built-in deserializer and serializer.
Member¶
A structure member can be any field or container class.
Define a Structure¶
You can define members of a structure by adding them in the
constructor method of the Structure
class.
>>> class Identifier(Structure):
...
... def __init__(self):
... super().__init__() # <- NEVER forget to call it first!
... self.version = Byte() # 1st field
... self.id = Unsigned8() # 2nd field
... self.length = Decimal8() # 3rd field
... self.module = Char() # 4th field
... self.index_fields() # <- Indexes all fields (optional)
>>> # Create an instance of the structure.
>>> identifier = Identifier()
>>> # List the field values of the structure.
>>> identifier.to_list()
[('Identifier.version', '0x0'),
('Identifier.id', '0x0'),
('Identifier.length', 0),
('Identifier.module', '\x00')]
>>> # List the field values of the structure as a CSV list.
>>> identifier.to_csv()
[{'id': 'Identifier.version', 'value': '0x0'},
{'id': 'Identifier.id', 'value': '0x0'},
{'id': 'Identifier.length', 'value': 0},
{'id': 'Identifier.module', 'value': '\x00'}]
>>> # View the structure field values as a JSON string.
>>> identifier.to_json()
'{"version": "0x0", "id": "0x0", "length": 0, "module": "\\u0000"}'
Align Fields in a Structure¶
You can align consecutive fields in a structure to
each other by using the align_to
parameter of the Field
class.
>>> class Identifier(Structure):
...
... def __init__(self):
... super().__init__()
... self.version = Byte(align_to=4) # 1st field aligned to 4 bytes
... self.id = Unsigned(8, align_to=4) # 2nd field aligned to 4 bytes
... self.length = Decimal(8, align_to=4) # 3rd field aligned to 4 bytes
... self.module = Char(align_to=4) # 4th field aligned to 4 bytes
... self.index_fields()
>>> # Create an instance of the structure.
>>> identifier = Identifier()
>>> # List the field alignments of the structure.
>>> identifier.to_list('alignment')
[('Identifier.version', Alignment(byte_size=4, bit_offset=0)),
('Identifier.id', Alignment(byte_size=4, bit_offset=8)),
('Identifier.length', Alignment(byte_size=4, bit_offset=16)),
('Identifier.module', Alignment(byte_size=4, bit_offset=24))]
>>> # List the field alignments of the structure as a CSV list.
>>> identifier.to_csv('alignment.byte_size', 'alignment.bit_offset')
[{'id': 'Identifier.version', 'alignment.byte_size': 4, 'alignment.bit_offset': 0},
{'id': 'Identifier.id', 'alignment.byte_size': 4, 'alignment.bit_offset': 8},
{'id': 'Identifier.length', 'alignment.byte_size': 4, 'alignment.bit_offset': 16},
{'id': 'Identifier.module', 'alignment.byte_size': 4, 'alignment.bit_offset': 24}]
>>> # View the structure field alignments as a JSON string.
>>> identifier.to_json('alignment')
'{"version": [4, 0], "id": [4, 8], "length": [4, 16], "module": [4, 24]}'
Nest Structures¶
You can nest a structure in another structure.
>>> # Define a new structure class with a nested structure.
>>> class Header(Structure):
...
... def __init__(self):
... super().__init__()
... self.type = Identifier() # nested structure
... self.size = Decimal32()
... self.index_fields()
>>> # Create an instance of the structure.
>>> header = Header()
>>> # List the field values of the structure.
>>> header.to_list()
[('Header.type.version', '0x0'),
('Header.type.id', '0x0'),
('Header.type.length', 0),
('Header.type.module', '\x00'),
('Header.size', 0)]
>>> # List the field values of the structure as a CSV list.
>>> header.to_csv()
[{'id': 'Header.type.version', 'value': '0x0'},
{'id': 'Header.type.id', 'value': '0x0'},
{'id': 'Header.type.length', 'value': 0},
{'id': 'Header.type.module', 'value': '\x00'},
{'id': 'Header.size', 'value': 0}]
>>> # View the structure field values as a JSON string.
>>> header.to_json()
'{"type": {"version": "0x0", "id": "0x0", "length": 0, "module": "\\u0000"},
"size": 0}'
Inherit from a Structure¶
You can inherit the members from a structure class to extend or change it.
>>> # Define a new structure class.
>>> class HeaderV1(Structure):
...
... def __init__(self):
... super().__init__()
... self.type = Identifier()
... self.index_fields()
>>> # Create an instance of the structure.
>>> header = HeaderV1()
>>> # List the field values of the structure.
>>> header.to_list()
[('HeaderV1.type.version', '0x0'),
('HeaderV1.type.id', '0x0'),
('HeaderV1.type.length', 0),
('HeaderV1.type.module', '\x00')]
>>> # List the field values of the structure as a CSV list.
>>> header.to_csv()
[{'id': 'HeaderV1.type.version', 'value': '0x0'},
{'id': 'HeaderV1.type.id', 'value': '0x0'},
{'id': 'HeaderV1.type.length', 'value': 0},
{'id': 'HeaderV1.type.module', 'value': '\x00'}]
>>> # View the structure field values as a JSON string.
>>> header.to_json()
'{"type": {"version": "0x0", "id": "0x0", "length": 0, "module": "\\u0000"}}'
>>> # Define a new structure class inherit from a structure the fields.
>>> class HeaderV2(HeaderV1):
...
... def __init__(self):
... super().__init__()
... self.size = Decimal32()
... self.index_fields()
>>> # Create an instance of the structure.
>>> header = HeaderV2()
>>> # List the field values of the structure.
>>> header.to_list()
[('HeaderV2.type.version', '0x0'),
('HeaderV2.type.id', '0x0'),
('HeaderV2.type.length', 0),
('HeaderV2.type.module', '\x00'),
('HeaderV2.size', 0)]
>>> # List the field values of the structure as a CSV list.
>>> header.to_csv()
[{'id': 'HeaderV2.type.version', 'value': '0x0'},
{'id': 'HeaderV2.type.id', 'value': '0x0'},
{'id': 'HeaderV2.type.length', 'value': 0},
{'id': 'HeaderV2.type.module', 'value': '\x00'},
{'id': 'HeaderV2.size', 'value': 0}]
>>> # View the structure field values as a JSON string.
>>> header.to_json()
'{"type": {"version": "0x0", "id": "0x0", "length": 0, "module": "\\u0000"},
"size": 0}'
Declare on the fly¶
You can declare a structure on the fly.
>>> # Create an empty structure.
>>> structure = Structure()
>>> # Add fields to the structure.
>>> structure.version = Byte()
>>> structure.id = Unsigned8()
>>> structure.length = Decimal8()
>>> structure.module = Char()
>>> # List the field values of the structure.
>>> structure.to_list()
[('Structure.version', '0x0'),
('Structure.id', '0x0'),
('Structure.length', 0),
('Structure.module', '\x00')]
>>> # List the field values of the structure as a CSV list.
>>> structure.to_csv()
[{'id': 'Structure.version', 'value': '0x0'},
{'id': 'Structure.id', 'value': '0x0'},
{'id': 'Structure.length', 'value': 0},
{'id': 'Structure.module', 'value': '\x00'}]
>>> # View the structure field values as a JSON string.
>>> structure.to_json()
'{"version": "0x0", "id": "0x0", "length": 0, "module": "\\u0000"}'
You can declare a structure with aligned fields on the fly.
>>> # Create an empty structure.
>>> structure = Structure()
>>> # Add aligned fields to the structure.
>>> structure.version = Byte(4)
>>> structure.id = Unsigned(8, 4)
>>> structure.length = Decimal(8, 4)
>>> structure.module = Char(4)
>>> # Index the fields in the structure.
>>> structure.index_fields()
Index(byte=4, bit=0, address=4, base_address=0, update=False)
>>> # List the field alignments of the structure.
>>> structure.to_list('alignment')
[('Structure.version', Alignment(byte_size=4, bit_offset=0)),
('Structure.id', Alignment(byte_size=4, bit_offset=8)),
('Structure.length', Alignment(byte_size=4, bit_offset=16)),
('Structure.module', Alignment(byte_size=4, bit_offset=24))]
>>> # List the field alignments of the structure as a CSV list.
>>> structure.to_csv('alignment.byte_size', 'alignment.bit_offset')
[{'id': 'Structure.version', 'alignment.byte_size': 4, 'alignment.bit_offset': 0},
{'id': 'Structure.id', 'alignment.byte_size': 4, 'alignment.bit_offset': 8},
{'id': 'Structure.length', 'alignment.byte_size': 4, 'alignment.bit_offset': 16},
{'id': 'Structure.module', 'alignment.byte_size': 4, 'alignment.bit_offset': 24}]
>>> # View the structure field alignments as a JSON string.
>>> structure.to_json('alignment')
'{"version": [4, 0], "id": [4, 8], "length": [4, 16], "module": [4, 24]}'
You can declare a structure with keywords.
>>> # Create a structure with keywords.
>>> structure = Structure(
... version=Byte(4),
... id=Unsigned(8, 4),
... length=Decimal(8, 4),
... module=Char(4))
>>> # List the field values of the structure.
>>> structure.to_list()
[('Structure.version', '0x0'),
('Structure.id', '0x0'),
('Structure.length', 0),
('Structure.module', '\x00')]
>>> # List the field values of the structure as a CSV list.
>>> structure.to_csv()
[{'id': 'Structure.version', 'value': '0x0'},
{'id': 'Structure.id', 'value': '0x0'},
{'id': 'Structure.length', 'value': 0},
{'id': 'Structure.module', 'value': '\x00'}]
>>> # View the structure field values as a JSON string.
>>> structure.to_json()
'{"version": "0x0", "id": "0x0", "length": 0, "module": "\\u0000"}'
You can nest structure’s on the fly.
>>> # Create an empty structure.
>>> structure = Structure()
>>> # Add an empty nested structure to the structure.
>>> structure.type = Structure()
>>> # Add fields to the nested structure.
>>> structure.type.version = Byte(4)
>>> structure.type.id = Unsigned(8, 4)
>>> structure.type.length = Decimal(8, 4)
>>> structure.type.module = Char(4)
>>> # Add a field to the structure.
>>> structure.size = Decimal32()
>>> # List the field values of the structure.
>>> structure.to_list()
[('Structure.type.version', '0x0'),
('Structure.type.id', '0x0'),
('Structure.type.length', 0),
('Structure.type.module', '\x00'),
('Structure.size', 0)]
>>> # List the field values of the structure as a CSV list.
>>> structure.to_csv()
[{'id': 'Structure.type.version', 'value': '0x0'},
{'id': 'Structure.type.id', 'value': '0x0'},
{'id': 'Structure.type.length', 'value': 0},
{'id': 'Structure.type.module', 'value': '\x00'},
{'id': 'Structure.size', 'value': 0}]
>>> # View the structure field values as a JSON string.
>>> structure.to_json()
'{"type": {"version": "0x0", "id": "0x0", "length": 0, "module": "\\u0000"},
"size": 0}'
You can assign a structure to a member of another structure on the fly.
>>> # Create a structure to be nested.
>>> identifier = Structure(
... version = Byte(4),
... id = Unsigned(8, 4),
... length = Decimal(8, 4),
... module = Char(4))
>>> # Create an empty structure.
>>> structure = Structure()
>>> # Add a nested structure to the structure.
>>> structure.type = identifier
>>> # Add a field to the structure.
>>> structure.size = Decimal32()
>>> # List the field values of the structure.
>>> structure.to_list()
[('Structure.type.version', '0x0'),
('Structure.type.id', '0x0'),
('Structure.type.length', 0),
('Structure.type.module', '\x00'),
('Structure.size', 0)]
>>> # List the field values of the structure as a CSV list.
>>> structure.to_csv()
[{'id': 'Structure.type.version', 'value': '0x0'},
{'id': 'Structure.type.id', 'value': '0x0'},
{'id': 'Structure.type.length', 'value': 0},
{'id': 'Structure.type.module', 'value': '\x00'},
{'id': 'Structure.size', 'value': 0}]
>>> # View the structure field values as a JSON string.
>>> structure.to_json()
'{"type": {"version": "0x0", "id": "0x0", "length": 0, "module": "\\u0000"},
"size": 0}'
Initialize a Structure¶
You can initialize the fields in a structure by calling the method
initialize_fields()
.
>>> # Create a structure.
>>> structure = Structure(
... version=Byte(4),
... id=Unsigned(8, 4),
... length=Decimal(8, 4),
... module=Char(4))
>>> # List the field values of the structure.
>>> structure.to_list()
[('Structure.version', '0x0'),
('Structure.id', '0x0'),
('Structure.length', 0),
('Structure.module', '\x00')]
>>> # List the field values of the structure as a CSV list.
>>> structure.to_csv()
[{'id': 'Structure.version', 'value': '0x0'},
{'id': 'Structure.id', 'value': '0x0'},
{'id': 'Structure.length', 'value': 0},
{'id': 'Structure.module', 'value': '\x00'}]
>>> # View the structure field values as a JSON string.
>>> structure.to_json()
'{"version": "0x0", "id": "0x0", "length": 0, "module": "\\u0000"}'
>>> # Initialize the fields of the structure.
>>> structure.initialize_fields(
... dict(version=1, id=2, length=9, module=0x46))
>>> # Initialize the fields in the structure.
>>> structure.initialize_fields({
... "version": "0x1",
... "id": "0x2",
... "length": 9,
... "module": "F"
... })
>>> # List the field values of the structure.
>>> structure.to_list()
[('Structure.version', '0x1'),
('Structure.id', '0x2'),
('Structure.length', 9),
('Structure.module', 'F')]
>>> # List the field values of the structure as a CSV list.
>>> structure.to_csv()
[{'id': 'Structure.version', 'value': '0x1'},
{'id': 'Structure.id', 'value': '0x2'},
{'id': 'Structure.length', 'value': 9},
{'id': 'Structure.module', 'value': 'F'}]
>>> # View the structure field values as a JSON string.
>>> structure.to_json()
'{"version": "0x1", "id": "0x2", "length": 9, "module": "F"}'
Display a Structure¶
You can display the structure.
>>> # Create a structure.
>>> structure = Structure(
... version=Byte(4),
... id=Unsigned(8, 4),
... length=Decimal(8, 4),
... module=Char(4))
>>> # Index the fields in the structure.
>>> structure.index_fields()
Index(byte=4, bit=0, address=4, base_address=0, update=False)
>>> # Display the structure.
>>> structure
Structure([('version', Byte(index=Index(byte=0, bit=0,
address=0, base_address=0,
update=False),
alignment=Alignment(byte_size=4, bit_offset=0),
bit_size=8,
value='0x0')),
('id', Unsigned(index=Index(byte=0, bit=8,
address=0, base_address=0,
update=False),
alignment=Alignment(byte_size=4, bit_offset=8),
bit_size=8,
value='0x0')),
('length', Decimal(index=Index(byte=0, bit=16,
address=0, base_address=0,
update=False),
alignment=Alignment(byte_size=4, bit_offset=16),
bit_size=8,
value=0)),
('module', Char(index=Index(byte=0, bit=24,
address=0, base_address=0,
update=False),
alignment=Alignment(byte_size=4, bit_offset=24),
bit_size=8,
value='\x00'))])
Metadata of a Structure¶
You can get the metadata of the structure by calling the method
describe()
.
>>> # Get the description of the structure.
>>> structure.describe()
OrderedDict([('class', 'Structure'),
('name', 'Structure'),
('size', 4),
('type', 'Structure'),
('member',
[OrderedDict([('address', 0),
('alignment', [4, 0]),
('class', 'Byte'),
('index', [0, 0]),
('max', 255),
('min', 0),
('name', 'version'),
('order', 'auto'),
('signed', False),
('size', 8),
('type', 'Field'),
('value', '0x0')]),
OrderedDict([('address', 0),
('alignment', [4, 8]),
('class', 'Unsigned8'),
('index', [0, 8]),
('max', 255),
('min', 0),
('name', 'id'),
('order', 'auto'),
('signed', False),
('size', 8),
('type', 'Field'),
('value', '0x0')]),
OrderedDict([('address', 0),
('alignment', [4, 16]),
('class', 'Decimal8'),
('index', [0, 16]),
('max', 255),
('min', 0),
('name', 'length'),
('order', 'auto'),
('signed', False),
('size', 8),
('type', 'Field'),
('value', 0)]),
OrderedDict([('address', 0),
('alignment', [4, 24]),
('class', 'Char'),
('index', [0, 24]),
('max', 255),
('min', 0),
('name', 'module'),
('order', 'auto'),
('signed', False),
('size', 8),
('type', 'Field'),
('value', '\x00')])])])
>>> json.dump(structure.describe(), sys.stdout, indent=2)
{
"class": "Structure",
"name": "Structure",
"size": 4,
"type": "Structure",
"member": [
{
"address": 0,
"alignment": [
4,
0
],
"class": "Byte",
"index": [
0,
0
],
"max": 255,
"min": 0,
"name": "version",
"order": "auto",
"signed": false,
"size": 8,
"type": "Field",
"value": "0x0"
},
{
"address": 0,
"alignment": [
4,
8
],
"class": "Unsigned8",
"index": [
0,
8
],
"max": 255,
"min": 0,
"name": "id",
"order": "auto",
"signed": false,
"size": 8,
"type": "Field",
"value": "0x0"
},
{
"address": 0,
"alignment": [
4,
16
],
"class": "Decimal8",
"index": [
0,
16
],
"max": 255,
"min": 0,
"name": "length",
"order": "auto",
"signed": false,
"size": 8,
"type": "Field",
"value": 0
},
{
"address": 0,
"alignment": [
4,
24
],
"class": "Char",
"index": [
0,
24
],
"max": 255,
"min": 0,
"name": "module",
"order": "auto",
"signed": false,
"size": 8,
"type": "Field",
"value": "\u0000"
}
]
}
Size of a Structure¶
You can get the size of a structure as a tuple in the form of
(number of bytes, number of remaining bits)
by calling the method
container_size()
.
>>> # Get the size of the structure.
>>> structure.container_size()
(4, 0)
Note
The number of remaining bits must be always zero or the structure declaration is incomplete.
Indexing¶
You can index all fields in a structure by calling the method
index_fields()
.
The Index
after the last field of the structure is
returned.
>>> # Create a structure.
>>> structure = Structure(
... version=Byte(),
... id=Unsigned8(),
... length=Decimal8(),
... module=Char())
>>> # List the field indexes of the structure.
>>> structure.to_list('index')
[('Structure.version', Index(byte=0, bit=0, address=0, base_address=0, update=False)),
('Structure.id', Index(byte=0, bit=0, address=0, base_address=0, update=False)),
('Structure.length', Index(byte=0, bit=0, address=0, base_address=0, update=False)),
('Structure.module', Index(byte=0, bit=0, address=0, base_address=0, update=False))]
>>> # List the field indexes of the structure as a CSV list.
>>> structure.to_csv('index.byte', 'index.address')
[{'id': 'Structure.version', 'index.byte': 0, 'index.address': 0},
{'id': 'Structure.id', 'index.byte': 0, 'index.address': 0},
{'id': 'Structure.length', 'index.byte': 0, 'index.address': 0},
{'id': 'Structure.module', 'index.byte': 0, 'index.address': 0}]
>>> # View the structure field indexes as a JSON string.
>>> structure.to_json('index')
'{"version": [0, 0, 0, 0, false],
"id": [0, 0, 0, 0, false],
"length": [0, 0, 0, 0, false],
"module": [0, 0, 0, 0, false]}'
>>> # Index the fields in the structure.
>>> structure.index_fields()
Index(byte=4, bit=0, address=4, base_address=0, update=False)
>>> # Index the fields in the structure with a start index.
>>> structure.index_fields(index=Index())
Index(byte=4, bit=0, address=4, base_address=0, update=False)
>>> # List the field indexes of the structure.
>>> structure.to_list('index')
[('Structure.version', Index(byte=0, bit=0, address=0, base_address=0, update=False)),
('Structure.id', Index(byte=1, bit=0, address=1, base_address=0, update=False)),
('Structure.length', Index(byte=2, bit=0, address=2, base_address=0, update=False)),
('Structure.module', Index(byte=3, bit=0, address=3, base_address=0, update=False))]
>>> # List the field indexes of the structure as a CSV list.
>>> structure.to_csv('index.byte', 'index.address')
[{'id': 'Structure.version', 'index.byte': 0, 'index.address': 0},
{'id': 'Structure.id', 'index.byte': 1, 'index.address': 1},
{'id': 'Structure.length', 'index.byte': 2, 'index.address': 2},
{'id': 'Structure.module', 'index.byte': 3, 'index.address': 3}]
>>> # View the structure field indexes as a JSON string.
>>> structure.to_json('index')
'{"version": [0, 0, 0, 0, false],
"id": [1, 0, 1, 0, false],
"length": [2, 0, 2, 0, false],
"module": [3, 0, 3, 0, false]}'
De-Serializing¶
You can deserialize a byte stream with a structure by calling the method
deserialize()
.
>>> # Create a structure.
>>> structure = Structure(
... version=Byte(),
... id=Unsigned8(),
... length=Decimal8(),
... module=Char())
>>> # Create a byte stream to be deserialized.
>>> bytestream = bytes.fromhex('01020946f00f00')
>>> # Deserialize the byte stream and map it to the structure.
>>> structure.deserialize(bytestream)
Index(byte=4, bit=0, address=4, base_address=0, update=False)
>>> # List the field values of the structure.
>>> structure.to_list()
[('Structure.version', '0x1'),
('Structure.id', '0x2'),
('Structure.length', 9),
('Structure.module', 'F')]
>>> # List the field values of the structure as a CSV list.
>>> structure.to_csv()
[{'id': 'Structure.version', 'value': '0x1'},
{'id': 'Structure.id', 'value': '0x2'},
{'id': 'Structure.length', 'value': 9},
{'id': 'Structure.module', 'value': 'F'}]
>>> # View the structure field values as a JSON string.
>>> structure.to_json()
'{"version": "0x1", "id": "0x2", "length": 9, "module": "F"}'
Serializing¶
You can serialize a byte stream with a structure by calling the method
serialize()
.
>>> # Create an empty byte stream.
>>> bytestream = bytearray()
>>> bytestream
bytearray(b'')
>>> # Serialize the structure to the byte stream.
>>> structure.serialize(bytestream)
Index(byte=4, bit=0, address=4, base_address=0, update=False)
>>> # Display the byte stream.
>>> bytestream.hex()
'01020946'
or
>>> bytes(structure).hex()
'01020946'
Number of Members¶
You can get the number of structure members with the built-in function
len()
.
>>> # Number of structure members.
>>> len(structure)
4
Access a Member¶
You can access a structure member with its name.
>>> # Access a structure member with its attribute name.
>>> structure.version
Byte(index=Index(byte=0, bit=0, address=0, base_address=0, update=False),
alignment=Alignment(byte_size=1, bit_offset=0),
bit_size=8,
value='0x1')
>>> # Access a structure member with its key name.
>>> structure['version']
Byte(index=Index(byte=0, bit=0, address=0, base_address=0, update=False),
alignment=Alignment(byte_size=1, bit_offset=0),
bit_size=8,
value='0x1')
Attributes of a Member Field¶
You can access the Field
attributes of a field
member in a structure with the attribute names:
>>> # Field name.
>>> structure.version.name
'Byte'
>>> # Field value.
>>> structure.version.value
'0x1'
>>> # Field bit size.
>>> structure.version.bit_size
8
>>> # Field alignment.
>>> structure.version.alignment
Alignment(byte_size=1, bit_offset=0)
>>> # Field alignment: byte size of the aligned field group.
>>> structure.version.alignment.byte_size
1
>>> # Field alignment: bit offset of the field in its field group.
>>> structure.version.alignment.bit_offset
0
>>> # Field byte order.
>>> structure.version.byte_order
Byteorder.auto = 'auto'
>>> # Field byte order value.
>>> structure.version.byte_order.value
'auto'
>>> # Field index.
>>> structure.version.index
Index(byte=0, bit=0, address=0, base_address=0, update=False)
>>> # Field index: byte offset of the field in the byte stream.
>>> structure.version.index.byte
0
>>> # Field index: bit offset of the field relative to its byte offset.
>>> structure.version.index.bit
0
>>> # Field index: memory address of the field in the data source.
>>> structure.version.index.address
0
>>> # Field index: start address of the byte stream in the data source.
>>> structure.version.index.base_address
0
>>> # Field index: update request for the byte stream.
>>> structure.version.index.update
False
You can check if a structure member is a field.
>>> is_field(structure.version)
True
You can check what kind of field it is.
>>> # Field is a bit field.
>>> structure.version.is_bit()
False
>>> # Field is a boolean field.
>>> structure.version.is_bool()
False
>>> # Field is a decimal field.
>>> structure.version.is_decimal()
True
>>> # Field is a float field.
>>> structure.version.is_float()
False
>>> # Field is a pointer field.
>>> structure.version.is_pointer()
False
>>> # Field is a stream field.
>>> structure.version.is_stream()
False
>>> # Field is a string field.
>>> structure.version.is_string()
False
Iterate over Members¶
You can iterate over the structure member names.
>>> [name for name in structure.keys()]
['version', 'id', 'length', 'module']
You can iterate over all kind of member items of a structure.
>>> [(name, member.item_type) for name, member in structure.items()]
[('version', ItemClass.Byte = 42),
('id', ItemClass.Unsigned = 45),
('length', ItemClass.Decimal = 40),
('module', ItemClass.Char = 43)]
You can iterate over all kind of members of a structure.
>>> [member.item_type for member in structure.values()]
[ItemClass.Byte = 42,
ItemClass.Unsigned = 45,
ItemClass.Decimal = 40,
ItemClass.Char = 43]
You can iterate over all field members of a structure.
>>> [member.name for member in structure.values() if is_field(member)]
['Byte', 'Unsigned8', 'Decimal8', 'Char']
View Field Attributes¶
You can view the attributes of each field of a structure
as an ordered dictionary by calling the method view_fields()
.
Default attribute is the field value
.
>>> # View the structure field values.
>>> structure.view_fields()
OrderedDict([('version', '0x1'),
('id', '0x2'),
('length', 9),
('module', 'F')])
>>> # View the structure field type names & field values.
>>> structure.view_fields('name', 'value')
OrderedDict([('version', {'name': 'Byte', 'value': '0x1'}),
('id', {'name': 'Unsigned8', 'value': '0x2'}),
('length', {'name': 'Decimal8', 'value': 9}),
('module', {'name': 'Char', 'value': 'F'})])
>>> # View the structure field indexes.
>>> structure.view_fields('index')
OrderedDict([('version',
Index(byte=0, bit=0, address=0, base_address=0, update=False)),
('id',
Index(byte=1, bit=0, address=1, base_address=0, update=False)),
('length',
Index(byte=2, bit=0, address=2, base_address=0, update=False)),
('module',
Index(byte=3, bit=0, address=3, base_address=0, update=False))])
View as a JSON string¶
You can view the attributes of each field of a structure
as a JSON formatted string by calling the method to_json()
.
Default attribute is the field value
.
>>> # View the structure field values as a JSON string.
>>> structure.to_json()
'{"version": "0x1", "id": "0x2", "length": 9, "module": "F"}'
>>> print(structure.to_json(indent=2))
{
"version": "0x1",
"id": "0x2",
"length": 9,
"module": "F"
}
>>> # View the structure field type names & field values as a JSON string.
>>> structure.to_json('name', 'value')
'{"version": {"name": "Byte", "value": "0x1"},
"id": {"name": "Unsigned8", "value": "0x2"},
"length": {"name": "Decimal8", "value": 9},
"module": {"name": "Char", "value": "F"}}'
>>> # View the structure field indexes as a JSON string.
>>> structure.to_json('index')
'{"version": [0, 0, 0, 0, false],
"id": [1, 0, 1, 0, false],
"length": [2, 0, 2, 0, false],
"module": [3, 0, 3, 0, false]}'
List Field Items¶
You can list all field items of a structure
as a flatten list by calling the method field_items()
.
>>> # List the field items of the structure.
>>> structure.field_items()
[('version',
Byte(index=Index(byte=0, bit=0, address=0, base_address=0, update=False),
alignment=Alignment(byte_size=1, bit_offset=0),
bit_size=8,
value='0x1')),
('id',
Unsigned8(index=Index(byte=1, bit=0, address=1, base_address=0, update=False),
alignment=Alignment(byte_size=1, bit_offset=0),
bit_size=8,
value='0x2')),
('length',
Decimal8(index=Index(byte=2, bit=0, address=2, base_address=0, update=False),
alignment=Alignment(byte_size=1, bit_offset=0),
bit_size=8,
value=9)),
('module',
Char(index=Index(byte=3, bit=0, address=3, base_address=0, update=False),
alignment=Alignment(byte_size=1, bit_offset=0),
bit_size=8,
value='F'))]
List Field Attributes¶
You can list the attributes of each field of a structure
as a flatten list by calling the method to_list()
.
Default attribute is the field value
.
>>> # List the field values of the structure.
>>> structure.to_list()
[('Structure.version', '0x1'),
('Structure.id', '0x2'),
('Structure.length', 9),
('Structure.module', 'F')]
>>> # List the field type names & values of the structure.
>>> structure.to_list('name', 'value')
[('Structure.version', ('Byte', '0x1')),
('Structure.id', ('Unsigned8', '0x2')),
('Structure.length', ('Decimal8', 9)),
('Structure.module', ('Char', 'F'))]
>>> # List the field indexes of the structure.
>>> structure.to_list('index')
[('Structure.version', Index(byte=0, bit=0, address=0, base_address=0, update=False)),
('Structure.id', Index(byte=1, bit=0, address=1, base_address=0, update=False)),
('Structure.length', Index(byte=2, bit=0, address=2, base_address=0, update=False)),
('Structure.module', Index(byte=3, bit=0, address=3, base_address=0, update=False))]
Note
The class name of the instance is used for the root name as long as no name is given.
You can list the attributes of each field of a structure
as a flatten ordered dictionary by calling the method to_dict()
.
Default attribute is the field value
.
>>> # List the field values of the structure.
>>> structure.to_dict()
OrderedDict([('Structure',
OrderedDict([('version', '0x1'),
('id', '0x2'),
('length', 9),
('module', 'F')]))])
>>> # List the field type names & values of the structure.
>>> structure.to_dict('name', 'value')
OrderedDict([('Structure',
OrderedDict([('version', ('Byte', '0x1')),
('id', ('Unsigned8', '0x2')),
('length', ('Decimal8', 9)),
('module', ('Char', 'F'))]))])
>>> # List the field indexes in the structure.
>>> structure.to_dict('index')
OrderedDict([('Structure',
OrderedDict([('version', Index(byte=0, bit=0,
address=0, base_address=0,
update=False)),
('id', Index(byte=1, bit=0,
address=1, base_address=0,
update=False)),
('length', Index(byte=2, bit=0,
address=2, base_address=0,
update=False)),
('module', Index(byte=3, bit=0,
address=3, base_address=0,
update=False))]))])
Note
The class name of the instance is used for the root name as long as no name is given.
You can list the attributes of each field of a structure
as a flatten list of dictionaries containing the field path and the selected
field attributes by calling the method to_csv()
.
Default attribute is the field value
.
>>> # List the field values of the structure as a CSV list.
>>> structure.to_csv()
[{'id': 'Structure.version', 'value': '0x1'},
{'id': 'Structure.id', 'value': '0x2'},
{'id': 'Structure.length', 'value': 9},
{'id': 'Structure.module', 'value': 'F'}]
>>> # List the field type names & values of the structure as a CSV list.
>>> structure.to_csv('name', 'value')
[{'id': 'Structure.version', 'name': 'Byte', 'value': '0x1'},
{'id': 'Structure.id', 'name': 'Unsigned8', 'value': '0x2'},
{'id': 'Structure.length', 'name': 'Decimal8', 'value': 9},
{'id': 'Structure.module', 'name': 'Char', 'value': 'F'}]
Note
The class name of the instance is used for the root name as long as no name is given.
Write Field Attributes¶
You can write the attributes of each field of a structure
to a .csv
file by calling the method write_csv()
.
Default attribute is the field value
.
>>> # List the field values of the structure as a CSV list.
>>> structure.to_csv()
[{'id': 'Structure.version', 'value': '0x1'},
{'id': 'Structure.id', 'value': '0x2'},
{'id': 'Structure.length', 'value': 9},
{'id': 'Structure.module', 'value': 'F'}]
>>> # Save the structure field values to a '.csv' file.
>>> structure.write_csv("_static/structure.csv")
The generated .csv
file for the structure looks like this:
id,value
Structure.version,0x1
Structure.id,0x2
Structure.length,9
Structure.module,F
Note
The class name of the instance is used for the root name as long as no name is given.
Save Field Attributes¶
You can save the attributes of each field of a structure
to an .ini
file by calling the method save()
.
Default attribute is the field value
.
>>> # List the field values of the structure.
>>> structure.to_list()
[('Structure.version', '0x1'),
('Structure.id', '0x2'),
('Structure.length', 9),
('Structure.module', 'F')]
>>> # Save the structure field values to an '.ini' file.
>>> structure.save("_static/structure.ini")
The generated .ini
file for the structure looks like this:
[Structure]
version = 0x1
id = 0x2
length = 9
module = F
Note
The class name of the instance is used for the section name as long as no section is given.
Load Field Values¶
You can load the value of each field of a structure
from an .ini
file by calling the method load()
.
>>> # Create a structure.
>>> structure = Structure(
... version=Byte(),
... id=Unsigned8(),
... length=Decimal8(),
... module=Char())
>>> # Load the structure field values from an '.ini' file.
>>> structure.load("_static/structure.ini")
[Structure]
Structure.version = 0x1
Structure.id = 0x2
Structure.length = 9
Structure.module = F
>>> # List the field values of the structure.
>>> structure.to_list()
[('Structure.version', '0x1'),
('Structure.id', '0x2'),
('Structure.length', 9),
('Structure.module', 'F')]
Note
The class name of the instance is used for the section name as long as no section is given.