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.

Name#

A field has a type 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#

A field has a bit_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#

A field has a value.

The field value represents the content area of a byte stream that the field map.

>>> # Field value.
>>> field.value

Index#

A field has an 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#

A field has an 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')