def serialize(self, val): if ( not isinstance(val, Iterable) or isinstance(val, (bytes, bytearray, str)) ): raise SerializationError( 'Can only serialize Iterable objects, except Dictionaries', val ) if self.empty and len(val) != 0: raise ValueError( "Empty List Sedes cannot serialize non-empty Iterables" ) serialized_iterable_string = b"".join( self.element_sedes.serialize(element) for element in val ) if len(serialized_iterable_string) >= 2 ** (LIST_PREFIX_LENGTH * 8): raise SerializationError( 'List too long to fit into {} bytes after serialization'.format(LIST_PREFIX_LENGTH), val ) serialized_len = len(serialized_iterable_string).to_bytes(LIST_PREFIX_LENGTH, 'big') return serialized_len + serialized_iterable_string
def serialize(self, val): if not isinstance(val, bytes): raise SerializationError('Hash should be of type bytes', val) if len(val) != self.num_bytes: raise SerializationError( "Can only serialize values of {} bytes".format(self.num_bytes), val) return val
def serialize(self, value: int) -> bytes: if value < 0: raise SerializationError( f"Can only serialize non-negative integers, got {value}", ) try: return value.to_bytes(self.size, "little") except OverflowError: raise SerializationError( f"{value} is too large to be serialized in {self.size * 8} bits" )
def serialize_content(self, value: Sequence[TSerializableElement]) -> bytes: if isinstance(value, (bytes, bytearray, str)): raise SerializationError("Can not serialize strings as tuples") if len(value) != self.length: raise SerializationError( f"Cannot serialize {len(value)} elements as {self.length}-tuple" ) return b"".join( self.element_sedes.serialize(element) for element in value)
def serialize(self, val): if not isinstance(val, (bytes, bytearray)): raise SerializationError( "Can only serialize bytes or bytearray objects", val) object_len = len(val) if object_len >= 2**(BYTES_PREFIX_LENGTH * 8): raise SerializationError( f'Object too long for its length to fit into {BYTES_PREFIX_LENGTH} bytes' f'after serialization', val) # Convert the length of bytes to a 4 bytes value object_len_bytes = object_len.to_bytes(BYTES_PREFIX_LENGTH, 'big') return object_len_bytes + val
def serialize(self, value: BytesOrByteArray) -> bytes: if len(value) != self.length: raise SerializationError( f"Cannot serialize length {len(value)} byte-string as bytes{self.length}" ) return value
def serialize(self, value: Sequence[bool]) -> bytes: if len(value) != self.bit_count: raise SerializationError( f"Cannot serialize length {len(value)} bit array as Bitvector[{self.bit_count}]" ) return bytes( get_serialized_bytearray(value, self.bit_count, extra_byte=False))
def _validate_emptiness(value: Iterable[TSerializable]) -> None: try: first(value) except StopIteration: pass else: raise SerializationError("Can only serialize empty Iterables")
def serialize(self, val): if isinstance(val, bool) or not isinstance(val, int): raise SerializationError( 'As per specified sedes object, can only serialize non-negative integer values', val) if val < 0: raise SerializationError( 'As per specified sedes object, can only serialize non-negative integer values', val) try: serialized_obj = val.to_bytes(self.num_bytes, 'big') except OverflowError as err: raise SerializationError('As per specified sedes object, %s' % err, val) return serialized_obj
def serialize_content(self, value: Iterable[TSerializable]) -> bytes: if isinstance(value, (bytes, bytearray, str)): raise SerializationError("Can not serialize strings as lists") if self.empty: self._validate_emptiness(value) return b"".join( self.element_sedes.serialize(element) for element in value)
def serialize(self, obj): if not isinstance(obj, bool): raise SerializationError('Can only serialize boolean values', obj) if obj is False: return b'\x00' elif obj is True: return b'\x01' else: raise Exception("Invariant: no other options for boolean values")
def serialize(self, value: Sequence[bool]) -> bytes: len_value = len(value) if len_value > self.max_bit_count: raise SerializationError( f"Cannot serialize length {len_value} bit array as Bitlist[{self.max_bit_count}]" ) serialized_bytearray = get_serialized_bytearray(value, len_value, extra_byte=True) serialized_bytearray[len_value // 8] |= 1 << (len_value % 8) return bytes(serialized_bytearray)
def serialize(cls, obj): # Make sure that the obj is instance of class before serializing if not isinstance(obj, cls): raise SerializationError( f"Can only serialize objects which are instances of {cls.__name__} class", obj ) serialized_string = b"".join( field_sedes.serialize(getattr(obj, field_name)) for field_name, field_sedes in cls._meta.fields ) if len(serialized_string) >= MAX_LEN_SERIALIZED_CONTAINER_OBJECT: raise SerializationError( f'Container too long to fit into {CONTAINER_PREFIX_LENGTH} bytes' f'after serialization', obj ) serialized_len = len(serialized_string).to_bytes(CONTAINER_PREFIX_LENGTH, 'big') return serialized_len + serialized_string
def validate_content_size(content: bytes) -> None: if len(content) >= MAX_CONTENT_SIZE: raise SerializationError( f"Content size is too large to be encoded in a {SIZE_PREFIX_SIZE} byte prefix", )
def serialize_content(self, value: BytesOrByteArray) -> bytes: if len(value) != self.size: raise SerializationError( f"Cannot serialize {len(value)} bytes as bytes{self.size}") return value
def serialize(self, value: TSerializable) -> bytes: serialized_content = self.serialize_content(value) if len(serialized_content) != self.size: raise SerializationError( f"Cannot serialize {value} in {self.size} bytes") return serialized_content
def validate_content_length(self, content: bytes) -> None: if len(content) >= self.max_content_length: raise SerializationError( f"Content is too big to be encoded in prefix of {self.length_bytes} bytes", )
def serialize(self, value: Sequence[TSerializable]): if len(value): raise SerializationError("Cannot serialize non-empty sequence using `EmptyList` sedes") return b''
def _validate_serializable(self, value: Any) -> None: if len(value) != self.length: raise SerializationError( f"Length mismatch. Cannot serialize value with length " f"{len(value)} as {self.length}-tuple")
def serialize_element_for_tree(self, index: int, byte_value: int) -> bytes: if not 0 <= byte_value < 256: raise SerializationError( f"Cannot serialize byte as its value {byte_value} is invalid") return bytes((byte_value, ))
def serialize_content(self, value: BytesOrByteArray) -> bytes: if len(value) != self.length: raise SerializationError( f"Can only serialize values of exactly {self.length} bytes, got" f"{encode_hex(value)} which is {len(value)} bytes.") return value
def serialize(self, value: bytes) -> bytes: if len(value) != 1: raise SerializationError( f"The `Byte` sedes can only serialize single bytes. Got: {value!r}" ) return value
def _validate_serializable(self, value: Sequence[Any]) -> bytes: if len(value) != len(self.field_sedes): raise SerializationError( f"Incorrect element count: Expected: {len(self.field_sedes)} / Got: {len(value)}" )