.. _datamodel_standard_bitfield:
Bit-field
=========
A *Bit-field*, despite its name suggesting a field of bits, is a powerful structure designed for
detailed byte inspection. Similar to other structures, it is a finite collection of named fields. This
section will introduce potential challenges associated with the implementation of a :class:`~caterpillar.model.Bitfield`
and explains its behavior.
.. versionchanged:: 2.5.0
Completely reworked the internal :class:`Bitfield` behaviour, model and processing.
Concept
-------
Each Bitfield instance maintains a sequence of bitfield groups, where each group
contains a collection of sized fields. A bitfield group may consist of either multiple
entries (i.e., any types that can be converted to an integral type) or a single
:class:`_StructLike` object. For example, consider the following bitfield definition:
.. code-block:: python
@bitfield
class Format:
a1: 2
a2: 1
_ : 0
b1: char
c1: uint32
This Bitfield definition will generate three distinct bitfield groups (labeled here as
groups a, b, and c). By default, bitfields use 8-bit alignment, leading to the following
layout:
.. code-block::
Group Pos Bits
a 0x00 8
b 0x01 8
c 0x02 32
Internally, only the first group requires special bit-level parsing. The remaining groups
(b and c) are treated as standard structures since they span full bytes or words without
sub-byte alignment. This dynamic grouping mechanism allows leveraging full struct-like
class definitions within bitfields.
Syntax
------
This new approach enables more complex and expressive bitfield definitions. The annotation
syntax is therefore extended as follows:
.. raw:: html
|
|
name
:
bits
-
field
(optional)
|
(1)
|
|
|
|
name
:
0
|
(2)
|
|
|
|
name
:
field-or-action
|
(3)
|
|
|
|
name
:
(
field
,
factory
)
|
(4)
|
|
|
|
name
:
(
bits
,
factory
(optional)
,
options
(optional)
)
|
(5)
|
|
|
|
Each identifier named above is bound to certain constraints:
.. raw:: html
| name
|
-
|
Any valid Python attribute name.
|
| bits
|
-
|
Any valid positive integer starting from 0.
|
| field
|
-
|
Any valid field definition for a struct resulting in a
_StructLike
that implements the subtract-operation resulting in a
Field
instance.
|
| field-or-action
|
-
|
Any valid field definition for a struct resulting or an object implementing the
_ActionLike
protocol.
|
| factory
|
-
|
Either a target Python type to use as factory or an instance of
BitfieldValueFactory.
|
| options
|
-
|
One or more options represented either as flags or instances of
SetAlignment.
|
What that syntax allows can be seen in the following example:
.. code-block:: python
:caption: Bit-field definition using all syntax rules
@bitfield
class Format: # -.
# Any annotation that can be converted by a TypeConverter | 1. Group
# into as _StructLike object is allowed. | (3 Bytes)
magic: b"foo" # bytes -'
# Syntax according to (1) and (2) -.
version : 4 # int | 2. Group
state : 3 # int | (1 Byte / 8 Bits)
_ : 0 # ignored/removed -'
# Extended Syntax (5)
flag1 : (1, SetAlignment(16)) # bool, new alignment -.
flag2 : 1 # bool | 3. Group
name : (12, CharFactory) # str | (2 Bytes / 16 Bits)
type : (2, SimpleEnum, EndGroup) # SimpleEnum -'
Processing Rules
----------------
Based on the previously defined syntax, some processing constraints were derived:
- Rule 1.:
- Default alignment is 1 byte (8 bits).
- Zero (``0``) bits are prohibited.
- If followed by a (2) declaration, the remaining bits in the current byte are padded.
- If a ```` is provided:
- typeof(````) is used to infer the factory.
- :func:`~caterpillar.model.getbits` and :func:`~cateprillar.model.sizeof` determine the field's alignment.
- If a custom alignment is configured in the Bitfield constructor, inferred alignment is ignored unless the field includes the :attr:`~cateprillar.options.B_OVERWRITE_ALIGNMENT` option.
- If the :attr:`~cateprillar.options.B_GROUP_END` option is set, the current group is finalized and a new one is started.
- Rule 2.:
- This rule forces alignment to the next byte boundary.
- The field is ignored during final class generation (name is discarded).
- The current group is finalized unless the bitfield is configured with :attr:`~caterpillar.options.B_GROUP_KEEP`
- Rule 3.:
- Equivalent to struct-like class field definitions.
- Automatically implies a rule 2 alignment.
- Always finalizes the current group regardless of :attr:`~caterpillar.options.B_GROUP_KEEP`.
- Rule 4.:
- Extension of (1).
- Explicitly defines a conversion factory for the field.
- The factory must be:
- A built-in type (e.g., int, bool) supporting ``__int__``, or
- A type or instance of :class:`BitfieldValueFactory`.
- Rule 5.:
- Builds upon (4) with support for options.
- Options can be passed as a list or single element.
- Supported Options:
- :attr:`~caterpillar.model.NewGroup`: Aligns the current group, starts a new one, and adds the entry to it.
- :attr:`~caterpillar.model.EndGroup`: Adds the entry to the current group, then aligns it.
- :class:`SetAlignment`: Changes the current working alignment.
- Note: Option order affects behavior and must be considered carefully.