1992-12-14 19:25:04 -04:00
|
|
|
# Implement (a subset of) Sun XDR -- RFC1014.
|
|
|
|
|
|
|
|
|
1992-12-17 13:32:24 -04:00
|
|
|
try:
|
2004-07-18 02:56:09 -03:00
|
|
|
import struct
|
1992-12-17 13:32:24 -04:00
|
|
|
except ImportError:
|
2004-07-18 02:56:09 -03:00
|
|
|
struct = None
|
1992-12-14 19:25:04 -04:00
|
|
|
|
|
|
|
|
2007-07-17 17:59:35 -03:00
|
|
|
Long = type(0)
|
1992-12-15 17:43:59 -04:00
|
|
|
|
|
|
|
|
1992-12-14 19:25:04 -04:00
|
|
|
class Packer:
|
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
def __init__(self):
|
|
|
|
self.reset()
|
1992-12-14 19:25:04 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
def reset(self):
|
|
|
|
self.buf = ''
|
1992-12-14 19:25:04 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
def get_buf(self):
|
|
|
|
return self.buf
|
1992-12-14 19:25:04 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
def pack_uint(self, x):
|
|
|
|
self.buf = self.buf + \
|
|
|
|
(chr(int(x>>24 & 0xff)) + chr(int(x>>16 & 0xff)) + \
|
|
|
|
chr(int(x>>8 & 0xff)) + chr(int(x & 0xff)))
|
|
|
|
if struct and struct.pack('l', 1) == '\0\0\0\1':
|
|
|
|
def pack_uint(self, x):
|
|
|
|
if type(x) == Long:
|
2007-07-17 17:59:35 -03:00
|
|
|
x = int((x + 0x80000000) % 0x100000000 \
|
|
|
|
- 0x80000000)
|
2004-07-18 02:56:09 -03:00
|
|
|
self.buf = self.buf + struct.pack('l', x)
|
1992-12-14 19:25:04 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
pack_int = pack_uint
|
1992-12-14 19:25:04 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
pack_enum = pack_int
|
1992-12-14 19:25:04 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
def pack_bool(self, x):
|
|
|
|
if x: self.buf = self.buf + '\0\0\0\1'
|
|
|
|
else: self.buf = self.buf + '\0\0\0\0'
|
1992-12-14 19:25:04 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
def pack_uhyper(self, x):
|
|
|
|
self.pack_uint(int(x>>32 & 0xffffffff))
|
|
|
|
self.pack_uint(int(x & 0xffffffff))
|
1992-12-14 19:25:04 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
pack_hyper = pack_uhyper
|
1992-12-14 19:25:04 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
def pack_float(self, x):
|
|
|
|
# XXX
|
|
|
|
self.buf = self.buf + struct.pack('f', x)
|
1993-12-17 10:32:26 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
def pack_double(self, x):
|
|
|
|
# XXX
|
|
|
|
self.buf = self.buf + struct.pack('d', x)
|
1993-12-17 10:32:26 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
def pack_fstring(self, n, s):
|
|
|
|
if n < 0:
|
2007-07-17 17:59:35 -03:00
|
|
|
raise ValueError('fstring size must be nonnegative')
|
Merged revisions 66394,66404,66412,66414,66424-66436 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r66394 | benjamin.peterson | 2008-09-11 17:04:02 -0500 (Thu, 11 Sep 2008) | 1 line
fix typo
........
r66404 | gerhard.haering | 2008-09-12 08:54:06 -0500 (Fri, 12 Sep 2008) | 2 lines
sqlite3 module: Mark iterdump() method as "Non-standard" like all the other methods not found in DB-API.
........
r66412 | gerhard.haering | 2008-09-12 13:58:57 -0500 (Fri, 12 Sep 2008) | 2 lines
Fixes issue #3103. In the sqlite3 module, made one more function static. All renaming public symbos now have the pysqlite prefix to avoid name clashes. This at least once created problems where the same symbol name appeared somewhere in Apache and the sqlite3 module was used from mod_python.
........
r66414 | gerhard.haering | 2008-09-12 17:33:22 -0500 (Fri, 12 Sep 2008) | 2 lines
Issue #3846: Release GIL during calls to sqlite3_prepare. This improves concurrent access to the same database file from multiple threads/processes.
........
r66424 | andrew.kuchling | 2008-09-12 20:22:08 -0500 (Fri, 12 Sep 2008) | 1 line
#687648 from Robert Schuppenies: use classic division. (RM Barry gave permission to update the demos.)
........
r66425 | andrew.kuchling | 2008-09-12 20:27:33 -0500 (Fri, 12 Sep 2008) | 1 line
#687648 from Robert Schuppenies: use classic division. From me: don't use string exception; flush stdout after printing
........
r66426 | andrew.kuchling | 2008-09-12 20:34:41 -0500 (Fri, 12 Sep 2008) | 1 line
#687648 from Robert Schuppenies: use classic division. From me: don't use string exception; add __main__ section
........
r66427 | andrew.kuchling | 2008-09-12 20:42:55 -0500 (Fri, 12 Sep 2008) | 1 line
#687648 from Robert Schuppenies: use classic division. From me: remove two stray semicolons
........
r66428 | andrew.kuchling | 2008-09-12 20:43:28 -0500 (Fri, 12 Sep 2008) | 1 line
#687648 from Robert Schuppenies: use classic division.
........
r66429 | andrew.kuchling | 2008-09-12 20:47:02 -0500 (Fri, 12 Sep 2008) | 1 line
Remove semicolon
........
r66430 | andrew.kuchling | 2008-09-12 20:48:36 -0500 (Fri, 12 Sep 2008) | 1 line
Subclass exception
........
r66431 | andrew.kuchling | 2008-09-12 20:56:56 -0500 (Fri, 12 Sep 2008) | 1 line
Fix SyntaxError
........
r66432 | andrew.kuchling | 2008-09-12 20:57:25 -0500 (Fri, 12 Sep 2008) | 1 line
Update uses of string exceptions
........
r66433 | andrew.kuchling | 2008-09-12 21:08:30 -0500 (Fri, 12 Sep 2008) | 1 line
Use title case
........
r66434 | andrew.kuchling | 2008-09-12 21:09:15 -0500 (Fri, 12 Sep 2008) | 1 line
Remove extra 'the'; the following title includes it
........
r66435 | andrew.kuchling | 2008-09-12 21:11:51 -0500 (Fri, 12 Sep 2008) | 1 line
#3288: Document as_integer_ratio
........
r66436 | andrew.kuchling | 2008-09-12 21:14:15 -0500 (Fri, 12 Sep 2008) | 1 line
Use title case
........
2008-09-13 12:58:53 -03:00
|
|
|
n = ((n + 3)//4)*4
|
2004-07-18 02:56:09 -03:00
|
|
|
data = s[:n]
|
|
|
|
data = data + (n - len(data)) * '\0'
|
|
|
|
self.buf = self.buf + data
|
1992-12-14 19:25:04 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
pack_fopaque = pack_fstring
|
1992-12-14 19:25:04 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
def pack_string(self, s):
|
|
|
|
n = len(s)
|
|
|
|
self.pack_uint(n)
|
|
|
|
self.pack_fstring(n, s)
|
1992-12-14 19:25:04 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
pack_opaque = pack_string
|
1992-12-14 19:25:04 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
def pack_list(self, list, pack_item):
|
|
|
|
for item in list:
|
|
|
|
self.pack_uint(1)
|
|
|
|
pack_item(item)
|
|
|
|
self.pack_uint(0)
|
1992-12-14 19:25:04 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
def pack_farray(self, n, list, pack_item):
|
2006-08-29 01:39:12 -03:00
|
|
|
if len(list) != n:
|
2007-07-17 17:59:35 -03:00
|
|
|
raise ValueError('wrong array size')
|
2004-07-18 02:56:09 -03:00
|
|
|
for item in list:
|
|
|
|
pack_item(item)
|
1992-12-21 10:33:18 -04:00
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
def pack_array(self, list, pack_item):
|
|
|
|
n = len(list)
|
|
|
|
self.pack_uint(n)
|
|
|
|
self.pack_farray(n, list, pack_item)
|
1992-12-21 10:33:18 -04:00
|
|
|
|
1992-12-14 19:25:04 -04:00
|
|
|
|
|
|
|
class Unpacker:
|
|
|
|
|
2004-07-18 02:56:09 -03:00
|
|
|
def __init__(self, data):
|
|
|
|
self.reset(data)
|
|
|
|
|
|
|
|
def reset(self, data):
|
|
|
|
self.buf = data
|
|
|
|
self.pos = 0
|
|
|
|
|
|
|
|
def done(self):
|
|
|
|
if self.pos < len(self.buf):
|
2007-07-17 17:59:35 -03:00
|
|
|
raise RuntimeError('unextracted data remains')
|
2004-07-18 02:56:09 -03:00
|
|
|
|
|
|
|
def unpack_uint(self):
|
|
|
|
i = self.pos
|
|
|
|
self.pos = j = i+4
|
|
|
|
data = self.buf[i:j]
|
|
|
|
if len(data) < 4:
|
|
|
|
raise EOFError
|
2007-07-17 17:59:35 -03:00
|
|
|
x = int(ord(data[0]))<<24 | ord(data[1])<<16 | \
|
2004-07-18 02:56:09 -03:00
|
|
|
ord(data[2])<<8 | ord(data[3])
|
|
|
|
# Return a Python long only if the value is not representable
|
|
|
|
# as a nonnegative Python int
|
2007-07-17 17:59:35 -03:00
|
|
|
if x < 0x80000000: x = int(x)
|
2004-07-18 02:56:09 -03:00
|
|
|
return x
|
|
|
|
if struct and struct.unpack('l', '\0\0\0\1') == 1:
|
|
|
|
def unpack_uint(self):
|
|
|
|
i = self.pos
|
|
|
|
self.pos = j = i+4
|
|
|
|
data = self.buf[i:j]
|
|
|
|
if len(data) < 4:
|
|
|
|
raise EOFError
|
|
|
|
return struct.unpack('l', data)
|
|
|
|
|
|
|
|
def unpack_int(self):
|
|
|
|
x = self.unpack_uint()
|
2007-07-17 17:59:35 -03:00
|
|
|
if x >= 0x80000000: x = x - 0x100000000
|
2004-07-18 02:56:09 -03:00
|
|
|
return int(x)
|
|
|
|
|
|
|
|
unpack_enum = unpack_int
|
|
|
|
|
|
|
|
unpack_bool = unpack_int
|
|
|
|
|
|
|
|
def unpack_uhyper(self):
|
|
|
|
hi = self.unpack_uint()
|
|
|
|
lo = self.unpack_uint()
|
2007-07-17 17:59:35 -03:00
|
|
|
return int(hi)<<32 | lo
|
2004-07-18 02:56:09 -03:00
|
|
|
|
|
|
|
def unpack_hyper(self):
|
|
|
|
x = self.unpack_uhyper()
|
2007-07-17 17:59:35 -03:00
|
|
|
if x >= 0x8000000000000000: x = x - 0x10000000000000000
|
2004-07-18 02:56:09 -03:00
|
|
|
return x
|
|
|
|
|
|
|
|
def unpack_float(self):
|
|
|
|
# XXX
|
|
|
|
i = self.pos
|
|
|
|
self.pos = j = i+4
|
|
|
|
data = self.buf[i:j]
|
|
|
|
if len(data) < 4:
|
|
|
|
raise EOFError
|
|
|
|
return struct.unpack('f', data)[0]
|
|
|
|
|
|
|
|
def unpack_double(self):
|
|
|
|
# XXX
|
|
|
|
i = self.pos
|
|
|
|
self.pos = j = i+8
|
|
|
|
data = self.buf[i:j]
|
|
|
|
if len(data) < 8:
|
|
|
|
raise EOFError
|
|
|
|
return struct.unpack('d', data)[0]
|
|
|
|
|
|
|
|
def unpack_fstring(self, n):
|
|
|
|
if n < 0:
|
2007-07-17 17:59:35 -03:00
|
|
|
raise ValueError('fstring size must be nonnegative')
|
2004-07-18 02:56:09 -03:00
|
|
|
i = self.pos
|
Merged revisions 66394,66404,66412,66414,66424-66436 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r66394 | benjamin.peterson | 2008-09-11 17:04:02 -0500 (Thu, 11 Sep 2008) | 1 line
fix typo
........
r66404 | gerhard.haering | 2008-09-12 08:54:06 -0500 (Fri, 12 Sep 2008) | 2 lines
sqlite3 module: Mark iterdump() method as "Non-standard" like all the other methods not found in DB-API.
........
r66412 | gerhard.haering | 2008-09-12 13:58:57 -0500 (Fri, 12 Sep 2008) | 2 lines
Fixes issue #3103. In the sqlite3 module, made one more function static. All renaming public symbos now have the pysqlite prefix to avoid name clashes. This at least once created problems where the same symbol name appeared somewhere in Apache and the sqlite3 module was used from mod_python.
........
r66414 | gerhard.haering | 2008-09-12 17:33:22 -0500 (Fri, 12 Sep 2008) | 2 lines
Issue #3846: Release GIL during calls to sqlite3_prepare. This improves concurrent access to the same database file from multiple threads/processes.
........
r66424 | andrew.kuchling | 2008-09-12 20:22:08 -0500 (Fri, 12 Sep 2008) | 1 line
#687648 from Robert Schuppenies: use classic division. (RM Barry gave permission to update the demos.)
........
r66425 | andrew.kuchling | 2008-09-12 20:27:33 -0500 (Fri, 12 Sep 2008) | 1 line
#687648 from Robert Schuppenies: use classic division. From me: don't use string exception; flush stdout after printing
........
r66426 | andrew.kuchling | 2008-09-12 20:34:41 -0500 (Fri, 12 Sep 2008) | 1 line
#687648 from Robert Schuppenies: use classic division. From me: don't use string exception; add __main__ section
........
r66427 | andrew.kuchling | 2008-09-12 20:42:55 -0500 (Fri, 12 Sep 2008) | 1 line
#687648 from Robert Schuppenies: use classic division. From me: remove two stray semicolons
........
r66428 | andrew.kuchling | 2008-09-12 20:43:28 -0500 (Fri, 12 Sep 2008) | 1 line
#687648 from Robert Schuppenies: use classic division.
........
r66429 | andrew.kuchling | 2008-09-12 20:47:02 -0500 (Fri, 12 Sep 2008) | 1 line
Remove semicolon
........
r66430 | andrew.kuchling | 2008-09-12 20:48:36 -0500 (Fri, 12 Sep 2008) | 1 line
Subclass exception
........
r66431 | andrew.kuchling | 2008-09-12 20:56:56 -0500 (Fri, 12 Sep 2008) | 1 line
Fix SyntaxError
........
r66432 | andrew.kuchling | 2008-09-12 20:57:25 -0500 (Fri, 12 Sep 2008) | 1 line
Update uses of string exceptions
........
r66433 | andrew.kuchling | 2008-09-12 21:08:30 -0500 (Fri, 12 Sep 2008) | 1 line
Use title case
........
r66434 | andrew.kuchling | 2008-09-12 21:09:15 -0500 (Fri, 12 Sep 2008) | 1 line
Remove extra 'the'; the following title includes it
........
r66435 | andrew.kuchling | 2008-09-12 21:11:51 -0500 (Fri, 12 Sep 2008) | 1 line
#3288: Document as_integer_ratio
........
r66436 | andrew.kuchling | 2008-09-12 21:14:15 -0500 (Fri, 12 Sep 2008) | 1 line
Use title case
........
2008-09-13 12:58:53 -03:00
|
|
|
j = i + (n+3)//4*4
|
2004-07-18 02:56:09 -03:00
|
|
|
if j > len(self.buf):
|
|
|
|
raise EOFError
|
|
|
|
self.pos = j
|
|
|
|
return self.buf[i:i+n]
|
|
|
|
|
|
|
|
unpack_fopaque = unpack_fstring
|
|
|
|
|
|
|
|
def unpack_string(self):
|
|
|
|
n = self.unpack_uint()
|
|
|
|
return self.unpack_fstring(n)
|
|
|
|
|
|
|
|
unpack_opaque = unpack_string
|
|
|
|
|
|
|
|
def unpack_list(self, unpack_item):
|
|
|
|
list = []
|
|
|
|
while 1:
|
|
|
|
x = self.unpack_uint()
|
|
|
|
if x == 0: break
|
2006-08-29 01:39:12 -03:00
|
|
|
if x != 1:
|
2007-07-17 17:59:35 -03:00
|
|
|
raise RuntimeError('0 or 1 expected, got %r' % (x, ))
|
2004-07-18 02:56:09 -03:00
|
|
|
item = unpack_item()
|
|
|
|
list.append(item)
|
|
|
|
return list
|
|
|
|
|
|
|
|
def unpack_farray(self, n, unpack_item):
|
|
|
|
list = []
|
|
|
|
for i in range(n):
|
|
|
|
list.append(unpack_item())
|
|
|
|
return list
|
|
|
|
|
|
|
|
def unpack_array(self, unpack_item):
|
|
|
|
n = self.unpack_uint()
|
|
|
|
return self.unpack_farray(n, unpack_item)
|