1
- from ctypes import Structure , c_char , c_uint32 , c_ubyte , alignment
1
+ from ctypes import Structure , c_char , c_uint32 , c_ubyte , alignment , sizeof , Union
2
2
import inspect
3
3
import unittest
4
4
@@ -22,11 +22,11 @@ class Main(Structure):
22
22
('string' , Aligned ),
23
23
]
24
24
25
- d = Main .from_buffer (data )
26
- self .assertEqual (d .first , 7 )
27
- self .assertEqual (d .string .value , b'hello world!' )
25
+ main = Main .from_buffer (data )
26
+ self .assertEqual (main .first , 7 )
27
+ self .assertEqual (main .string .value , b'hello world!' )
28
28
self .assertEqual (
29
- bytes (d .string .__buffer__ (inspect .BufferFlags .SIMPLE )),
29
+ bytes (main .string .__buffer__ (inspect .BufferFlags .SIMPLE )),
30
30
b'\x68 \x65 \x6c \x6c \x6f \x20 \x77 \x6f \x72 \x6c \x64 \x21 \x00 \x00 \x00 \x00 '
31
31
)
32
32
@@ -60,12 +60,12 @@ class MainTooBig(Structure):
60
60
("x" , SomeBoolsTooBig ),
61
61
("y" , c_uint32 ),
62
62
]
63
- d = Main .from_buffer (data )
64
- self .assertEqual (d .y , 7 )
63
+ main = Main .from_buffer (data )
64
+ self .assertEqual (main .y , 7 )
65
65
self .assertEqual (alignment (SomeBools ), 4 )
66
- self .assertEqual (d .x .bool1 , True )
67
- self .assertEqual (d .x .bool2 , False )
68
- self .assertEqual (d .x .bool3 , True )
66
+ self .assertEqual (main .x .bool1 , True )
67
+ self .assertEqual (main .x .bool2 , False )
68
+ self .assertEqual (main .x .bool3 , True )
69
69
70
70
with self .assertRaises (ValueError ) as ctx :
71
71
MainTooBig .from_buffer (data )
@@ -74,5 +74,92 @@ class MainTooBig(Structure):
74
74
'Buffer size too small (4 instead of at least 8 bytes)'
75
75
)
76
76
77
+ def test_aligned_subclasses (self ):
78
+ data = bytearray (
79
+ b"\x01 \x00 \x00 \x00 \x02 \x00 \x00 \x00 \x03 \x00 \x00 \x00 \x04 \x00 \x00 \x00 "
80
+ )
81
+
82
+ class UnalignedSub (Structure ):
83
+ x : c_uint32
84
+ _fields_ = [
85
+ ("x" , c_uint32 ),
86
+ ]
87
+
88
+ class AlignedStruct (UnalignedSub ):
89
+ _align_ = 8
90
+ y : c_uint32
91
+ _fields_ = [
92
+ ("y" , c_uint32 ),
93
+ ]
94
+
95
+ class Main (Structure ):
96
+ _fields_ = [
97
+ ("a" , c_uint32 ),
98
+ ("b" , AlignedStruct )
99
+ ]
100
+
101
+ main = Main .from_buffer (data )
102
+ self .assertEqual (alignment (main .b ), 8 )
103
+ self .assertEqual (alignment (main ), 8 )
104
+ self .assertEqual (sizeof (main .b ), 8 )
105
+ self .assertEqual (sizeof (main ), 16 )
106
+ self .assertEqual (main .a , 1 )
107
+ self .assertEqual (main .b .x , 3 )
108
+ self .assertEqual (main .b .y , 4 )
109
+
110
+ def test_aligned_union (self ):
111
+ data = bytearray (
112
+ b"\x01 \x00 \x00 \x00 \x02 \x00 \x00 \x00 \x03 \x00 \x00 \x00 \x04 \x00 \x00 \x00 "
113
+ )
114
+
115
+ class AlignedUnion (Union ):
116
+ _align_ = 8
117
+ _fields_ = [
118
+ ("a" , c_uint32 ),
119
+ ("b" , c_ubyte * 8 ),
120
+ ]
121
+
122
+ class Main (Structure ):
123
+ _fields_ = [
124
+ ("first" , c_uint32 ),
125
+ ("union" , AlignedUnion ),
126
+ ]
127
+
128
+ main = Main .from_buffer (data )
129
+ self .assertEqual (main .first , 1 )
130
+ self .assertEqual (main .union .a , 3 )
131
+ self .assertEqual (bytes (main .union .b ), b"\x03 \x00 \x00 \x00 \x04 \x00 \x00 \x00 " )
132
+
133
+ def test_aligned_struct_in_union (self ):
134
+ data = bytearray (
135
+ b"\x01 \x00 \x00 \x00 \x02 \x00 \x00 \x00 \x03 \x00 \x00 \x00 \x04 \x00 \x00 \x00 "
136
+ )
137
+
138
+ class Sub (Structure ):
139
+ _align_ = 8
140
+ _fields_ = [
141
+ ("x" , c_uint32 ),
142
+ ("y" , c_uint32 ),
143
+ ]
144
+
145
+ class MainUnion (Union ):
146
+ _fields_ = [
147
+ ("a" , c_uint32 ),
148
+ ("b" , Sub ),
149
+ ]
150
+
151
+ class Main (Structure ):
152
+ _fields_ = [
153
+ ("first" , c_uint32 ),
154
+ ("union" , MainUnion ),
155
+ ]
156
+
157
+ main = Main .from_buffer (data )
158
+ self .assertEqual (main .first , 1 )
159
+ self .assertEqual (main .union .a , 3 )
160
+ self .assertEqual (main .union .b .x , 3 )
161
+ self .assertEqual (main .union .b .y , 4 )
162
+
163
+
77
164
if __name__ == '__main__' :
78
165
unittest .main ()
0 commit comments