def decoder_fn(cls, data): value = big_endian_to_int(data) with decimal.localcontext(abi_decimal_context): decimal_value = decimal.Decimal(value) raw_real_value = decimal_value / 2**cls.low_bit_size real_value = quantize_value(raw_real_value, cls.low_bit_size) return real_value
def test_decode_signed_real(high_bit_size, low_bit_size, integer_bit_size, stream_bytes, data_byte_size): if integer_bit_size > data_byte_size * 8: with pytest.raises(ValueError): SignedRealDecoder.as_decoder( value_bit_size=integer_bit_size, high_bit_size=high_bit_size, low_bit_size=low_bit_size, data_byte_size=data_byte_size, ) return elif high_bit_size + low_bit_size != integer_bit_size: with pytest.raises(ValueError): SignedRealDecoder.as_decoder( value_bit_size=integer_bit_size, high_bit_size=high_bit_size, low_bit_size=low_bit_size, data_byte_size=data_byte_size, ) return else: decoder = SignedRealDecoder.as_decoder( value_bit_size=integer_bit_size, high_bit_size=high_bit_size, low_bit_size=low_bit_size, data_byte_size=data_byte_size, ) stream = BytesIO(stream_bytes) padding_bytes = stream_bytes[:data_byte_size][:data_byte_size - integer_bit_size // 8] if len(stream_bytes) < data_byte_size: with pytest.raises(InsufficientDataBytes): decoder(stream) return elif is_non_empty_non_null_byte_string(padding_bytes): with pytest.raises(NonEmptyPaddingBytes): decoder(stream) return else: decoded_value = decoder(stream) _, upper_bound = compute_signed_integer_bounds(high_bit_size + low_bit_size) unsigned_integer_value = big_endian_to_int(stream_bytes[:data_byte_size]) if unsigned_integer_value >= upper_bound: signed_integer_value = unsigned_integer_value - 2**(high_bit_size + low_bit_size) else: signed_integer_value = unsigned_integer_value with decimal.localcontext(abi_decimal_context): raw_actual_value = decimal.Decimal( signed_integer_value) / 2**low_bit_size actual_value = quantize_value(raw_actual_value, low_bit_size) assert decoded_value == actual_value
def decoder_fn(cls, data): value = big_endian_to_int(data) if value >= 2 ** (cls.high_bit_size + cls.low_bit_size - 1): signed_value = value - 2 ** (cls.high_bit_size + cls.low_bit_size) else: signed_value = value signed_decimal_value = decimal.Decimal(signed_value) raw_real_value = signed_decimal_value / 2 ** cls.low_bit_size real_value = quantize_value(raw_real_value, cls.low_bit_size) return real_value
def test_decode_unsigned_real(high_bit_size, low_bit_size, integer_bit_size, stream_bytes, data_byte_size): if integer_bit_size > data_byte_size * 8: with pytest.raises(ValueError): UnsignedRealDecoder.as_decoder( value_bit_size=integer_bit_size, high_bit_size=high_bit_size, low_bit_size=low_bit_size, data_byte_size=data_byte_size, ) return elif high_bit_size + low_bit_size != integer_bit_size: with pytest.raises(ValueError): UnsignedRealDecoder.as_decoder( value_bit_size=integer_bit_size, high_bit_size=high_bit_size, low_bit_size=low_bit_size, data_byte_size=data_byte_size, ) return else: decoder = UnsignedRealDecoder.as_decoder( value_bit_size=integer_bit_size, high_bit_size=high_bit_size, low_bit_size=low_bit_size, data_byte_size=data_byte_size, ) stream = BytesIO(stream_bytes) padding_bytes = stream_bytes[:data_byte_size][:data_byte_size - integer_bit_size // 8] if len(stream_bytes) < data_byte_size: with pytest.raises(InsufficientDataBytes): decoder(stream) return elif is_non_empty_non_null_byte_string(padding_bytes): with pytest.raises(NonEmptyPaddingBytes): decoder(stream) return else: decoded_value = decoder(stream) unsigned_integer_value = big_endian_to_int(stream_bytes[:data_byte_size]) raw_real_value = decimal.Decimal(unsigned_integer_value) / 2 ** low_bit_size actual_value = quantize_value(raw_real_value, low_bit_size) assert decoded_value == actual_value
def test_decode_signed_int(integer_bit_size, stream_bytes, data_byte_size): if integer_bit_size % 8 != 0: with pytest.raises(ValueError): SignedIntegerDecoder.as_decoder( value_bit_size=integer_bit_size, data_byte_size=data_byte_size, ) return elif integer_bit_size > data_byte_size * 8: with pytest.raises(ValueError): SignedIntegerDecoder.as_decoder( value_bit_size=integer_bit_size, data_byte_size=data_byte_size, ) return else: decoder = SignedIntegerDecoder.as_decoder( value_bit_size=integer_bit_size, data_byte_size=data_byte_size, ) stream = BytesIO(stream_bytes) padding_bytes = data_byte_size - integer_bit_size // 8 raw_value = big_endian_to_int(stream_bytes[padding_bytes:data_byte_size]) if raw_value >= 2 ** (integer_bit_size - 1): actual_value = raw_value - 2 ** integer_bit_size else: actual_value = raw_value if len(stream_bytes) < data_byte_size: with pytest.raises(InsufficientDataBytes): decoder(stream) return elif ( (actual_value >= 0 and not all_bytes_equal(stream_bytes[:padding_bytes], 0)) or (actual_value < 0 and not all_bytes_equal(stream_bytes[:padding_bytes], 255)) ): with pytest.raises(NonEmptyPaddingBytes): decoder(stream) return else: decoded_value = decoder(stream) assert decoded_value == actual_value
def test_decode_unsigned_int(integer_bit_size, stream_bytes, data_byte_size): if integer_bit_size % 8 != 0: with pytest.raises(ValueError): UnsignedIntegerDecoder.as_decoder( value_bit_size=integer_bit_size, data_byte_size=data_byte_size, ) return elif integer_bit_size > data_byte_size * 8: with pytest.raises(ValueError): UnsignedIntegerDecoder.as_decoder( value_bit_size=integer_bit_size, data_byte_size=data_byte_size, ) return else: decoder = UnsignedIntegerDecoder.as_decoder( value_bit_size=integer_bit_size, data_byte_size=data_byte_size, ) stream = BytesIO(stream_bytes) actual_value = big_endian_to_int(stream_bytes[:data_byte_size]) if len(stream_bytes) < data_byte_size: with pytest.raises(InsufficientDataBytes): decoder(stream) return elif actual_value > 2 ** integer_bit_size - 1: with pytest.raises(NonEmptyPaddingBytes): decoder(stream) return else: decoded_value = decoder(stream) assert decoded_value == actual_value
def is_non_empty_non_null_byte_string(value): return value and big_endian_to_int(value) != 0
def decoder_fn(cls, data): value = big_endian_to_int(data) if value >= 2**(cls.value_bit_size - 1): return value - 2**cls.value_bit_size else: return value
def test_decode_signed_real(high_bit_size, low_bit_size, integer_bit_size, stream_bytes, data_byte_size): if integer_bit_size > data_byte_size * 8: with pytest.raises(ValueError): SignedRealDecoder.as_decoder( value_bit_size=integer_bit_size, high_bit_size=high_bit_size, low_bit_size=low_bit_size, data_byte_size=data_byte_size, ) return elif high_bit_size + low_bit_size != integer_bit_size: with pytest.raises(ValueError): SignedRealDecoder.as_decoder( value_bit_size=integer_bit_size, high_bit_size=high_bit_size, low_bit_size=low_bit_size, data_byte_size=data_byte_size, ) return else: decoder = SignedRealDecoder.as_decoder( value_bit_size=integer_bit_size, high_bit_size=high_bit_size, low_bit_size=low_bit_size, data_byte_size=data_byte_size, ) stream = BytesIO(stream_bytes) padding_offset = data_byte_size - integer_bit_size // 8 data_offset = padding_offset + integer_bit_size // 8 padding_bytes = stream_bytes[:data_byte_size][:padding_offset] data_bytes = stream_bytes[:data_byte_size][padding_offset:data_offset] if len(stream_bytes) < data_byte_size: with pytest.raises(InsufficientDataBytes): decoder(stream) return elif not is_valid_padding_bytes(padding_bytes, data_bytes): with pytest.raises(NonEmptyPaddingBytes): decoder(stream) return else: decoded_value = decoder(stream) if padding_bytes: if decoded_value >= 0: assert bytes(set(padding_bytes)) == b'\x00' else: assert bytes(set(padding_bytes)) == b'\xff' _, upper_bound = compute_signed_integer_bounds(high_bit_size + low_bit_size) unsigned_integer_value = big_endian_to_int(data_bytes) if unsigned_integer_value >= upper_bound: signed_integer_value = unsigned_integer_value - 2 ** (high_bit_size + low_bit_size) else: signed_integer_value = unsigned_integer_value with decimal.localcontext(abi_decimal_context): raw_actual_value = decimal.Decimal(signed_integer_value) / 2 ** low_bit_size actual_value = quantize_value(raw_actual_value, low_bit_size) assert decoded_value == actual_value
def decoder_fn(cls, data): value = big_endian_to_int(data) decimal_value = decimal.Decimal(value) raw_real_value = decimal_value / 2 ** cls.low_bit_size real_value = quantize_value(raw_real_value, cls.low_bit_size) return real_value