@@ -22,6 +22,274 @@ serializing the values into an array of bytes.
2222
2323[ Api Documentation] ( https://python-cstruct.readthedocs.io/en/latest/ )
2424
25+ Install
26+ -------
27+
28+ ```
29+ pip install cstruct
30+ ```
31+
32+ Features
33+ --------
34+
35+ ### Structs
36+
37+ Struct definition subclassing ` cstruct.MemCStruct `
38+
39+ ``` python
40+ class Position (cstruct .MemCStruct ):
41+ __def__ = """
42+ struct {
43+ unsigned char head;
44+ unsigned char sector;
45+ unsigned char cyl;
46+ }
47+ """
48+
49+ pos = Position(head = 10 , sector = 20 , cyl = 30 )
50+ print (f " head: { pos.head} sector: { pos.sector} cyl: { pos.cyl} " )
51+ ```
52+
53+ Struct definition using ` cstruct.parse `
54+
55+ ``` python
56+ Partition = cstruct.parse("""
57+ struct {
58+ #define ACTIVE_FLAG 0x80
59+
60+ unsigned char status; /* 0x80 - active */
61+ struct Position start;
62+ unsigned char partition_type;
63+ struct Position end;
64+ unsigned int start_sect; /* starting sector counting from 0 */
65+ unsigned int sectors; /* nr of sectors in partition */
66+ }
67+ """ )
68+
69+ part = Partition()
70+ part.status = cstruct.getdef(' ACTIVE_FLAG' )
71+ ```
72+
73+ ### Unions
74+
75+ Union definition subclassing ` cstruct.MemCStruct `
76+
77+ ``` python
78+ class Data (cstruct .MemCStruct ):
79+ __def__ = """
80+ union {
81+ int integer;
82+ float real;
83+ }
84+ """
85+
86+ data = Data()
87+ data.integer = 2
88+ data.real = 3
89+ assert data.integer != 2
90+ ```
91+
92+ ### Enums
93+
94+ Enum definition subclassing ` cstruct.CEnum `
95+
96+ ``` python
97+ class HtmlFont (cstruct .CEnum ):
98+ __size__ = 2
99+ __def__ = """
100+ #define NONE 0
101+
102+ enum htmlfont {
103+ HTMLFONT_NONE = NONE,
104+ HTMLFONT_BOLD,
105+ HTMLFONT_ITALIC
106+ }
107+ """
108+
109+ assert HtmlFont.HTMLFONT_NONE == 0
110+ assert HtmlFont.HTMLFONT_BOLD == 1
111+ assert HtmlFont.HTMLFONT_ITALIC == 2
112+ ```
113+
114+ Different supported ` __def__ ` styles:
115+
116+ ``` c
117+ enum Type_A a; // externally defined using CEnum
118+ enum Type_B {A, B, C} b;
119+ enum {A, B, C} c;
120+ ```
121+
122+ ```python
123+ class Type_A(cstruct.CEnum):
124+ __size__ = 2
125+ __enum__ = """
126+ #define SOME_DEFINE 7
127+
128+ A,
129+ B,
130+ C = 5,
131+ D,
132+ E = 7 + SOME_DEFINE
133+ """
134+
135+ # this is a nice gimmick that works, but wasn't really planned to be supported
136+ class Type_C(cstruct.CEnum):
137+ A = 0,
138+ B = 1,
139+ C = 2,
140+ D = 3
141+ ```
142+
143+ ### Nested structures (named/anonymous)
144+
145+ ``` python
146+ class Packet (cstruct .MemCStruct ):
147+ __def__ = """
148+ struct Packet {
149+ uint8_t packetLength;
150+ union {
151+ struct {
152+ uint16_t field1;
153+ uint16_t field2;
154+ uint16_t field3;
155+ } format1;
156+ struct {
157+ double value1;
158+ double value2;
159+ } format2;
160+ };
161+ };
162+ """
163+ ```
164+
165+ ### Byte Order, Size, and Padding
166+
167+ Suported byte orders:
168+
169+ * ` cstruct.LITTLE_ENDIAN ` - Little endian byte order, standard size, no padding
170+ * ` cstruct.BIG_ENDIAN ` - Big endian byte order, standard size, no padding
171+ * ` cstruct.NATIVE_ORDER ` - Native byte order, native size, padding
172+
173+ ``` python
174+ class Native (cstruct .MemCStruct ):
175+ __byte_order__ = cstruct.NATIVE_ORDER
176+ __def__ = """
177+ struct {
178+ long p;
179+ char c;
180+ long x;
181+ }
182+ """
183+ ```
184+
185+ ### Flexible Array Member
186+
187+ ``` python
188+ class Pkg (cstruct .MemCStruct ):
189+ __byte_order__ = cstruct.LITTLE_ENDIAN
190+ __def__ = """
191+ struct {
192+ uint16_t cmd;
193+ uint16_t length;
194+ uint8_t data[];
195+ }
196+ """
197+
198+ pkg = Pkg()
199+ pkg.length = 4
200+ pkg.data = [10 , 20 , 30 , 40 ]
201+ ```
202+
203+ ### Pack and Unpack
204+
205+ ``` python
206+ class StructWithEnum (cstruct .MemCStruct ):
207+ __byte_order__ = cstruct.LITTLE_ENDIAN
208+ __def__ = """
209+ struct StructWithEnum {
210+ enum HtmlFont font;
211+ unsigned int font_size;
212+ }
213+ """
214+
215+ # Pack
216+ s.font = HtmlFont.HTMLFONT_NONE
217+ s.font_size = 20
218+ assert s.font == HtmlFont.HTMLFONT_NONE
219+ assert s.font_size == 20
220+ packed = s.pack()
221+
222+ # Unpack
223+ s1 = StructWithEnum()
224+ s1.unpack(packed)
225+ assert s1.font == HtmlFont.HTMLFONT_NONE
226+ assert s1.font_size == 20
227+ ```
228+
229+ ### Define, Sizeof, and Eval
230+
231+ Definitions in Struct declaration:
232+
233+ ``` python
234+ class Packet (cstruct .MemCStruct ):
235+ __byte_order__ = cstruct.LITTLE_ENDIAN
236+ __def__ = """
237+ #define MaxPacket 20
238+
239+ struct Packet {
240+ uint8_t bytes[MaxPacket];
241+ }
242+ """
243+ ```
244+
245+ Parse C definitions:
246+
247+ ``` python
248+ cstruct.parse("""
249+ #define A1 10
250+ #define A2 10 + A1
251+ #define A3 30
252+ """ )
253+ assert cstruct.getdef(" A1" ) == 10
254+ assert cstruct.getdef(' A2' ) == 20
255+ ```
256+
257+ Get structure size:
258+
259+ ``` python
260+ cstruct.sizeof(Partition)
261+ ```
262+
263+ Evaluate C expression:
264+
265+ ``` python
266+ cstruct.c_eval(" A1 / 10" )
267+ cstruct.c_eval(" ((A10 < 6) || (A10>10))" )
268+ ```
269+
270+ C expressions are automatically evaluated during structure definitions:
271+
272+ ``` python
273+ class MBR (cstruct .MemCStruct ):
274+ __byte_order__ = cstruct.LITTLE_ENDIAN
275+ __struct__ = """
276+ #define MBR_SIZE 512
277+ #define MBR_DISK_SIGNATURE_SIZE 4
278+ #define MBR_USUALY_NULLS_SIZE 2
279+ #define MBR_SIGNATURE_SIZE 2
280+ #define MBR_BOOT_SIGNATURE 0xaa55
281+ #define MBR_PARTITIONS_NUM 4
282+ #define MBR_PARTITIONS_SIZE (sizeof(Partition) * MBR_PARTITIONS_NUM)
283+ #define MBR_UNUSED_SIZE (MBR_SIZE - MBR_DISK_SIGNATURE_SIZE - MBR_USUALY_NULLS_SIZE - MBR_PARTITIONS_SIZE - MBR_SIGNATURE_SIZE)
284+
285+ char unused[MBR_UNUSED_SIZE];
286+ unsigned char disk_signature[MBR_DISK_SIGNATURE_SIZE];
287+ unsigned char usualy_nulls[MBR_USUALY_NULLS_SIZE];
288+ struct Partition partitions[MBR_PARTITIONS_NUM];
289+ uint16 signature;
290+ """
291+ ```
292+
25293Example
26294-------
27295
0 commit comments