BitFieldModel¶
BitFieldModel enables packing multiple boolean or small integer values into a single byte, word, or double-word. This is essential for C-compatible bit flags and space-efficient binary protocols.
Overview¶
Use BitFieldModel when you need to:
- Map individual bits to meaningful boolean flags
- Pack small integers into bit ranges within a byte/word
- Interface with C bit fields or hardware registers
- Create compact flag structures for network protocols
Quick Example¶
from pdc_struct import BitFieldModel, Bit, StructConfig, StructMode
class FilePermissions(BitFieldModel):
read: bool = Bit(0) # Bit 0
write: bool = Bit(1) # Bit 1
execute: bool = Bit(2) # Bit 2
struct_config = StructConfig(
mode=StructMode.C_COMPATIBLE,
bit_width=8
)
# Create with individual flags
perms = FilePermissions(read=True, write=True, execute=False)
print(perms.packed_value) # 3 (binary: 00000011)
# Create from packed value
perms = FilePermissions(packed_value=7) # binary: 00000111
print(perms.read, perms.write, perms.execute) # True True True
The Bit() Function¶
Bit() defines where a field maps within the packed integer:
Single-Bit Fields (Boolean)¶
class Flags(BitFieldModel):
active: bool = Bit(0) # Single bit at position 0
ready: bool = Bit(1) # Single bit at position 1
error: bool = Bit(7) # Single bit at position 7
Multi-Bit Fields (Integer)¶
For values that span multiple bits, list all bit positions:
class StatusRegister(BitFieldModel):
# 3-bit priority field using bits 0, 1, 2 (values 0-7)
priority: int = Bit(0, 1, 2)
# 4-bit error code using bits 4, 5, 6, 7 (values 0-15)
error_code: int = Bit(4, 5, 6, 7)
struct_config = StructConfig(
mode=StructMode.C_COMPATIBLE,
bit_width=8
)
Contiguous Bits Required
Bit positions must be contiguous. Bit(0, 1, 3) will raise a ValueError because bit 2 is missing.
Bit Width¶
The bit_width in StructConfig determines the packed size:
| bit_width | Packed Size | Max Bits | Struct Format |
|---|---|---|---|
| 8 | 1 byte | 0-7 | B (unsigned char) |
| 16 | 2 bytes | 0-15 | H (unsigned short) |
| 32 | 4 bytes | 0-31 | I (unsigned int) |
class WideFlags(BitFieldModel):
# Can use bits 0-31 with bit_width=32
low_byte: int = Bit(0, 1, 2, 3, 4, 5, 6, 7)
high_bits: int = Bit(24, 25, 26, 27, 28, 29, 30, 31)
struct_config = StructConfig(
mode=StructMode.C_COMPATIBLE,
bit_width=32
)
Working with Packed Values¶
The packed_value Property¶
Get or set the entire packed integer representation:
flags = FilePermissions(read=True, write=False, execute=True)
# Read packed value
value = flags.packed_value # 5 (binary: 101)
# Set packed value (updates all fields)
flags.packed_value = 3 # Sets read=True, write=True, execute=False
Initializing from Bytes¶
Pass raw bytes to unpack into fields:
# From a single byte
flags = FilePermissions(packed_value=b'\x07')
# From network data (16-bit example)
class NetworkFlags(BitFieldModel):
syn: bool = Bit(0)
ack: bool = Bit(1)
fin: bool = Bit(2)
struct_config = StructConfig(
mode=StructMode.C_COMPATIBLE,
bit_width=16,
byte_order=ByteOrder.BIG_ENDIAN
)
flags = NetworkFlags(packed_value=b'\x00\x03') # SYN and ACK set
Embedding in StructModel¶
BitFieldModel instances can be nested within StructModel:
class Packet(StructModel):
flags: FilePermissions # Embedded bit field
data: bytes = Field(json_schema_extra={"max_length": 64})
struct_config = StructConfig(
mode=StructMode.C_COMPATIBLE,
byte_order=ByteOrder.LITTLE_ENDIAN
)
# The flags field packs as a single byte within the struct
packet = Packet(
flags=FilePermissions(read=True, write=True),
data=b"hello"
)
binary = packet.to_bytes()
Class Reference¶
Bit Function¶
Bit(start_bit, *additional_bits, **kwargs)
¶
Define a bit field within a BitFieldModel.
Creates a Pydantic Field with bit position metadata. Use this to map model attributes to specific bit positions within the packed integer representation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_bit
|
int
|
The starting bit position (0-indexed from LSB). |
required |
*additional_bits
|
int
|
Additional contiguous bit positions for multi-bit integer fields.
For single-bit boolean fields, omit this. For multi-bit fields, list all bit
positions (e.g., |
()
|
**kwargs
|
Any
|
Additional arguments passed to Pydantic's Field(), such as |
{}
|
Returns:
| Type | Description |
|---|---|
FieldInfo
|
A Pydantic FieldInfo configured for bit field usage. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If bit positions are not contiguous. |
Example
from pdc_struct import BitFieldModel, Bit, StructConfig, StructMode
class StatusByte(BitFieldModel): ... # Single-bit boolean fields ... enabled: bool = Bit(0) # Bit 0 ... ready: bool = Bit(1) # Bit 1 ... error: bool = Bit(7) # Bit 7 ... ... # Multi-bit integer field (bits 2-4, values 0-7) ... priority: int = Bit(2, 3, 4) ... ... struct_config = StructConfig( ... mode=StructMode.C_COMPATIBLE, ... bit_width=8 ... )
status = StatusByte(enabled=True, priority=5) status.packed_value # Binary: 00010101 21
Source code in pdc_struct/models/bit_field.py
BitFieldModel Class¶
BitFieldModel
¶
Bases: BaseModel
Base model for bit field structures, enabling packing of multiple boolean or integer values into a single byte/word/dword for C-compatible serialization.
BitFieldModel maps Python attributes to bits within an integer, facilitating compact
storage and C struct compatibility. Fields are defined using Bit() to specify their
position and width:
Example
class Flags(BitFieldModel): read: bool = Bit(0) # Maps to bit 0 write: bool = Bit(1) # Maps to bit 1 value: int = Bit(2,3,4) # Maps to bits 2-4
struct_config = StructConfig(
mode=StructMode.C_COMPATIBLE,
bit_width=8 # Must be 8, 16, or 32
)
Access individual fields as normal attributes. Use packed_value property to get/set the packed integer representation for serialization.
Source code in pdc_struct/models/bit_field.py
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | |
struct_config = StructConfig()
class-attribute
¶
packed_value
property
writable
¶
Get or set the packed integer representation of all bit fields.
When getting, combines all field values into a single integer by setting bits according to each field's position and width.
When setting, unpacks the integer and updates all field values accordingly.
Returns:
| Type | Description |
|---|---|
int
|
The integer value with all bit fields packed according to their positions. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a field value is out of range for its bit width. |
Example
from pdc_struct import BitFieldModel, Bit, StructConfig, StructMode
class Permissions(BitFieldModel): ... read: bool = Bit(0) ... write: bool = Bit(1) ... execute: bool = Bit(2) ... ... struct_config = StructConfig( ... mode=StructMode.C_COMPATIBLE, ... bit_width=8 ... )
Get packed value¶
perms = Permissions(read=True, write=True, execute=False) perms.packed_value 3
Set packed value (updates all fields)¶
perms.packed_value = 7 # All permissions enabled perms.read, perms.write, perms.execute (True, True, True)
struct_format_string
property
¶
Get the struct format string for this bit field.
clone(**field_updates)
¶
Create a new instance with the same packed value but optionally override specific fields.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**field_updates
|
Any
|
Field values to override in the new instance. Any fields not specified will retain their values from the current instance. |
{}
|
Returns:
| Type | Description |
|---|---|
BitFieldModel
|
A new instance of the same class with the specified updates applied. |
Examples:
>>> flags = ByteFlags(packed_value=b'ÿ') # all bits set
>>> new_flags = flags.clone(read=False) # copy state but clear read bit
Source code in pdc_struct/models/bit_field.py
See Also¶
StructConfig- Configuration includingbit_widthStructModel- Embedding bit fields in structs- BitFields Guide - Detailed usage patterns