Skip to content

Commit fe0db2f

Browse files
committed
more TU
1 parent 631eb36 commit fe0db2f

File tree

2 files changed

+63
-11
lines changed

2 files changed

+63
-11
lines changed

haystack/utils.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ def getaddress(obj):
115115

116116
def container_of(memberaddr, typ, membername):
117117
"""
118+
From a pointer to a member, returns the parent struct.
118119
Returns the instance of typ(), in which the member "membername' is really.
120+
Useful in some Kernel linked list which used members as prec,next pointers.
119121
120122
:param memberadd: the address of membername.
121123
:param typ: the type of the containing structure.
@@ -134,8 +136,6 @@ def offsetof(typ, membername):
134136
:param typ: the structure type.
135137
:param membername: the membername in that structure.
136138
"""
137-
#T=typ()
138-
#return ctypes.addressof( getattr(T,membername) ) - ctypes.addressof(T)
139139
return getattr(typ, membername).offset
140140

141141

@@ -194,7 +194,8 @@ def array2bytes(array):
194194
195195
This is a bad example of introspection.
196196
"""
197-
if not isBasicTypeArray(array):
197+
import ctypes
198+
if not ctypes.is_array_of_basic_instance(array):
198199
return b'NOT-AN-BasicType-ARRAY'
199200
# BEURK
200201
#log.info(type(array).__name__.split('_'))
@@ -267,7 +268,7 @@ def isCTypes(obj):
267268

268269
@deprecated
269270
def isBasicTypeArray(obj):
270-
return ctypes.is_array_to_basic_instance(obj)
271+
return ctypes.is_array_of_basic_instance(obj)
271272

272273
@deprecated
273274
def isBasicType(objtype):

test/haystack/test_utils.py

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@
1313
# init ctypes with a controlled type size
1414
from haystack import model
1515
from haystack import utils
16+
from haystack import types
1617

1718
import unittest
1819

1920
class 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

Comments
 (0)