In embedded systems, binary file formats, and network protocols, space is at a premium. Instead of using a whole int for a boolean flag, programmers often pack multiple small values into a single byte. For example, a single 8-bit value might store a 3-bit version number, a 1-bit status flag, and a 4-bit command code.

In C, this is handled via Bitfields. In standard Perl, you would have to use complex bitwise math (>>, &, |). In Affix, you can define these fields directly in your Struct and let the JIT engine handle the math for you.

The Recipe

We will build a parser for a hypothetical hardware "Control Register."

use v5.40;
use Affix qw[:all];

# Define the Packed Structure
# C equivalent:
# struct ControlRegister {
#     uint8_t enabled  : 1;
#     uint8_t mode     : 3;
#     uint8_t reserved : 2;
#     uint8_t error    : 1;
#     uint8_t interrupt: 1;
# };
typedef ControlRegister => Struct [
    enabled   => UInt8 | 1,    # 1 bit
    mode      => UInt8 | 3,    # 3 bits
    reserved  => UInt8 | 2,    # 2 bits
    error     => UInt8 | 1,    # 1 bit
    interrupt => UInt8 | 1     # 1 bit (Total = 8 bits / 1 byte)
];

# Simulate hardware input
# Raw byte: 0b10001011
#   Interrupt: 1
#   Error:     0
#   Reserved:  00
#   Mode:      101 (5)
#   Enabled:   1
my $ptr = Affix::malloc( sizeof UChar );
memcpy( $ptr, chr 0b10001011, sizeof UChar );    # Direct byte-level access

# 'Map' the structure onto the raw byte
# We use cast to interpret the scalar memory as our struct
my $reg = cast( $ptr, ControlRegister() );

# Access fields naturally
say 'Register Analysis:';
say ' Enabled:   ' . ( $reg->{enabled} ? 'YES' : 'NO' );
say ' Mode:      ' . $reg->{mode};
say ' Error:     ' . ( $reg->{error}     ? 'YES' : 'NO' );
say ' Interrupt: ' . ( $reg->{interrupt} ? 'YES' : 'NO' );

# Modify fields
say 'Disabling hardware and changing mode...';
$reg->{enabled} = 0;
$reg->{mode}    = 2;

# Inspect the raw byte again
my $new_val = unpack( 'C', $ptr );
say sprintf( 'New raw value: 0b%08b', $new_val );

How It Works

Kitchen Reminders