Package: quickstruct
QuickStructQuickStruct 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 usefromquickstructimport*classPerson(DataStruct):name:Stringage:i8Structs can also be composedclassTeachingClass(DataStruct):teacher:Person# We use Array[T] to make it dynamic sizedstudents:Array[Person]And structs can also inherit other structs
(we even support multiple inheritance!)classEmployee(Person):salary:i32Now let's use the structs we defined# We have 2 options when initializing.# Either by setting each attribute individuallyperson=Person()person.name="John Doe"person.age=42# Or by passing them as keyword argumentsperson=Person(name="John Doe",age=42)The main use for C structs is to convert them from bytes and backdata=person.to_bytes()# Do something with the data# And it's also easy to deserializeperson=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 StructsA 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.classFixedSizeStruct(DataStruct,flags=StructFlags.FixedSize):a:i32b:i8c:f32d:chare:String[10]# 10 character stringf:Person[3]# 3 'person' objects# g: Array[i32] <- not a fixed size field. this will errorStruct PropertiesIt is possible to query some information about a structure.fromquickstructimport*classFixed(DataStruct):s:String[10]x:i32classDynamic(DataStruct):s:Stringx:i32print("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)# Trueprint("Dynamic.is_fixed_size:",Dynamic.is_fixed_size)# Falseprint("Fixed.is_dynamic_size:",Fixed.is_dynamic_size)# Falseprint("Dynamic.is_dynamic_size:",Dynamic.is_dynamic_size)# Trueprint("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)# Falseprint("Dynamic.is_final:",Dynamic.is_final)# Falseprint("Fixed.is_protected:",Fixed.is_protected)# Falseprint("Dynamic.is_protected:",Dynamic.is_protected)# FalseAlignmentIt is also possible to add padding to the struct. There are 2 ways to do that:Manual AlignmentThis can be done with thePaddingtype.classAlignedStruct(DataStruct):c1:char# This adds a single byte padding_pad0:Paddingshort:i16# We can also add multi-byte padding# Here we'll pad to get 8 byte alignment (missing 4 bytes)_pad1:Padding[4]Automatic AlignmentThis can done by passing some flags to the class definition. By default the struct is automatically aligned.# Aligned on 2 byte boundaryclassAlignedStruct(DataStruct,flags=StructFlags.Align2Bytes):c1:char# Padding will be added hereshort:i16Struct FlagsFlagDescriptionDefaultThe default to use if no flags are given. Same asAllowOverride | AlignAuto.NoAlignmentThis is the most packed form of the struct. All fields are adjacent with no padding (unless manually added)PackedSame asNoAlignmentexcept thatNoAlignmentis a bit more optimized because no alignment is done.Align1ByteSame asPackedAlign2BytesAligns the fields on 2 byte boundary.Align4BytesAligns the fields on 4 byte boundary.Align8BytesAligns the fields on 8 byte boundary.AlignAutoAligns the fields by their type.ReorderFieldsSpecifies the fields should be reordered in order to make the struct a little more compressed.ForceDataOnlyDeprecated. Specifies that the struct may only contain serializable fields. Data-only structs may only inherit data-only structs.AllowOverrideIf set, fields defined in the struct may override fields that are defined in the base struct.TypeSafeOverrideIf set, when fields are overridden, they must have the same type (which would make it pretty useless to override). ImpliesAllowOverride. If fields have a different type, anUnsafeOverrideErroris raised.ForceSafeOverrideDeprectaed. Same asTypeSafeOverride.FixedSizeIf set, the struct must have a fixed size. If not, an exceptionSizeErroris raised.ForceFixedSizeDeprecated. Same asFixedSize.AllowInlineDeprecated. If set, the struct's fields will be inlined into another struct the contains this struct.ProtectedIf set, denies any overrides of that structure. If a struct is trying to override a field of it, anUnoverridableFieldErroris raised.LockedStructureDeprecated. Same asProtected.FinalMarks the structure so it won't be inheritable by any other class. If a struct is trying to inherit it, anInheritanceErroris raised.