1313# init ctypes with a controlled type size
1414from haystack import model
1515from haystack import utils
16+ from haystack import types
1617
1718import unittest
1819
1920class TestHelpers (unittest .TestCase ):
2021 """Tests helpers functions."""
2122
2223 def test_formatAddress (self ):
23- from haystack import types
2424 types .reload_ctypes (8 ,8 ,16 )
2525 x = utils .formatAddress (0x12345678 )
2626 self .assertEquals ('0x0000000012345678' , x )
@@ -30,7 +30,6 @@ def test_formatAddress(self):
3030 self .assertEquals ('0x12345678' , x )
3131
3232 def test_unpackWord (self ):
33- from haystack import types
3433 # 64b
3534 types .reload_ctypes (8 ,8 ,16 )
3635 one = b'\x01 ' + 7 * b'\x00 '
@@ -64,7 +63,6 @@ def test_is_address_local(self):
6463
6564 def test_getaddress (self ):
6665 """tests getaddress on host ctypes POINTER and haystack POINTER"""
67- from haystack import types
6866 ctypes = types .reload_ctypes (8 ,8 ,16 )
6967 class X (ctypes .Structure ):
7068 _pack_ = True
@@ -109,12 +107,65 @@ class Y(ctypes.Structure):
109107
110108 pass
111109
112- def test_container_of (self ):
113- #utils.container_of(memberaddr, typ, membername):
114- pass
115110 def test_offsetof (self ):
116- #utils.offsetof(typ, membername):
111+ """returns the offset of a member fields in a record"""
112+ ctypes = types .reload_ctypes (4 ,4 ,8 )
113+ class Y (ctypes .Structure ):
114+ _pack_ = True
115+ _fields_ = [('a' ,ctypes .c_long ),
116+ ('p' ,ctypes .POINTER (ctypes .c_int )),
117+ ('b' , ctypes .c_ubyte )]
118+ o = utils .offsetof (Y , 'b' )
119+ self .assertEquals ( o , 8 )
120+
121+ ctypes = types .reload_ctypes (8 ,8 ,16 )
122+ class X (ctypes .Structure ):
123+ _pack_ = True
124+ _fields_ = [('a' ,ctypes .c_long ),
125+ ('p' ,ctypes .POINTER (ctypes .c_int )),
126+ ('b' , ctypes .c_ubyte )]
127+ o = utils .offsetof (X , 'b' )
128+ self .assertEquals ( o , 16 )
129+
130+ class X2 (ctypes .Union ):
131+ _pack_ = True
132+ _fields_ = [('a' ,ctypes .c_long ),
133+ ('p' ,ctypes .POINTER (ctypes .c_int )),
134+ ('b' , ctypes .c_ubyte )]
135+ o = utils .offsetof (X2 , 'b' )
136+ self .assertEquals ( o , 0 )
137+ pass
138+
139+ def test_container_of (self ):
140+ """From a pointer to a member, returns the parent struct"""
141+ # depends on offsetof
142+ ctypes = types .reload_ctypes (8 ,8 ,16 )
143+ class X (ctypes .Structure ):
144+ _pack_ = True
145+ _fields_ = [('a' ,ctypes .c_long ),
146+ ('p' ,ctypes .POINTER (ctypes .c_int )),
147+ ('b' , ctypes .c_ubyte )]
148+ x = X ()
149+ x .a = 1
150+ x .b = 2
151+ addr_b = ctypes .addressof (x ) + 16 # a + p
152+ o = utils .container_of (addr_b , X , 'b' )
153+ self .assertEquals ( ctypes .addressof (o ), ctypes .addressof (x ))
154+
155+ ctypes = types .reload_ctypes (4 ,4 ,8 )
156+ class Y (ctypes .Structure ):
157+ _pack_ = True
158+ _fields_ = [('a' ,ctypes .c_long ),
159+ ('p' ,ctypes .POINTER (ctypes .c_int )),
160+ ('b' , ctypes .c_ubyte )]
161+ y = Y ()
162+ y .a = 1
163+ y .b = 2
164+ addr_b = ctypes .addressof (y ) + 8 # a + p
165+ o = utils .container_of (addr_b , Y , 'b' )
166+ self .assertEquals ( ctypes .addressof (o ), ctypes .addressof (y ))
117167 pass
168+
118169 def test_array2bytes_ (self ):
119170 #utils.array2bytes_(array, typ):
120171 pass
0 commit comments