Example #1
0
def write_uvarint(w: Writer, n: int) -> None:
    ensure(0 <= n <= 0xFFFF_FFFF_FFFF_FFFF)
    shifted = 1
    while shifted:
        shifted = n >> 7
        byte = (n & 0x7F) | (0x80 if shifted else 0x00)
        w.append(byte)
        n = shifted
Example #2
0
def write_uint64_be(w: Writer, n: int) -> int:
    ensure(0 <= n <= 0xFFFFFFFFFFFFFFFF)
    w.append((n >> 56) & 0xFF)
    w.append((n >> 48) & 0xFF)
    w.append((n >> 40) & 0xFF)
    w.append((n >> 32) & 0xFF)
    w.append((n >> 24) & 0xFF)
    w.append((n >> 16) & 0xFF)
    w.append((n >> 8) & 0xFF)
    w.append(n & 0xFF)
    return 8
Example #3
0
def write_int(w: Writer, number: bytes) -> None:
    i = 0
    while i < len(number) and number[i] == 0:
        i += 1

    length = len(number) - i
    w.append(0x02)
    if length == 0 or number[i] >= 0x80:
        w.extend(encode_length(length + 1))
        w.append(0x00)
    else:
        w.extend(encode_length(length))

    w.extend(memoryview(number)[i:])
Example #4
0
def write_varint(w: Writer, val: int) -> None:
    """
    Implements variable-length int encoding from Ripple.
    See: https://ripple.com/wiki/Binary_Format#Variable_Length_Data_Encoding
    """
    if val < 0:
        raise ValueError("Only non-negative integers are supported")
    elif val < 192:
        w.append(val)
    elif val <= 12480:
        val -= 193
        w.append(193 + rshift(val, 8))
        w.append(val & 0xFF)
    elif val <= 918744:
        val -= 12481
        w.append(241 + rshift(val, 16))
        w.append(rshift(val, 8) & 0xFF)
        w.append(val & 0xFF)
    else:
        raise ValueError("Value is too large")
Example #5
0
def write_compact_size(w: Writer, n: int) -> None:
    ensure(0 <= n <= 0xFFFF_FFFF)
    if n < 253:
        w.append(n & 0xFF)
    elif n < 0x1_0000:
        w.append(253)
        write_uint16_le(w, n)
    elif n < 0x1_0000_0000:
        w.append(254)
        write_uint32_le(w, n)
    else:
        w.append(255)
        write_uint64_le(w, n)
Example #6
0
def write_type(w: Writer, field: RippleField) -> None:
    if field.key <= 0xF:
        w.append((field.type << 4) | field.key)
    else:
        # this concerns two-bytes fields such as lastLedgerSequence
        w.append(field.type << 4)
        w.append(field.key)
Example #7
0
def write_uint32_be(w: Writer, n: int) -> int:
    ensure(0 <= n <= 0xFFFFFFFF)
    w.append((n >> 24) & 0xFF)
    w.append((n >> 16) & 0xFF)
    w.append((n >> 8) & 0xFF)
    w.append(n & 0xFF)
    return 4
Example #8
0
def write_header(
    w: Writer,
    length: int,
    header_byte: int,
    data_start: bytes | None = None,
) -> None:
    if length == 1 and data_start is not None and data_start[0] <= 0x7F:
        # no header when encoding one byte below 0x80
        pass

    elif length <= 55:
        w.append(header_byte + length)

    else:
        encoded_length = int_to_bytes(length)
        w.append(header_byte + 55 + len(encoded_length))
        w.extend(encoded_length)
Example #9
0
def write(w: Writer, field: RippleField,
          value: int | bytes | str | None) -> None:
    if value is None:
        return
    write_type(w, field)
    if field.type == FIELD_TYPE_INT16:
        assert isinstance(value, int)
        w.extend(value.to_bytes(2, "big"))
    elif field.type == FIELD_TYPE_INT32:
        assert isinstance(value, int)
        w.extend(value.to_bytes(4, "big"))
    elif field.type == FIELD_TYPE_AMOUNT:
        assert isinstance(value, int)
        w.extend(serialize_amount(value))
    elif field.type == FIELD_TYPE_ACCOUNT:
        assert isinstance(value, str)
        write_bytes_varint(w, helpers.decode_address(value))
    elif field.type == FIELD_TYPE_VL:
        assert isinstance(value, (bytes, bytearray))
        write_bytes_varint(w, value)
    else:
        raise ValueError("Unknown field type")
Example #10
0
def write_bytes_reversed(w: Writer, b: bytes, length: int) -> int:
    ensure(len(b) == length)
    w.extend(bytes(reversed(b)))
    return length
Example #11
0
def write_bytes_reversed(w: Writer, b: bytes) -> int:
    w.extend(bytes(reversed(b)))
    return len(b)
Example #12
0
def write_bytes(w: Writer, b: bytes) -> int:
    w.extend(b)
    return len(b)
Example #13
0
def write_uint16_le(w: Writer, n: int) -> int:
    ensure(0 <= n <= 0xFFFF)
    w.append(n & 0xFF)
    w.append((n >> 8) & 0xFF)
    return 2
Example #14
0
def write_uint8(w: Writer, n: int) -> int:
    ensure(0 <= n <= 0xFF)
    w.append(n)
    return 1
Example #15
0
def write_bytes_varint(w: Writer, value: bytes) -> None:
    """Serialize a variable length bytes."""
    write_varint(w, len(value))
    w.extend(value)
Example #16
0
def write_bytes_fixed(w: Writer, b: bytes, length: int) -> int:
    ensure(len(b) == length)
    w.extend(b)
    return length
Example #17
0
def write_bytes_unchecked(w: Writer, b: Union[bytes, memoryview]) -> int:
    w.extend(b)
    return len(b)
Example #18
0
def write_bytes_unchecked(w: Writer, b: bytes) -> int:
    w.extend(b)
    return len(b)
Example #19
0
def write_string(w: Writer, string: bytes) -> None:
    write_header(w, len(string), STRING_HEADER_BYTE, string)
    w.extend(string)
Example #20
0
def write_bitcoin_varint(w: Writer, n: int) -> None:
    ensure(0 <= n <= 0xFFFF_FFFF)
    if n < 253:
        w.append(n & 0xFF)
    elif n < 0x1_0000:
        w.append(253)
        w.append(n & 0xFF)
        w.append((n >> 8) & 0xFF)
    else:
        w.append(254)
        w.append(n & 0xFF)
        w.append((n >> 8) & 0xFF)
        w.append((n >> 16) & 0xFF)
        w.append((n >> 24) & 0xFF)