Skip to main content

A small library to ease the creation, usage, serialization and deserialization of C structs.

Project description

QuickStruct

QuickStruct is a small library written in Python that allows you to easily create C structs (and a bit more dynamic stuff) in Python!

It's fairly easy to use

from quickstruct import *

class Person(DataStruct):
    name: String
    age: i8

Structs can also be composed

class TeachingClass(DataStruct):
    teacher: Person
    # We use Array[T] to make it dynamic sized
    students: Array[Person]

And structs can also inherit other structs (we even support multiple inheritance!)

class Employee(Person):
    salary: i32

Now let's use the structs we defined

# We have 2 options when initializing.
# Either by setting each attribute individually
person = Person()
person.name = "John Doe"
person.age = 42

# Or by passing them as keyword arguments
person = Person(name="John Doe", age=42)

The main use for C structs is to convert them from bytes and back

data = person.to_bytes()
# Do something with the data

# And it's also easy to deserialize
person = Person.from_bytes(data)

When deserializing a struct with multiple bases or if one of the fields was overriden, the deserialization must be done through the exact type of the struct.

Fixed Size Structs

A fixed size struct is any struct that has a known fixed size at build time that doesn't depend on the data it holds. QuickStruct can verify a struct has a fixed size.

# The StructFlags.FixedSize flag is used to verify the struct has a fixed size.
# If the size could not be verified, a SizeError is raised.
class FixedSizeStruct(DataStruct, flags=StructFlags.FixedSize):
    a: i32
    b: i8
    c: f32
    d: char
    e: String[10] # 10 character string
    f: Person[3] # 3 'person' objects
    # g: Array[i32] <- not a fixed size field. this will error

Struct Properties

It is possible to query some information about a structure.

from quickstruct import *
class Fixed(DataStruct):
    s: String[10]
    x: i32

class Dynamic(DataStruct):
    s: String
    x: i32

print("Fixed.size:", Fixed.size) # 16 (padding automatically added)
print("Dynamic.size:", Dynamic.size) # -1 (dynamic size)

print("Fixed.is_fixed_size:", Fixed.is_fixed_size) # True
print("Dynamic.is_fixed_size:", Dynamic.is_fixed_size) # False

print("Fixed.is_dynamic_size:", Fixed.is_dynamic_size) # False
print("Dynamic.is_dynamic_size:", Dynamic.is_dynamic_size) # True

print("Fixed.fields:", Fixed.fields) # [s: String[10], __pad_0__: Padding(2), x: i32]
print("Dynamic.fields:", Dynamic.fields) # [s: String, x: i32]

print("Fixed.alignment:", Fixed.alignment) # 16.
print("Dynamic.alignment:", Dynamic.alignment) # -1 (no alignment because dynamic struct can't be aligned).

print("Fixed.is_final:", Fixed.is_final) # False
print("Dynamic.is_final:", Dynamic.is_final) # False

print("Fixed.is_protected:", Fixed.is_protected) # False
print("Dynamic.is_protected:", Dynamic.is_protected) # False

Alignment

It is also possible to add padding to the struct. There are 2 ways to do that:

Manual Alignment

This can be done with the Padding type.

class AlignedStruct(DataStruct):
    c1: char
    # This adds a single byte padding
    _pad0: Padding
    short: i16
    # We can also add multi-byte padding
    # Here we'll pad to get 8 byte alignment (missing 4 bytes)
    _pad1: Padding[4]

Automatic Alignment

This can done by passing some flags to the class definition. By default the struct is automatically aligned.

# Aligned on 2 byte boundary
class AlignedStruct(DataStruct, flags = StructFlags.Align2Bytes):
    c1: char
    # Padding will be added here
    short: i16

Struct Flags

Flag Description
Default The default to use if no flags are given. Same as AllowOverride | AlignAuto.
NoAlignment This is the most packed form of the struct. All fields are adjacent with no padding (unless manually added)
Packed Same as NoAlignment except that NoAlignment is a bit more optimized because no alignment is done.
Align1Byte Same as Packed
Align2Bytes Aligns the fields on 2 byte boundary.
Align4Bytes Aligns the fields on 4 byte boundary.
Align8Bytes Aligns the fields on 8 byte boundary.
AlignAuto Aligns the fields by their type.
ReorderFields Specifies the fields should be reordered in order to make the struct a little more compressed.
ForceDataOnly Deprecated. Specifies that the struct may only contain serializable fields. Data-only structs may only inherit data-only structs.
AllowOverride If set, fields defined in the struct may override fields that are defined in the base struct.
TypeSafeOverride If set, when fields are overridden, they must have the same type (which would make it pretty useless to override). Implies AllowOverride. If fields have a different type, an UnsafeOverrideError is raised.
ForceSafeOverride Deprectaed. Same as TypeSafeOverride.
FixedSize If set, the struct must have a fixed size. If not, an exception SizeError is raised.
ForceFixedSize Deprecated. Same as FixedSize.
AllowInline Deprecated. If set, the struct's fields will be inlined into another struct the contains this struct.
Protected If set, denies any overrides of that structure. If a struct is trying to override a field of it, an UnoverridableFieldError is raised.
LockedStructure Deprecated. Same as Protected.
Final Marks the structure so it won't be inheritable by any other class. If a struct is trying to inherit it, an InheritanceError is raised.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

quickstruct-0.2.1.tar.gz (13.2 kB view details)

Uploaded Source

Built Distribution

quickstruct-0.2.1-py3-none-any.whl (12.9 kB view details)

Uploaded Python 3

File details

Details for the file quickstruct-0.2.1.tar.gz.

File metadata

  • Download URL: quickstruct-0.2.1.tar.gz
  • Upload date:
  • Size: 13.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for quickstruct-0.2.1.tar.gz
Algorithm Hash digest
SHA256 3ff4627c3b4275555fc1528e0188f797b9489934828383f2bb3209338d729352
MD5 32cd87895632ced73b3d665d7b0214b2
BLAKE2b-256 0a05447b70eb7b4ad3ad60b65d3fc2501ade9571e2e227f0e59b10d001f1e08d

See more details on using hashes here.

File details

Details for the file quickstruct-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: quickstruct-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 12.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for quickstruct-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5b5f2081791ac353e091fbfb010c772aee8d3e86ca47ec3af1e0942f03781248
MD5 86910d0db0e5cf5be323c776db37b876
BLAKE2b-256 aca89921540974f9b5c776144a3600272874916ff76c00512e27d3f3c6c7aa9e

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page