Kaydet (Commit) d59ca8f3 authored tarafından Thomas Heller's avatar Thomas Heller

Accessing unaligned structure fields works now on all architectures.

Including unittest.
üst 6c2f9138
...@@ -2,7 +2,6 @@ import sys, unittest, struct, math ...@@ -2,7 +2,6 @@ import sys, unittest, struct, math
from binascii import hexlify from binascii import hexlify
from ctypes import * from ctypes import *
from ctypes.test import is_resource_enabled
def bin(s): def bin(s):
return hexlify(buffer(s)).upper() return hexlify(buffer(s)).upper()
...@@ -222,54 +221,60 @@ class Test(unittest.TestCase): ...@@ -222,54 +221,60 @@ class Test(unittest.TestCase):
s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14) s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
self.failUnlessEqual(bin(s1), bin(s2)) self.failUnlessEqual(bin(s1), bin(s2))
if is_resource_enabled("unaligned_access"): def test_unaligned_nonnative_struct_fields(self):
if sys.byteorder == "little":
def test_unaligned_nonnative_struct_fields(self): base = BigEndianStructure
if sys.byteorder == "little": fmt = ">b h xi xd"
base = BigEndianStructure else:
fmt = ">b h xi xd" base = LittleEndianStructure
else: fmt = "<b h xi xd"
base = LittleEndianStructure
fmt = "<b h xi xd"
class S(base): class S(base):
_pack_ = 1 _pack_ = 1
_fields_ = [("b", c_byte), _fields_ = [("b", c_byte),
("h", c_short), ("h", c_short),
("_1", c_byte), ("_1", c_byte),
("i", c_int), ("i", c_int),
("_2", c_byte), ("_2", c_byte),
("d", c_double)] ("d", c_double)]
s1 = S(0x12, 0x1234, 0, 0x12345678, 0, 3.14) s1 = S()
s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14) s1.b = 0x12
self.failUnlessEqual(bin(s1), bin(s2)) s1.h = 0x1234
s1.i = 0x12345678
s1.d = 3.14
s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
self.failUnlessEqual(bin(s1), bin(s2))
def test_unaligned_native_struct_fields(self): def test_unaligned_native_struct_fields(self):
if sys.byteorder == "little": if sys.byteorder == "little":
fmt = "<b h xi xd" fmt = "<b h xi xd"
else: else:
base = LittleEndianStructure base = LittleEndianStructure
fmt = ">b h xi xd" fmt = ">b h xi xd"
class S(Structure): class S(Structure):
_pack_ = 1 _pack_ = 1
_fields_ = [("b", c_byte), _fields_ = [("b", c_byte),
("h", c_short), ("h", c_short),
("_1", c_byte), ("_1", c_byte),
("i", c_int), ("i", c_int),
("_2", c_byte), ("_2", c_byte),
("d", c_double)] ("d", c_double)]
s1 = S(0x12, 0x1234, 0, 0x12345678, 0, 3.14) s1 = S()
s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14) s1.b = 0x12
self.failUnlessEqual(bin(s1), bin(s2)) s1.h = 0x1234
s1.i = 0x12345678
s1.d = 3.14
s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
self.failUnlessEqual(bin(s1), bin(s2))
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
import sys, unittest
from ctypes import *
structures = []
byteswapped_structures = []
if sys.byteorder == "little":
SwappedStructure = BigEndianStructure
else:
SwappedStructure = LittleEndianStructure
for typ in [c_short, c_int, c_long, c_longlong,
c_float, c_double,
c_ushort, c_uint, c_ulong, c_ulonglong]:
class X(Structure):
_pack_ = 1
_fields_ = [("pad", c_byte),
("value", typ)]
class Y(SwappedStructure):
_pack_ = 1
_fields_ = [("pad", c_byte),
("value", typ)]
structures.append(X)
byteswapped_structures.append(Y)
class TestStructures(unittest.TestCase):
def test_native(self):
for typ in structures:
## print typ.value
self.failUnlessEqual(typ.value.offset, 1)
o = typ()
o.value = 4
self.failUnlessEqual(o.value, 4)
def test_swapped(self):
for typ in byteswapped_structures:
## print >> sys.stderr, typ.value
self.failUnlessEqual(typ.value.offset, 1)
o = typ()
o.value = 4
self.failUnlessEqual(o.value, 4)
if __name__ == '__main__':
unittest.main()
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment