Issue #7042: Use a better mechanism for testing timers in test_signal.
[python.git] / Demo / rpc / xdr.py
blob041d51aa2862b0f63b84ac47a8056a20e98ad679
1 # Implement (a subset of) Sun XDR -- RFC1014.
4 try:
5 import struct
6 except ImportError:
7 struct = None
10 Long = type(0L)
13 class Packer:
15 def __init__(self):
16 self.reset()
18 def reset(self):
19 self.buf = ''
21 def get_buf(self):
22 return self.buf
24 def pack_uint(self, x):
25 self.buf = self.buf + \
26 (chr(int(x>>24 & 0xff)) + chr(int(x>>16 & 0xff)) + \
27 chr(int(x>>8 & 0xff)) + chr(int(x & 0xff)))
28 if struct and struct.pack('l', 1) == '\0\0\0\1':
29 def pack_uint(self, x):
30 if type(x) == Long:
31 x = int((x + 0x80000000L) % 0x100000000L \
32 - 0x80000000L)
33 self.buf = self.buf + struct.pack('l', x)
35 pack_int = pack_uint
37 pack_enum = pack_int
39 def pack_bool(self, x):
40 if x: self.buf = self.buf + '\0\0\0\1'
41 else: self.buf = self.buf + '\0\0\0\0'
43 def pack_uhyper(self, x):
44 self.pack_uint(int(x>>32 & 0xffffffff))
45 self.pack_uint(int(x & 0xffffffff))
47 pack_hyper = pack_uhyper
49 def pack_float(self, x):
50 # XXX
51 self.buf = self.buf + struct.pack('f', x)
53 def pack_double(self, x):
54 # XXX
55 self.buf = self.buf + struct.pack('d', x)
57 def pack_fstring(self, n, s):
58 if n < 0:
59 raise ValueError, 'fstring size must be nonnegative'
60 n = ((n + 3)//4)*4
61 data = s[:n]
62 data = data + (n - len(data)) * '\0'
63 self.buf = self.buf + data
65 pack_fopaque = pack_fstring
67 def pack_string(self, s):
68 n = len(s)
69 self.pack_uint(n)
70 self.pack_fstring(n, s)
72 pack_opaque = pack_string
74 def pack_list(self, list, pack_item):
75 for item in list:
76 self.pack_uint(1)
77 pack_item(item)
78 self.pack_uint(0)
80 def pack_farray(self, n, list, pack_item):
81 if len(list) <> n:
82 raise ValueError, 'wrong array size'
83 for item in list:
84 pack_item(item)
86 def pack_array(self, list, pack_item):
87 n = len(list)
88 self.pack_uint(n)
89 self.pack_farray(n, list, pack_item)
92 class Unpacker:
94 def __init__(self, data):
95 self.reset(data)
97 def reset(self, data):
98 self.buf = data
99 self.pos = 0
101 def done(self):
102 if self.pos < len(self.buf):
103 raise RuntimeError, 'unextracted data remains'
105 def unpack_uint(self):
106 i = self.pos
107 self.pos = j = i+4
108 data = self.buf[i:j]
109 if len(data) < 4:
110 raise EOFError
111 x = long(ord(data[0]))<<24 | ord(data[1])<<16 | \
112 ord(data[2])<<8 | ord(data[3])
113 # Return a Python long only if the value is not representable
114 # as a nonnegative Python int
115 if x < 0x80000000L: x = int(x)
116 return x
117 if struct and struct.unpack('l', '\0\0\0\1') == 1:
118 def unpack_uint(self):
119 i = self.pos
120 self.pos = j = i+4
121 data = self.buf[i:j]
122 if len(data) < 4:
123 raise EOFError
124 return struct.unpack('l', data)
126 def unpack_int(self):
127 x = self.unpack_uint()
128 if x >= 0x80000000L: x = x - 0x100000000L
129 return int(x)
131 unpack_enum = unpack_int
133 unpack_bool = unpack_int
135 def unpack_uhyper(self):
136 hi = self.unpack_uint()
137 lo = self.unpack_uint()
138 return long(hi)<<32 | lo
140 def unpack_hyper(self):
141 x = self.unpack_uhyper()
142 if x >= 0x8000000000000000L: x = x - 0x10000000000000000L
143 return x
145 def unpack_float(self):
146 # XXX
147 i = self.pos
148 self.pos = j = i+4
149 data = self.buf[i:j]
150 if len(data) < 4:
151 raise EOFError
152 return struct.unpack('f', data)[0]
154 def unpack_double(self):
155 # XXX
156 i = self.pos
157 self.pos = j = i+8
158 data = self.buf[i:j]
159 if len(data) < 8:
160 raise EOFError
161 return struct.unpack('d', data)[0]
163 def unpack_fstring(self, n):
164 if n < 0:
165 raise ValueError, 'fstring size must be nonnegative'
166 i = self.pos
167 j = i + (n+3)//4*4
168 if j > len(self.buf):
169 raise EOFError
170 self.pos = j
171 return self.buf[i:i+n]
173 unpack_fopaque = unpack_fstring
175 def unpack_string(self):
176 n = self.unpack_uint()
177 return self.unpack_fstring(n)
179 unpack_opaque = unpack_string
181 def unpack_list(self, unpack_item):
182 list = []
183 while 1:
184 x = self.unpack_uint()
185 if x == 0: break
186 if x <> 1:
187 raise RuntimeError, '0 or 1 expected, got %r' % (x, )
188 item = unpack_item()
189 list.append(item)
190 return list
192 def unpack_farray(self, n, unpack_item):
193 list = []
194 for i in range(n):
195 list.append(unpack_item())
196 return list
198 def unpack_array(self, unpack_item):
199 n = self.unpack_uint()
200 return self.unpack_farray(n, unpack_item)