Use the new struct module's ability to pack and unpack standardized
data formats. The _xdr module is no longer used, since struct supports the required IEEE floats and doubles. (I have one doubt about not using _xdr. The struct module doesn't handle Inf, NaN and gradual underflow correctly. If the _xdr module does these things better, it may still have a (small) competitive advantage. On the other hand, since not all platforms support IEEE floating point, it's not clear that it would be a good idea to ever transfer Inf or NaNs. Gradual underflow can be fixed in the struct module.
This commit is contained in:
parent
07ef655222
commit
6083f0e9ce
|
@ -2,24 +2,9 @@
|
|||
|
||||
See: RFC 1014
|
||||
|
||||
This module will conditionally use the _xdrmodule.so module to get
|
||||
support for those representations we can't do much with from Python.
|
||||
|
||||
"""
|
||||
|
||||
import struct
|
||||
from types import LongType
|
||||
|
||||
# use C layer XDR libraries for some data types if available
|
||||
try:
|
||||
import _xdr
|
||||
except ImportError:
|
||||
_xdr = None
|
||||
|
||||
# this test is done to see if machine representation is the same as
|
||||
# network representation. if so, we can use module struct for packing
|
||||
# some data types
|
||||
_USE_MACHINE_REP = (struct.pack('l', 1) == '\0\0\0\1')
|
||||
|
||||
# exceptions
|
||||
class Error:
|
||||
|
@ -60,14 +45,7 @@ class Packer:
|
|||
get_buf = get_buffer
|
||||
|
||||
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 _USE_MACHINE_REP:
|
||||
def pack_uint(self, x):
|
||||
if type(x) == LongType:
|
||||
x = int((x + 0x80000000L) % 0x100000000L - 0x80000000L)
|
||||
self.__buf = self.__buf + struct.pack('l', x)
|
||||
self.__buf = self.__buf + struct.pack('>L', x)
|
||||
|
||||
pack_int = pack_uint
|
||||
pack_enum = pack_int
|
||||
|
@ -83,18 +61,13 @@ class Packer:
|
|||
pack_hyper = pack_uhyper
|
||||
|
||||
def pack_float(self, x):
|
||||
raise ConversionError('Not supported')
|
||||
def pack_double(self, x):
|
||||
raise ConversionError('Not supported')
|
||||
# get these from the C layer if available
|
||||
if _xdr:
|
||||
def pack_float(self, x):
|
||||
try: self.__buf = self.__buf + _xdr.pack_float(x)
|
||||
except _xdr.error, msg:
|
||||
try: self.__buf = self.__buf + struct.pack('>f', x)
|
||||
except struct.error, msg:
|
||||
raise ConversionError(msg)
|
||||
|
||||
def pack_double(self, x):
|
||||
try: self.__buf = self.__buf + _xdr.pack_double(x)
|
||||
except _xdr.error, msg:
|
||||
try: self.__buf = self.__buf + struct.pack('>d', x)
|
||||
except struct.error, msg:
|
||||
raise ConversionError(msg)
|
||||
|
||||
def pack_fstring(self, n, s):
|
||||
|
@ -163,27 +136,19 @@ class Unpacker:
|
|||
data = self.__buf[i:j]
|
||||
if len(data) < 4:
|
||||
raise EOFError
|
||||
x = long(ord(data[0]))<<24 | ord(data[1])<<16 | \
|
||||
ord(data[2])<<8 | ord(data[3])
|
||||
# Return a Python long only if the value is not representable
|
||||
# as a nonnegative Python int
|
||||
if x < 0x80000000L:
|
||||
x = int(x)
|
||||
x = struct.unpack('>L', data)[0]
|
||||
try:
|
||||
return int(x)
|
||||
except OverflowError:
|
||||
return x
|
||||
if _USE_MACHINE_REP:
|
||||
def unpack_uint(self):
|
||||
|
||||
def unpack_int(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)[0]
|
||||
|
||||
def unpack_int(self):
|
||||
x = self.unpack_uint()
|
||||
if x >= 0x80000000L:
|
||||
x = x - 0x100000000L
|
||||
return int(x)
|
||||
return struct.unpack('>l', data)[0]
|
||||
|
||||
unpack_enum = unpack_int
|
||||
unpack_bool = unpack_int
|
||||
|
@ -199,21 +164,13 @@ class Unpacker:
|
|||
x = x - 0x10000000000000000L
|
||||
return x
|
||||
|
||||
def unpack_float(self):
|
||||
raise ConversionError('Not supported')
|
||||
def unpack_double(self):
|
||||
raise ConversionError('Not supported')
|
||||
# get these from the C layer if available
|
||||
if _xdr:
|
||||
def unpack_float(self):
|
||||
i = self.__pos
|
||||
self.__pos = j = i+4
|
||||
data = self.__buf[i:j]
|
||||
if len(data) < 4:
|
||||
raise EOFError
|
||||
try: return _xdr.unpack_float(data)
|
||||
except _xdr.error, msg:
|
||||
raise ConversionError(msg)
|
||||
return struct.unpack('>f', data)[0]
|
||||
|
||||
def unpack_double(self):
|
||||
i = self.__pos
|
||||
|
@ -221,9 +178,7 @@ class Unpacker:
|
|||
data = self.__buf[i:j]
|
||||
if len(data) < 8:
|
||||
raise EOFError
|
||||
try: return _xdr.unpack_double(data)
|
||||
except _xdr.error, msg:
|
||||
raise ConversionError(msg)
|
||||
return struct.unpack('>d', data)[0]
|
||||
|
||||
def unpack_fstring(self, n):
|
||||
if n < 0:
|
||||
|
|
Loading…
Reference in New Issue