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
109
Lib/xdrlib.py
109
Lib/xdrlib.py
|
@ -2,24 +2,9 @@
|
||||||
|
|
||||||
See: RFC 1014
|
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
|
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
|
# exceptions
|
||||||
class Error:
|
class Error:
|
||||||
|
@ -60,14 +45,7 @@ class Packer:
|
||||||
get_buf = get_buffer
|
get_buf = get_buffer
|
||||||
|
|
||||||
def pack_uint(self, x):
|
def pack_uint(self, x):
|
||||||
self.__buf = self.__buf + \
|
self.__buf = self.__buf + struct.pack('>L', x)
|
||||||
(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)
|
|
||||||
|
|
||||||
pack_int = pack_uint
|
pack_int = pack_uint
|
||||||
pack_enum = pack_int
|
pack_enum = pack_int
|
||||||
|
@ -83,19 +61,14 @@ class Packer:
|
||||||
pack_hyper = pack_uhyper
|
pack_hyper = pack_uhyper
|
||||||
|
|
||||||
def pack_float(self, x):
|
def pack_float(self, x):
|
||||||
raise ConversionError('Not supported')
|
try: self.__buf = self.__buf + struct.pack('>f', x)
|
||||||
|
except struct.error, msg:
|
||||||
|
raise ConversionError(msg)
|
||||||
|
|
||||||
def pack_double(self, x):
|
def pack_double(self, x):
|
||||||
raise ConversionError('Not supported')
|
try: self.__buf = self.__buf + struct.pack('>d', x)
|
||||||
# get these from the C layer if available
|
except struct.error, msg:
|
||||||
if _xdr:
|
raise ConversionError(msg)
|
||||||
def pack_float(self, x):
|
|
||||||
try: self.__buf = self.__buf + _xdr.pack_float(x)
|
|
||||||
except _xdr.error, msg:
|
|
||||||
raise ConversionError(msg)
|
|
||||||
def pack_double(self, x):
|
|
||||||
try: self.__buf = self.__buf + _xdr.pack_double(x)
|
|
||||||
except _xdr.error, msg:
|
|
||||||
raise ConversionError(msg)
|
|
||||||
|
|
||||||
def pack_fstring(self, n, s):
|
def pack_fstring(self, n, s):
|
||||||
if n < 0:
|
if n < 0:
|
||||||
|
@ -163,27 +136,19 @@ class Unpacker:
|
||||||
data = self.__buf[i:j]
|
data = self.__buf[i:j]
|
||||||
if len(data) < 4:
|
if len(data) < 4:
|
||||||
raise EOFError
|
raise EOFError
|
||||||
x = long(ord(data[0]))<<24 | ord(data[1])<<16 | \
|
x = struct.unpack('>L', data)[0]
|
||||||
ord(data[2])<<8 | ord(data[3])
|
try:
|
||||||
# Return a Python long only if the value is not representable
|
return int(x)
|
||||||
# as a nonnegative Python int
|
except OverflowError:
|
||||||
if x < 0x80000000L:
|
return x
|
||||||
x = int(x)
|
|
||||||
return x
|
|
||||||
if _USE_MACHINE_REP:
|
|
||||||
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)[0]
|
|
||||||
|
|
||||||
def unpack_int(self):
|
def unpack_int(self):
|
||||||
x = self.unpack_uint()
|
i = self.__pos
|
||||||
if x >= 0x80000000L:
|
self.__pos = j = i+4
|
||||||
x = x - 0x100000000L
|
data = self.__buf[i:j]
|
||||||
return int(x)
|
if len(data) < 4:
|
||||||
|
raise EOFError
|
||||||
|
return struct.unpack('>l', data)[0]
|
||||||
|
|
||||||
unpack_enum = unpack_int
|
unpack_enum = unpack_int
|
||||||
unpack_bool = unpack_int
|
unpack_bool = unpack_int
|
||||||
|
@ -200,30 +165,20 @@ class Unpacker:
|
||||||
return x
|
return x
|
||||||
|
|
||||||
def unpack_float(self):
|
def unpack_float(self):
|
||||||
raise ConversionError('Not supported')
|
i = self.__pos
|
||||||
def unpack_double(self):
|
self.__pos = j = i+4
|
||||||
raise ConversionError('Not supported')
|
data = self.__buf[i:j]
|
||||||
# get these from the C layer if available
|
if len(data) < 4:
|
||||||
if _xdr:
|
raise EOFError
|
||||||
def unpack_float(self):
|
return struct.unpack('>f', data)[0]
|
||||||
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)
|
|
||||||
|
|
||||||
def unpack_double(self):
|
def unpack_double(self):
|
||||||
i = self.__pos
|
i = self.__pos
|
||||||
self.__pos = j = i+8
|
self.__pos = j = i+8
|
||||||
data = self.__buf[i:j]
|
data = self.__buf[i:j]
|
||||||
if len(data) < 8:
|
if len(data) < 8:
|
||||||
raise EOFError
|
raise EOFError
|
||||||
try: return _xdr.unpack_double(data)
|
return struct.unpack('>d', data)[0]
|
||||||
except _xdr.error, msg:
|
|
||||||
raise ConversionError(msg)
|
|
||||||
|
|
||||||
def unpack_fstring(self, n):
|
def unpack_fstring(self, n):
|
||||||
if n < 0:
|
if n < 0:
|
||||||
|
|
Loading…
Reference in New Issue