-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathnamestruct.py
101 lines (87 loc) · 2.71 KB
/
namestruct.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#! /usr/bin/python
from array import array, ArrayType
import struct
print 'H', struct.calcsize('H')
print 'I', struct.calcsize('I')
print 'L', struct.calcsize('L')
print 'Q', struct.calcsize('Q')
assert struct.calcsize('B') == 1
assert struct.calcsize('H') == 2
assert struct.calcsize('I') == 4
assert struct.calcsize('L') in [ 4, 8 ]
assert struct.calcsize('Q') == 8
class NameStruct(object):
def __init__(self, fmt = ''):
self._fmt = fmt
self._members = []
self.__slots__ = []
def add(self, fmt, name = None, default = None):
assert name not in self.__slots__
# On 64 bit machines the meaning changes a bit
if struct.calcsize('L') == 8:
fmt = fmt.replace('L', 'I')
count = 0
for c in fmt:
if c >= '0' and c <= '9':
count = count * 10 + ord(c) - ord('0')
else:
if c == 's':
count = 0
break
self._fmt += fmt
if name:
self._members.append((name, count))
self.__slots__.append(name)
setattr(self, name, default)
def calcsize(self):
v = struct.calcsize(self._fmt)
print self.__class__.__name__, v
return v
def unpack(self, data):
l = struct.unpack(self._fmt, data)
index = 0
for name, count in self._members:
if name:
if count:
value = l[index:index+count]
index += count
else:
value = l[index]
index += 1
setattr(self, name, value)
def pack(self):
l = [ self._fmt ]
for name, count in self._members:
if name:
value = getattr(self, name)
if count:
l += value
else:
l.append(value)
else:
if count:
l += [ 0 ] * count
else:
l.append(0)
# print l, type(self)
return apply(struct.pack, l)
def items(self):
l = []
for name, count in self._members:
if name:
l.append((name, getattr(self, name)))
return l
def dump(self):
print type(self)
print self._fmt
for name, value in self.items():
if type(value) == int or type(value) == long:
value = "0x%08x" % value
else:
value = repr(value)
print "%-20s: %s" % (name, value)
def update(self, d):
for k, v in d.items():
setattr(self, k, v)
def clear(self):
self.unpack('\0' * self.calcsize())