1
"""Implements (a subset of) Sun XDR -- eXternal Data Representation.
9
from cStringIO import StringIO as _StringIO
11
from StringIO import StringIO as _StringIO
13
__all__ = ["Error", "Packer", "Unpacker", "ConversionError"]
16
class Error(Exception):
17
"""Exception class for this module. Use:
19
except xdrlib.Error, var:
20
# var has the Error instance for the exception
23
msg -- contains the message
26
def __init__(self, msg):
34
class ConversionError(Error):
40
"""Pack various data representations into a buffer."""
46
self.__buf = _StringIO()
49
return self.__buf.getvalue()
50
# backwards compatibility
53
def pack_uint(self, x):
54
self.__buf.write(struct.pack('>L', x))
59
def pack_bool(self, x):
60
if x: self.__buf.write('\0\0\0\1')
61
else: self.__buf.write('\0\0\0\0')
63
def pack_uhyper(self, x):
64
self.pack_uint(x>>32 & 0xffffffffL)
65
self.pack_uint(x & 0xffffffffL)
67
pack_hyper = pack_uhyper
69
def pack_float(self, x):
70
try: self.__buf.write(struct.pack('>f', x))
71
except struct.error, msg:
72
raise ConversionError, msg
74
def pack_double(self, x):
75
try: self.__buf.write(struct.pack('>d', x))
76
except struct.error, msg:
77
raise ConversionError, msg
79
def pack_fstring(self, n, s):
81
raise ValueError, 'fstring size must be nonnegative'
84
data = data + (n - len(data)) * '\0'
85
self.__buf.write(data)
87
pack_fopaque = pack_fstring
89
def pack_string(self, s):
92
self.pack_fstring(n, s)
94
pack_opaque = pack_string
95
pack_bytes = pack_string
97
def pack_list(self, list, pack_item):
103
def pack_farray(self, n, list, pack_item):
105
raise ValueError, 'wrong array size'
109
def pack_array(self, list, pack_item):
112
self.pack_farray(n, list, pack_item)
117
"""Unpacks various data representations from the given buffer."""
119
def __init__(self, data):
122
def reset(self, data):
126
def get_position(self):
129
def set_position(self, position):
130
self.__pos = position
132
def get_buffer(self):
136
if self.__pos < len(self.__buf):
137
raise Error('unextracted data remains')
139
def unpack_uint(self):
142
data = self.__buf[i:j]
145
x = struct.unpack('>L', data)[0]
148
except OverflowError:
151
def unpack_int(self):
154
data = self.__buf[i:j]
157
return struct.unpack('>l', data)[0]
159
unpack_enum = unpack_int
161
def unpack_bool(self):
162
return bool(self.unpack_int())
164
def unpack_uhyper(self):
165
hi = self.unpack_uint()
166
lo = self.unpack_uint()
167
return long(hi)<<32 | lo
169
def unpack_hyper(self):
170
x = self.unpack_uhyper()
171
if x >= 0x8000000000000000L:
172
x = x - 0x10000000000000000L
175
def unpack_float(self):
178
data = self.__buf[i:j]
181
return struct.unpack('>f', data)[0]
183
def unpack_double(self):
186
data = self.__buf[i:j]
189
return struct.unpack('>d', data)[0]
191
def unpack_fstring(self, n):
193
raise ValueError, 'fstring size must be nonnegative'
196
if j > len(self.__buf):
199
return self.__buf[i:i+n]
201
unpack_fopaque = unpack_fstring
203
def unpack_string(self):
204
n = self.unpack_uint()
205
return self.unpack_fstring(n)
207
unpack_opaque = unpack_string
208
unpack_bytes = unpack_string
210
def unpack_list(self, unpack_item):
213
x = self.unpack_uint()
216
raise ConversionError, '0 or 1 expected, got %r' % (x,)
221
def unpack_farray(self, n, unpack_item):
224
list.append(unpack_item())
227
def unpack_array(self, unpack_item):
228
n = self.unpack_uint()
229
return self.unpack_farray(n, unpack_item)