4.1. Byteorder and Architecture#

4.1.1. Byteorder#

class caterpillar.byteorder.ByteOrder(name: str, ch: str, alignment: Alignment = Alignment.NONE, size: Size = Size.STANDARD)[source]#

Represents byte order information, including alignment and size.

Parameters:
  • name – A string representing the name of the byte order.

  • ch – A string representing the character used to specify the byte order in struct format strings.

  • alignment – An enumeration representing the alignment (default is Alignment.NONE).

  • size – An enumeration representing the size (default is Size.STANDARD).

class Alignment(*values)[source]#
class Size(*values)[source]#
apply(other)[source]#

Applies the byte order information to another object.

Parameters:

other – The object to which the byte order information should be applied.

class caterpillar.byteorder.DynByteOrder(name=None, key=None, func=None, init_ch=None)[source]#

Represents a dynamic byte order resolved at runtime.

A dynamic byte order defers endian resolution until pack or unpack execution. Resolution may depend on the active context, a field value, or a user-provided callable.

Supported concepts:

  • Root context resolution using CTX_ORDER

  • Context key lookup using a string or callable

  • Runtime resolution using a function

  • Per-field byte order overrides using addition syntax

Using the root context byte order:

@struct(order=Dynamic)
class Format:
    a: uint16
    b: uint32

pack(obj, **{CTX_ORDER: BigEndian})

Using a context key:

@struct(order=Dynamic(this.spec))
class Format:
    spec: uint8
    a: uint16

Using a function:

def func():
    return BigEndian

@struct(order=DynByteOrder(func=func))
class Format:
    a: uint16

Using a per-field dynamic byte order:

a: Dynamic(this.spec) + uint16
Parameters:
  • name (str, optional) – Human readable name for the byte order, defaults to None

  • key (str or callable, optional) – Context key or callable used to resolve byte order, defaults to None

  • func (callable, optional) – Callable returning an object with a ch attribute, defaults to None

  • init_ch (str, optional) – Initial format character, defaults to None

getch(context) str[source]#

Resolve the byte order format character from a context.

Resolution order:

  1. Function result, with or without context

  2. Context key lookup

  3. Root context CTX_ORDER value

  4. Boolean or string fallback

Resolution prioritizes a callable, then a context key, and finally a root context fallback with default behavior. :param context: Context providing byte order information :type context: object :return: Struct format character representing byte order :rtype: str

property ch: str#

Return the active byte order character.

The value may change dynamically by inspecting the caller frame and extracting a local variable named context.

Returns:

Struct format character for byte order

Return type:

str

caterpillar.byteorder.byteorder(obj, default: ByteOrder | None = None) ByteOrder[source]#

Get the byte order of an object, defaulting to SysNative if not explicitly set.

Parameters:

obj – The object to retrieve the byte order from.

Returns:

The byte order of the object.

caterpillar.byteorder.byteorder_is_little(obj) bool[source]#

Check if the byte order of an object is little-endian.

4.1.1.1. Standard Byteorder Instances#

byteorder.Native = ByteOrder(name='Native', ch='=', alignment=<Alignment.NONE: 0>, size=<Size.STANDARD: 0>)#
byteorder.BigEndian = ByteOrder(name='Big Endian', ch='>', alignment=<Alignment.NONE: 0>, size=<Size.STANDARD: 0>)#
byteorder.LittleEndian = ByteOrder(name='Little Endian', ch='<', alignment=<Alignment.NONE: 0>, size=<Size.STANDARD: 0>)#
byteorder.NetEndian = ByteOrder(name='Network', ch='!', alignment=<Alignment.NONE: 0>, size=<Size.STANDARD: 0>)#
byteorder.SysNative = ByteOrder(name='SysNative', ch='@', alignment=<Alignment.NATIVE: 1>, size=<Size.NATIVE: 1>)#
byteorder.Dynamic = <DynByteOrder little=True>#

4.1.2. Architecture#

class caterpillar.byteorder.Arch(name: str, ptr_size: int)[source]#

Represents a system architecture with a name and an indication of whether it is 64-bit.

Parameters:
  • name – The name of the architecture.

  • ptr_size – the amount of bits one pointer takes

byteorder.system_arch: Arch = Arch(name='x86_64', ptr_size=64)#

4.1.2.1. Standard Architectures#

byteorder.x86 = Arch(name='x86', ptr_size=32)#
byteorder.x86_64 = Arch(name='x86-64', ptr_size=64)#
byteorder.ARM = Arch(name='ARM', ptr_size=32)#
byteorder.ARM64 = Arch(name='ARM64', ptr_size=64)#
byteorder.AARCH64 = Arch(name='ARM64', ptr_size=64)#
byteorder.PowerPC = Arch(name='PowerPC', ptr_size=32)#
byteorder.PowerPC64 = Arch(name='PowerPC64', ptr_size=64)#
byteorder.MIPS = Arch(name='MIPS', ptr_size=32)#
byteorder.MIPS64 = Arch(name='MIPS64', ptr_size=64)#
byteorder.SPARC = Arch(name='SPARC', ptr_size=32)#
byteorder.SPARC64 = Arch(name='SPARC64', ptr_size=64)#
byteorder.RISC_V64 = Arch(name='RISK-V64', ptr_size=64)#
byteorder.RISC_V = Arch(name='RISK-V', ptr_size=32)#
byteorder.AMD = Arch(name='AMD', ptr_size=32)#
byteorder.AMD64 = Arch(name='AMD64', ptr_size=64)#