import struct
import p2pool
+from p2pool.util import memoize
class EarlyEnd(Exception):
pass
def __ne__(self, other):
return not (self == other)
- def _unpack(self, data):
+ def _unpack(self, data, ignore_trailing=False):
obj, (data2, pos) = self.read((data, 0))
assert data2 is data
- if pos != len(data):
+ if pos != len(data) and not ignore_trailing:
raise LateEnd()
return obj
return ''.join(res)
- def unpack(self, data):
- obj = self._unpack(data)
+ def unpack(self, data, ignore_trailing=False):
+ obj = self._unpack(data, ignore_trailing)
if p2pool.DEBUG:
- if self._pack(obj) != data:
+ packed = self._pack(obj)
+ good = data.startswith(packed) if ignore_trailing else data == packed
+ if not good:
raise AssertionError()
return obj
class ListType(Type):
_inner_size = VarIntType()
- def __init__(self, type):
+ def __init__(self, type, mul=1):
self.type = type
+ self.mul = mul
def read(self, file):
length, file = self._inner_size.read(file)
- res = []
+ length *= self.mul
+ res = [None]*length
for i in xrange(length):
- item, file = self.type.read(file)
- res.append(item)
+ res[i], file = self.type.read(file)
return res, file
def write(self, file, item):
- file = self._inner_size.write(file, len(item))
+ assert len(item) % self.mul == 0
+ file = self._inner_size.write(file, len(item)//self.mul)
for subitem in item:
file = self.type.write(file, subitem)
return file
def write(self, file, item):
return file, struct.pack(self.desc, item)
+@memoize.fast_memoize_multiple_args
class IntType(Type):
__slots__ = 'bytes step format_str max'.split(' ')
if isinstance(other, dict):
return dict(self) == other
elif isinstance(other, _Record):
- return all(self[k] == other[k] for k in self.keys())
+ for k in fields:
+ if getattr(self, k) != getattr(other, k):
+ return False
+ return True
elif other is None:
return False
raise TypeError()
def __ne__(self, other):
return not (self == other)
_record_types[fields] = _Record
- return _record_types[fields]()
+ return _record_types[fields]
class ComposedType(Type):
def __init__(self, fields):
- self.fields = tuple(fields)
+ self.fields = list(fields)
self.field_names = set(k for k, v in fields)
+ self.record_type = get_record(k for k, v in self.fields)
def read(self, file):
- item = get_record(k for k, v in self.fields)
+ item = self.record_type()
for key, type_ in self.fields:
item[key], file = type_.read(file)
return item, file