Fields#
The role of a Field
is to map a specific content area of a byte stream.
A field is always placed in a container except from a pointer field which is the entry point for a mapper to connect the attached data object via a byte stream provider to a data source to retrieve the required byte stream for the mapper .
>>> # Create a field.
>>> field = Field()
>>> # Display the field.
>>> field
Field(index=Index(byte=0, bit=0,
address=0, base_address=0,
update=False),
alignment=Alignment(byte_size=0, bit_offset=0),
bit_size=0,
value=None)
Overview#
The list below shows the available field classes.
Decimal
Bit
,Byte
,Char
,Signed
,Unsigned
,Bitset
,Bool
,Enum
,Scaled
,Fraction
,Bipolar
,Unipolar
,Datetime
,IPv4Address
Pointer
,StructurePointer
,SequencePointer
,ArrayPointer
StreamPointer
,StringPointer
,AutoStringPointer
RelativePointer
,StructureRelativePointer
,SequenceRelativePointer
,ArrayRelativePointer
,StreamRelativePointer
,StringRelativePointer
Name#
The field name consists of the name of the field base class and its field size to describe the kind of the field.
>>> # Field name.
>>> field.name
'Field0'
Size#
The field size defines the size of the content area of a byte stream that the field map.
>>> # Field bit size.
>>> field.bit_size
0
Value#
The field value represents the content area of a byte stream that the field map.
>>> # Field value.
>>> field.value
Index#
The field index contains the location of the field in a byte stream and in the providing data source.
The field index is automatically calculated by the built-in deserializer and serializer from the start point of the byte stream and the start address of the byte stream in the providing data source.
>>> # Field index.
>>> field.index
Index(byte=0, bit=0, address=0, base_address=0, update=False)
>>> # Field index: byte offset of the field in the byte stream.
>>> field.index.byte
0
>>> # Field index: bit offset of the field relative to its byte offset.
>>> field.index.bit
0
>>> # Field index: memory address of the field in the data source.
>>> field.index.address
0
>>> # Field index: start address of the byte stream in the data source.
>>> field.index.base_address
0
>>> # Field index: update request for the byte stream.
>>> field.index.update
False
Alignment#
The field alignment contains the location of the field within an aligned group of consecutive fields.
The order how the consecutive fields are declared in a container defines the order how the consecutive fields are aligned to each other.
The bit offset
of the field alignment is automatically calculated by the
built-in deserializer and serializer.
>>> # Field alignment.
>>> field.alignment
Alignment(byte_size=0, bit_offset=0)
>>> byte_size, bit_offset = field.alignment
>>> # Field alignment: byte size of the aligned field group.
>>> byte_size
0
>>> # Field alignment: bit offset of the field in its field group.
>>> bit_offset
0
A field can be aligned to a group of consecutive fields by using the
align_to
argument of the Field
class to describe an atomic
content part of a byte stream with more than one field.
>>> Decimal(15).alignment
Alignment(byte_size=2, bit_offset=0)
>>> Bool(1, align_to=2).alignment
Alignment(byte_size=2, bit_offset=0)
Note
A field aligns it self to the next matching byte size when the field size matches not full bytes and no field alignment is given.
For example to describe an atomic 16-bit value in a byte stream with more than one field can be achieved like this:
>>> # Create an empty structure for the atomic 16-bit value.
>>> atomic = Structure()
>>> # Add field for the first 15 bits of an atomic 16-bit value.
>>> atomic.size = Decimal(15, 2)
>>> # Add field for the last bit of an atomic 16-bit value.
>>> atomic.flag = Bool(1, 2)
>>> # Index the fields of the atomic 16-bit value.
>>> atomic.index_fields()
Index(byte=2, bit=0, address=2, base_address=0, update=False)
>>> # Display alignment of the size field.
>>> atomic.size.alignment
Alignment(byte_size=2, bit_offset=0)
>>> # Display alignment of the flag field.
>>> atomic.flag.alignment
Alignment(byte_size=2, bit_offset=15)
Note
The field alignment works only for the Decimal
field classes.
Byte order#
A field defines its own decoding/encoding byte_order
.
The default field byte order is auto
it means that the
field use the byte order which the byte stream mapper
defines to unpack
and pack
the required bytes and
bits for its field value from and to the byte stream.
>>> # Field byte order.
>>> field.byte_order
Byteorder.auto = 'auto'
>>> # Field byte order value.
>>> field.byte_order.value
'auto'
Enumeration#
The name instead of the value of an enumeration can be displayed with the
Enum
field class by assigning an Enumeration
class to the
Enum
field.
For example to describe a 2-bit ambivalent enumeration by an Enum
field can be achieved like this:
>>> # Define the enumeration class.
>>> class Validity(Enumeration):
... error = 0
... correct = 1
... forced = 2
... undefined = 3
>>> # Create an enum field and assign an enumeration to the field.
>>> ambivalent = Enum(2, enumeration=Validity)
>>> # Display the value of the field.
>>> ambivalent.value
'error'
>>> # Returns the field value as an integer.
>>> int(ambivalent)
0
>>> # Display the field.
>>> ambivalent
Enum(index=Index(byte=0, bit=0,
address=0, base_address=0,
update=False),
alignment=Alignment(byte_size=1, bit_offset=0),
bit_size=2,
value='error')