~ubuntu-branches/ubuntu/maverick/python3.1/maverick

« back to all changes in this revision

Viewing changes to Lib/ctypes/test/test_byteswap.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-03-23 00:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090323000127-5fstfxju4ufrhthq
Tags: upstream-3.1~a1+20090322
ImportĀ upstreamĀ versionĀ 3.1~a1+20090322

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import sys, unittest, struct, math
 
2
from binascii import hexlify
 
3
 
 
4
from ctypes import *
 
5
 
 
6
def bin(s):
 
7
    return hexlify(memoryview(s)).decode().upper()
 
8
 
 
9
# Each *simple* type that supports different byte orders has an
 
10
# __ctype_be__ attribute that specifies the same type in BIG ENDIAN
 
11
# byte order, and a __ctype_le__ attribute that is the same type in
 
12
# LITTLE ENDIAN byte order.
 
13
#
 
14
# For Structures and Unions, these types are created on demand.
 
15
 
 
16
class Test(unittest.TestCase):
 
17
    def X_test(self):
 
18
        print(sys.byteorder, file=sys.stderr)
 
19
        for i in range(32):
 
20
            bits = BITS()
 
21
            setattr(bits, "i%s" % i, 1)
 
22
            dump(bits)
 
23
 
 
24
    def test_endian_short(self):
 
25
        if sys.byteorder == "little":
 
26
            self.failUnless(c_short.__ctype_le__ is c_short)
 
27
            self.failUnless(c_short.__ctype_be__.__ctype_le__ is c_short)
 
28
        else:
 
29
            self.failUnless(c_short.__ctype_be__ is c_short)
 
30
            self.failUnless(c_short.__ctype_le__.__ctype_be__ is c_short)
 
31
        s = c_short.__ctype_be__(0x1234)
 
32
        self.failUnlessEqual(bin(struct.pack(">h", 0x1234)), "1234")
 
33
        self.failUnlessEqual(bin(s), "1234")
 
34
        self.failUnlessEqual(s.value, 0x1234)
 
35
 
 
36
        s = c_short.__ctype_le__(0x1234)
 
37
        self.failUnlessEqual(bin(struct.pack("<h", 0x1234)), "3412")
 
38
        self.failUnlessEqual(bin(s), "3412")
 
39
        self.failUnlessEqual(s.value, 0x1234)
 
40
 
 
41
        s = c_ushort.__ctype_be__(0x1234)
 
42
        self.failUnlessEqual(bin(struct.pack(">h", 0x1234)), "1234")
 
43
        self.failUnlessEqual(bin(s), "1234")
 
44
        self.failUnlessEqual(s.value, 0x1234)
 
45
 
 
46
        s = c_ushort.__ctype_le__(0x1234)
 
47
        self.failUnlessEqual(bin(struct.pack("<h", 0x1234)), "3412")
 
48
        self.failUnlessEqual(bin(s), "3412")
 
49
        self.failUnlessEqual(s.value, 0x1234)
 
50
 
 
51
    def test_endian_int(self):
 
52
        if sys.byteorder == "little":
 
53
            self.failUnless(c_int.__ctype_le__ is c_int)
 
54
            self.failUnless(c_int.__ctype_be__.__ctype_le__ is c_int)
 
55
        else:
 
56
            self.failUnless(c_int.__ctype_be__ is c_int)
 
57
            self.failUnless(c_int.__ctype_le__.__ctype_be__ is c_int)
 
58
 
 
59
        s = c_int.__ctype_be__(0x12345678)
 
60
        self.failUnlessEqual(bin(struct.pack(">i", 0x12345678)), "12345678")
 
61
        self.failUnlessEqual(bin(s), "12345678")
 
62
        self.failUnlessEqual(s.value, 0x12345678)
 
63
 
 
64
        s = c_int.__ctype_le__(0x12345678)
 
65
        self.failUnlessEqual(bin(struct.pack("<i", 0x12345678)), "78563412")
 
66
        self.failUnlessEqual(bin(s), "78563412")
 
67
        self.failUnlessEqual(s.value, 0x12345678)
 
68
 
 
69
        s = c_uint.__ctype_be__(0x12345678)
 
70
        self.failUnlessEqual(bin(struct.pack(">I", 0x12345678)), "12345678")
 
71
        self.failUnlessEqual(bin(s), "12345678")
 
72
        self.failUnlessEqual(s.value, 0x12345678)
 
73
 
 
74
        s = c_uint.__ctype_le__(0x12345678)
 
75
        self.failUnlessEqual(bin(struct.pack("<I", 0x12345678)), "78563412")
 
76
        self.failUnlessEqual(bin(s), "78563412")
 
77
        self.failUnlessEqual(s.value, 0x12345678)
 
78
 
 
79
    def test_endian_longlong(self):
 
80
        if sys.byteorder == "little":
 
81
            self.failUnless(c_longlong.__ctype_le__ is c_longlong)
 
82
            self.failUnless(c_longlong.__ctype_be__.__ctype_le__ is c_longlong)
 
83
        else:
 
84
            self.failUnless(c_longlong.__ctype_be__ is c_longlong)
 
85
            self.failUnless(c_longlong.__ctype_le__.__ctype_be__ is c_longlong)
 
86
 
 
87
        s = c_longlong.__ctype_be__(0x1234567890ABCDEF)
 
88
        self.failUnlessEqual(bin(struct.pack(">q", 0x1234567890ABCDEF)), "1234567890ABCDEF")
 
89
        self.failUnlessEqual(bin(s), "1234567890ABCDEF")
 
90
        self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
 
91
 
 
92
        s = c_longlong.__ctype_le__(0x1234567890ABCDEF)
 
93
        self.failUnlessEqual(bin(struct.pack("<q", 0x1234567890ABCDEF)), "EFCDAB9078563412")
 
94
        self.failUnlessEqual(bin(s), "EFCDAB9078563412")
 
95
        self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
 
96
 
 
97
        s = c_ulonglong.__ctype_be__(0x1234567890ABCDEF)
 
98
        self.failUnlessEqual(bin(struct.pack(">Q", 0x1234567890ABCDEF)), "1234567890ABCDEF")
 
99
        self.failUnlessEqual(bin(s), "1234567890ABCDEF")
 
100
        self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
 
101
 
 
102
        s = c_ulonglong.__ctype_le__(0x1234567890ABCDEF)
 
103
        self.failUnlessEqual(bin(struct.pack("<Q", 0x1234567890ABCDEF)), "EFCDAB9078563412")
 
104
        self.failUnlessEqual(bin(s), "EFCDAB9078563412")
 
105
        self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
 
106
 
 
107
    def test_endian_float(self):
 
108
        if sys.byteorder == "little":
 
109
            self.failUnless(c_float.__ctype_le__ is c_float)
 
110
            self.failUnless(c_float.__ctype_be__.__ctype_le__ is c_float)
 
111
        else:
 
112
            self.failUnless(c_float.__ctype_be__ is c_float)
 
113
            self.failUnless(c_float.__ctype_le__.__ctype_be__ is c_float)
 
114
        s = c_float(math.pi)
 
115
        self.failUnlessEqual(bin(struct.pack("f", math.pi)), bin(s))
 
116
        # Hm, what's the precision of a float compared to a double?
 
117
        self.failUnlessAlmostEqual(s.value, math.pi, places=6)
 
118
        s = c_float.__ctype_le__(math.pi)
 
119
        self.failUnlessAlmostEqual(s.value, math.pi, places=6)
 
120
        self.failUnlessEqual(bin(struct.pack("<f", math.pi)), bin(s))
 
121
        s = c_float.__ctype_be__(math.pi)
 
122
        self.failUnlessAlmostEqual(s.value, math.pi, places=6)
 
123
        self.failUnlessEqual(bin(struct.pack(">f", math.pi)), bin(s))
 
124
 
 
125
    def test_endian_double(self):
 
126
        if sys.byteorder == "little":
 
127
            self.failUnless(c_double.__ctype_le__ is c_double)
 
128
            self.failUnless(c_double.__ctype_be__.__ctype_le__ is c_double)
 
129
        else:
 
130
            self.failUnless(c_double.__ctype_be__ is c_double)
 
131
            self.failUnless(c_double.__ctype_le__.__ctype_be__ is c_double)
 
132
        s = c_double(math.pi)
 
133
        self.failUnlessEqual(s.value, math.pi)
 
134
        self.failUnlessEqual(bin(struct.pack("d", math.pi)), bin(s))
 
135
        s = c_double.__ctype_le__(math.pi)
 
136
        self.failUnlessEqual(s.value, math.pi)
 
137
        self.failUnlessEqual(bin(struct.pack("<d", math.pi)), bin(s))
 
138
        s = c_double.__ctype_be__(math.pi)
 
139
        self.failUnlessEqual(s.value, math.pi)
 
140
        self.failUnlessEqual(bin(struct.pack(">d", math.pi)), bin(s))
 
141
 
 
142
    def test_endian_other(self):
 
143
        self.failUnless(c_byte.__ctype_le__ is c_byte)
 
144
        self.failUnless(c_byte.__ctype_be__ is c_byte)
 
145
 
 
146
        self.failUnless(c_ubyte.__ctype_le__ is c_ubyte)
 
147
        self.failUnless(c_ubyte.__ctype_be__ is c_ubyte)
 
148
 
 
149
        self.failUnless(c_char.__ctype_le__ is c_char)
 
150
        self.failUnless(c_char.__ctype_be__ is c_char)
 
151
 
 
152
    def test_struct_fields_1(self):
 
153
        if sys.byteorder == "little":
 
154
            base = BigEndianStructure
 
155
        else:
 
156
            base = LittleEndianStructure
 
157
 
 
158
        class T(base):
 
159
            pass
 
160
        _fields_ = [("a", c_ubyte),
 
161
                    ("b", c_byte),
 
162
                    ("c", c_short),
 
163
                    ("d", c_ushort),
 
164
                    ("e", c_int),
 
165
                    ("f", c_uint),
 
166
                    ("g", c_long),
 
167
                    ("h", c_ulong),
 
168
                    ("i", c_longlong),
 
169
                    ("k", c_ulonglong),
 
170
                    ("l", c_float),
 
171
                    ("m", c_double),
 
172
                    ("n", c_char),
 
173
 
 
174
                    ("b1", c_byte, 3),
 
175
                    ("b2", c_byte, 3),
 
176
                    ("b3", c_byte, 2),
 
177
                    ("a", c_int * 3 * 3 * 3)]
 
178
        T._fields_ = _fields_
 
179
 
 
180
        # these fields do not support different byte order:
 
181
        for typ in c_wchar, c_void_p, POINTER(c_int):
 
182
            _fields_.append(("x", typ))
 
183
            class T(base):
 
184
                pass
 
185
            self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)])
 
186
 
 
187
    def test_struct_struct(self):
 
188
        # Nested structures with different byte order not (yet) supported
 
189
        if sys.byteorder == "little":
 
190
            base = BigEndianStructure
 
191
        else:
 
192
            base = LittleEndianStructure
 
193
 
 
194
        class T(Structure):
 
195
            _fields_ = [("a", c_int),
 
196
                        ("b", c_int)]
 
197
        class S(base):
 
198
            pass
 
199
        self.assertRaises(TypeError, setattr, S, "_fields_", [("s", T)])
 
200
 
 
201
    def test_struct_fields_2(self):
 
202
        # standard packing in struct uses no alignment.
 
203
        # So, we have to align using pad bytes.
 
204
        #
 
205
        # Unaligned accesses will crash Python (on those platforms that
 
206
        # don't allow it, like sparc solaris).
 
207
        if sys.byteorder == "little":
 
208
            base = BigEndianStructure
 
209
            fmt = ">bxhid"
 
210
        else:
 
211
            base = LittleEndianStructure
 
212
            fmt = "<bxhid"
 
213
 
 
214
        class S(base):
 
215
            _fields_ = [("b", c_byte),
 
216
                        ("h", c_short),
 
217
                        ("i", c_int),
 
218
                        ("d", c_double)]
 
219
 
 
220
        s1 = S(0x12, 0x1234, 0x12345678, 3.14)
 
221
        s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
 
222
        self.failUnlessEqual(bin(s1), bin(s2))
 
223
 
 
224
    def test_unaligned_nonnative_struct_fields(self):
 
225
        if sys.byteorder == "little":
 
226
            base = BigEndianStructure
 
227
            fmt = ">b h xi xd"
 
228
        else:
 
229
            base = LittleEndianStructure
 
230
            fmt = "<b h xi xd"
 
231
 
 
232
        class S(base):
 
233
            _pack_ = 1
 
234
            _fields_ = [("b", c_byte),
 
235
 
 
236
                        ("h", c_short),
 
237
 
 
238
                        ("_1", c_byte),
 
239
                        ("i", c_int),
 
240
 
 
241
                        ("_2", c_byte),
 
242
                        ("d", c_double)]
 
243
 
 
244
        s1 = S()
 
245
        s1.b = 0x12
 
246
        s1.h = 0x1234
 
247
        s1.i = 0x12345678
 
248
        s1.d = 3.14
 
249
        s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
 
250
        self.failUnlessEqual(bin(s1), bin(s2))
 
251
 
 
252
    def test_unaligned_native_struct_fields(self):
 
253
        if sys.byteorder == "little":
 
254
            fmt = "<b h xi xd"
 
255
        else:
 
256
            base = LittleEndianStructure
 
257
            fmt = ">b h xi xd"
 
258
 
 
259
        class S(Structure):
 
260
            _pack_ = 1
 
261
            _fields_ = [("b", c_byte),
 
262
 
 
263
                        ("h", c_short),
 
264
 
 
265
                        ("_1", c_byte),
 
266
                        ("i", c_int),
 
267
 
 
268
                        ("_2", c_byte),
 
269
                        ("d", c_double)]
 
270
 
 
271
        s1 = S()
 
272
        s1.b = 0x12
 
273
        s1.h = 0x1234
 
274
        s1.i = 0x12345678
 
275
        s1.d = 3.14
 
276
        s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
 
277
        self.failUnlessEqual(bin(s1), bin(s2))
 
278
 
 
279
if __name__ == "__main__":
 
280
    unittest.main()