1 """Implements (a subset of) Sun XDR -- eXternal Data Representation.
10 __all__
= ["Error", "Packer", "Unpacker", "ConversionError"]
13 class Error(Exception):
14 """Exception class for this module. Use:
16 except xdrlib.Error, var:
17 # var has the Error instance for the exception
20 msg -- contains the message
23 def __init__(self
, msg
):
31 class ConversionError(Error
):
37 """Pack various data representations into a buffer."""
43 self
.__buf
= BytesIO()
46 return self
.__buf
.getvalue()
47 # backwards compatibility
50 def pack_uint(self
, x
):
51 self
.__buf
.write(struct
.pack('>L', x
))
56 def pack_bool(self
, x
):
57 if x
: self
.__buf
.write(b
'\0\0\0\1')
58 else: self
.__buf
.write(b
'\0\0\0\0')
60 def pack_uhyper(self
, x
):
61 self
.pack_uint(x
>>32 & 0xffffffff)
62 self
.pack_uint(x
& 0xffffffff)
64 pack_hyper
= pack_uhyper
66 def pack_float(self
, x
):
67 try: self
.__buf
.write(struct
.pack('>f', x
))
68 except struct
.error
as msg
:
69 raise ConversionError(msg
)
71 def pack_double(self
, x
):
72 try: self
.__buf
.write(struct
.pack('>d', x
))
73 except struct
.error
as msg
:
74 raise ConversionError(msg
)
76 def pack_fstring(self
, n
, s
):
78 raise ValueError('fstring size must be nonnegative')
81 data
= data
+ (n
- len(data
)) * b
'\0'
82 self
.__buf
.write(data
)
84 pack_fopaque
= pack_fstring
86 def pack_string(self
, s
):
89 self
.pack_fstring(n
, s
)
91 pack_opaque
= pack_string
92 pack_bytes
= pack_string
94 def pack_list(self
, list, pack_item
):
100 def pack_farray(self
, n
, list, pack_item
):
102 raise ValueError('wrong array size')
106 def pack_array(self
, list, pack_item
):
109 self
.pack_farray(n
, list, pack_item
)
114 """Unpacks various data representations from the given buffer."""
116 def __init__(self
, data
):
119 def reset(self
, data
):
123 def get_position(self
):
126 def set_position(self
, position
):
127 self
.__pos
= position
129 def get_buffer(self
):
133 if self
.__pos
< len(self
.__buf
):
134 raise Error('unextracted data remains')
136 def unpack_uint(self
):
139 data
= self
.__buf
[i
:j
]
142 x
= struct
.unpack('>L', data
)[0]
145 except OverflowError:
148 def unpack_int(self
):
151 data
= self
.__buf
[i
:j
]
154 return struct
.unpack('>l', data
)[0]
156 unpack_enum
= unpack_int
158 def unpack_bool(self
):
159 return bool(self
.unpack_int())
161 def unpack_uhyper(self
):
162 hi
= self
.unpack_uint()
163 lo
= self
.unpack_uint()
164 return int(hi
)<<32 | lo
166 def unpack_hyper(self
):
167 x
= self
.unpack_uhyper()
168 if x
>= 0x8000000000000000:
169 x
= x
- 0x10000000000000000
172 def unpack_float(self
):
175 data
= self
.__buf
[i
:j
]
178 return struct
.unpack('>f', data
)[0]
180 def unpack_double(self
):
183 data
= self
.__buf
[i
:j
]
186 return struct
.unpack('>d', data
)[0]
188 def unpack_fstring(self
, n
):
190 raise ValueError('fstring size must be nonnegative')
193 if j
> len(self
.__buf
):
196 return self
.__buf
[i
:i
+n
]
198 unpack_fopaque
= unpack_fstring
200 def unpack_string(self
):
201 n
= self
.unpack_uint()
202 return self
.unpack_fstring(n
)
204 unpack_opaque
= unpack_string
205 unpack_bytes
= unpack_string
207 def unpack_list(self
, unpack_item
):
210 x
= self
.unpack_uint()
213 raise ConversionError('0 or 1 expected, got %r' % (x
,))
218 def unpack_farray(self
, n
, unpack_item
):
221 list.append(unpack_item())
224 def unpack_array(self
, unpack_item
):
225 n
= self
.unpack_uint()
226 return self
.unpack_farray(n
, unpack_item
)