Conversions¶
Bytemaker leverages its BitTypes classes to C Bitfield functionality in Python. bytemaker.conversions.aggregate_types.to_bits_aggregate and bytemaker.aggregate_types.from_bits_aggregate are the primary methods for accomplishing this.
pytypes.py contains methods and configuration options for automatically converting native Python types to bits. This is accomplished through bytemaker.conversions.pytypes.ConversionConfig, which controls the bytemaker.conversions.pytypes.bits_to_pytype and bytemaker.conversions.pytypes.pytype_to_bits methods for converting single instances of Python types to/from BitVectors.
ctypes_.py contains methods for converting Python’s ctypes data structures to/from BitVector objects, generalized by bytemaker.conversions.ctypes_.bits_to_ctype and bytemaker.conversions.ctypes_.ctype_to_bits
Finally, aggregate_types.py contains methods for combining the above conversions into single methods that handle instances of ctypes, Python native types, and BitTypes. These methods are count_bits_in_unit_type.
[3]:
import ctypes
from bytemaker.bittypes import SInt32, Float32, Buffer4, Str8
from bytemaker.conversions.aggregate_types import to_bits_aggregate, from_bits_aggregate
from dataclasses import dataclass
@dataclass
class PyTypeAggregate:
a: int
b: float
c: str # Char
d: str # Char
@dataclass
class CTypeAggregate:
a: ctypes.c_int32
b: ctypes.c_float
c: ctypes.c_char
d: ctypes.c_char
@dataclass
class YTypeAggregate:
a: SInt32
b: Float32
c: Str8
d: Str8
e: Buffer4
@dataclass
class MixedAggregate:
pytype_aggregate: PyTypeAggregate
ctype_aggregate: CTypeAggregate
ytype_aggregate: YTypeAggregate
hp: int
mixedagg = MixedAggregate(
PyTypeAggregate(
512,
3.14,
'A',
'B'
),
CTypeAggregate(
ctypes.c_int32(512),
ctypes.c_float(3.14),
ctypes.c_char('A'.encode('utf-8')),
ctypes.c_char('B'.encode('utf-8'))
),
YTypeAggregate(
SInt32(382),
Float32(3.14),
Str8('A'),
Str8('B'),
Buffer4('0b0101')
),
255
)
mixed_agg_as_bits = to_bits_aggregate(mixedagg)
print(mixed_agg_as_bits.hex(bytes_per_sep=2, sep='_'))
mixedagg.ytype_aggregate.a = SInt32(512)
mixed_agg_as_bits = to_bits_aggregate(mixedagg)
print(mixed_agg_as_bits.hex(bytes_per_sep=2, sep='_'))
mixed_agg_from_bits = from_bits_aggregate(mixed_agg_as_bits, MixedAggregate)
print(mixed_agg_from_bits)
0x0000_0200_4048_f5c3_4142_0000_0200_4048_f5c3_4142_0000_017e_4048_f5c3_4142_5000_000f_f
0x0000_0200_4048_f5c3_4142_0000_0200_4048_f5c3_4142_0000_0200_4048_f5c3_4142_5000_000f_f
MixedAggregate(pytype_aggregate=PyTypeAggregate(a=512, b=3.140000104904175, c='A', d='B'), ctype_aggregate=CTypeAggregate(a=c_long(512), b=c_float(3.140000104904175), c=c_char(b'A'), d=c_char(b'B')), ytype_aggregate=YTypeAggregate(a=SInt32(bits=BitVector('00000000 00000000 00000010 00000000'), endianness=big), b=Float32(bits=BitVector('01000000 01001000 11110101 11000011'), endianness=big), c=Str8(bits=BitVector('01000001'), endianness=big), d=Str8(bits=BitVector('01000010'), endianness=big), e=Buffer4(bits=BitVector('0101'), endianness=big)), hp=255)