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
160 unpack_bool
= unpack_int
162 def unpack_uhyper(self
):
163 hi
= self
.unpack_uint()
164 lo
= self
.unpack_uint()
165 return long(hi
)<<32 | lo
167 def unpack_hyper(self
):
168 x
= self
.unpack_uhyper()
169 if x
>= 0x8000000000000000L
:
170 x
= x
- 0x10000000000000000L
173 def unpack_float(self
):
176 data
= self
.__buf
[i
:j
]
179 return struct
.unpack('>f', data
)[0]
181 def unpack_double(self
):
184 data
= self
.__buf
[i
:j
]
187 return struct
.unpack('>d', data
)[0]
189 def unpack_fstring(self
, n
):
191 raise ValueError, 'fstring size must be nonnegative'
194 if j
> len(self
.__buf
):
197 return self
.__buf
[i
:i
+n
]
199 unpack_fopaque
= unpack_fstring
201 def unpack_string(self
):
202 n
= self
.unpack_uint()
203 return self
.unpack_fstring(n
)
205 unpack_opaque
= unpack_string
206 unpack_bytes
= unpack_string
208 def unpack_list(self
, unpack_item
):
211 x
= self
.unpack_uint()
214 raise ConversionError
, '0 or 1 expected, got ' + `x`
219 def unpack_farray(self
, n
, unpack_item
):
222 list.append(unpack_item())
225 def unpack_array(self
, unpack_item
):
226 n
= self
.unpack_uint()
227 return self
.unpack_farray(n
, unpack_item
)
235 (p
.pack_bool
, (None,)),
236 (p
.pack_bool
, ('hello',)),
237 (p
.pack_uhyper
, (45L,)),
238 (p
.pack_float
, (1.9,)),
239 (p
.pack_double
, (1.9,)),
240 (p
.pack_string
, ('hello world',)),
241 (p
.pack_list
, (range(5), p
.pack_uint
)),
242 (p
.pack_array
, (['what', 'is', 'hapnin', 'doctor'], p
.pack_string
)),
244 succeedlist
= [1] * len(packtest
)
246 for method
, args
in packtest
:
247 print 'pack test', count
,
251 except ConversionError
, var
:
252 print 'ConversionError:', var
.msg
253 succeedlist
[count
] = 0
255 data
= p
.get_buffer()
259 (up
.unpack_uint
, (), lambda x
: x
== 9),
260 (up
.unpack_bool
, (), lambda x
: not x
),
261 (up
.unpack_bool
, (), lambda x
: x
),
262 (up
.unpack_uhyper
, (), lambda x
: x
== 45L),
263 (up
.unpack_float
, (), lambda x
: 1.89 < x
< 1.91),
264 (up
.unpack_double
, (), lambda x
: 1.89 < x
< 1.91),
265 (up
.unpack_string
, (), lambda x
: x
== 'hello world'),
266 (up
.unpack_list
, (up
.unpack_uint
,), lambda x
: x
== range(5)),
267 (up
.unpack_array
, (up
.unpack_string
,),
268 lambda x
: x
== ['what', 'is', 'hapnin', 'doctor']),
271 for method
, args
, pred
in unpacktest
:
272 print 'unpack test', count
,
274 if succeedlist
[count
]:
275 x
= apply(method
, args
)
276 print pred(x
) and 'succeeded' or 'failed', ':', x
279 except ConversionError
, var
:
280 print 'ConversionError:', var
.msg
284 if __name__
== '__main__':