home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pyth_os2.zip / python-1.0.2 / Demo / rpc / xdr.py < prev   
Text File  |  1993-12-17  |  4KB  |  202 lines

  1. # Implement (a subset of) Sun XDR -- RFC1014.
  2.  
  3.  
  4. try:
  5.     import struct
  6. except ImportError:
  7.     struct = None
  8.  
  9.  
  10. Long = type(0L)
  11.  
  12.  
  13. class Packer:
  14.  
  15.     def __init__(self):
  16.         self.reset()
  17.  
  18.     def reset(self):
  19.         self.buf = ''
  20.  
  21.     def get_buf(self):
  22.         return self.buf
  23.  
  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)
  34.  
  35.     pack_int = pack_uint
  36.  
  37.     pack_enum = pack_int
  38.  
  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'
  42.  
  43.     def pack_uhyper(self, x):
  44.         self.pack_uint(int(x>>32 & 0xffffffff))
  45.         self.pack_uint(int(x & 0xffffffff))
  46.  
  47.     pack_hyper = pack_uhyper
  48.  
  49.     def pack_float(self, x):
  50.         # XXX
  51.         self.buf = self.buf + struct.pack('f', x)
  52.  
  53.     def pack_double(self, x):
  54.         # XXX
  55.         self.buf = self.buf + struct.pack('d', x)
  56.  
  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
  64.  
  65.     pack_fopaque = pack_fstring
  66.  
  67.     def pack_string(self, s):
  68.         n = len(s)
  69.         self.pack_uint(n)
  70.         self.pack_fstring(n, s)
  71.  
  72.     pack_opaque = pack_string
  73.  
  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)
  79.  
  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)
  85.  
  86.     def pack_array(self, list, pack_item):
  87.         n = len(list)
  88.         self.pack_uint(n)
  89.         self.pack_farray(n, list)
  90.  
  91.  
  92. class Unpacker:
  93.  
  94.     def __init__(self, data):
  95.         self.reset(data)
  96.  
  97.     def reset(self, data):
  98.         self.buf = data
  99.         self.pos = 0
  100.  
  101.     def done(self):
  102.         if self.pos < len(self.buf):
  103.             raise RuntimeError, 'unextracted data remains'
  104.  
  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)
  125.  
  126.     def unpack_int(self):
  127.         x = self.unpack_uint()
  128.         if x >= 0x80000000L: x = x - 0x100000000L
  129.         return int(x)
  130.  
  131.     unpack_enum = unpack_int
  132.  
  133.     unpack_bool = unpack_int
  134.  
  135.     def unpack_uhyper(self):
  136.         hi = self.unpack_uint()
  137.         lo = self.unpack_uint()
  138.         return long(hi)<<32 | lo
  139.  
  140.     def unpack_hyper(self):
  141.         x = self.unpack_uhyper()
  142.         if x >= 0x8000000000000000L: x = x - 0x10000000000000000L
  143.         return x
  144.  
  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]
  153.  
  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('8', data)[0]
  162.  
  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]
  172.  
  173.     unpack_fopaque = unpack_fstring
  174.  
  175.     def unpack_string(self):
  176.         n = self.unpack_uint()
  177.         return self.unpack_fstring(n)
  178.  
  179.     unpack_opaque = unpack_string
  180.  
  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, \
  188.                     '0 or 1 expected, got ' + `x`
  189.             item = unpack_item()
  190.             list.append(item)
  191.         return list
  192.  
  193.     def unpack_farray(self, n, unpack_item):
  194.         list = []
  195.         for i in range(n):
  196.             list.append(unpack_item())
  197.         return list
  198.  
  199.     def unpack_array(self, unpack_item):
  200.         n = self.unpack_uint()
  201.         return self.unpack_farray(n, unpack_item)
  202.