big_endian_int.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. from eth_utils import (
  2. big_endian_to_int,
  3. int_to_big_endian,
  4. )
  5. from rlp.exceptions import (
  6. DeserializationError,
  7. SerializationError,
  8. )
  9. class BigEndianInt:
  10. """
  11. A sedes for big endian integers.
  12. :param l: the size of the serialized representation in bytes or `None` to
  13. use the shortest possible one
  14. """
  15. def __init__(self, length=None):
  16. self.length = length
  17. def serialize(self, obj):
  18. if isinstance(obj, bool) or not isinstance(obj, int):
  19. raise SerializationError("Can only serialize integers", obj)
  20. if self.length is not None and obj >= 256**self.length:
  21. raise SerializationError(
  22. f"Integer too large (does not fit in {self.length} bytes)",
  23. obj,
  24. )
  25. if obj < 0:
  26. raise SerializationError("Cannot serialize negative integers", obj)
  27. if obj == 0:
  28. s = b""
  29. else:
  30. s = int_to_big_endian(obj)
  31. if self.length is not None:
  32. return b"\x00" * max(0, self.length - len(s)) + s
  33. else:
  34. return s
  35. def deserialize(self, serial):
  36. if self.length is not None and len(serial) != self.length:
  37. raise DeserializationError("Invalid serialization (wrong size)", serial)
  38. if self.length is None and len(serial) > 0 and serial[0:1] == b"\x00":
  39. raise DeserializationError(
  40. "Invalid serialization (not minimal " "length)", serial
  41. )
  42. serial = serial or b"\x00"
  43. return big_endian_to_int(serial)
  44. big_endian_int = BigEndianInt()