serial.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import struct
  2. def write_u8(by, v):
  3. assert v < 2**256
  4. by += v.to_bytes(1, 'little')
  5. def write_u16(by, v):
  6. assert v < 2**(2*256)
  7. by += v.to_bytes(2, 'little')
  8. def write_u32(by, v):
  9. assert v < 2**(4*256)
  10. by += v.to_bytes(4, 'little')
  11. def write_u64(by, v):
  12. assert v < 2**(8*256)
  13. by += v.to_bytes(8, 'little')
  14. def write_f32(by, v):
  15. by += struct.pack("<f", v)
  16. def encode_varint(by, v):
  17. if v <= 0xfc:
  18. write_u8(by, v)
  19. return 1
  20. elif v <= 0xffff:
  21. write_u8(by, 0xfd)
  22. write_u16(by, v)
  23. return 3
  24. elif v <= 0xffffffff:
  25. write_u8(by, 0xfe)
  26. write_u32(by, v)
  27. return 5
  28. else:
  29. write_u8(by, 0xff)
  30. write_u64(by, v)
  31. return 9
  32. def encode_str(by, s):
  33. l = 0
  34. l += encode_varint(by, len(s))
  35. s_by = s.encode("utf-8")
  36. l += len(s_by)
  37. by += s_by
  38. return l
  39. def encode_buf(by, buf):
  40. l = 0
  41. l += encode_varint(by, len(buf))
  42. l += len(buf)
  43. by += buf
  44. return l
  45. def encode_opt(by, val, write_fn):
  46. l = 0
  47. if val is None:
  48. write_u8(by, 0)
  49. else:
  50. write_u8(by, 1)
  51. write_fn(by)
  52. # Cursor for bytearray type
  53. class Cursor:
  54. def __init__(self, by):
  55. self.by = by
  56. self.i = 0
  57. def read(self, n):
  58. slice = self.by[self.i:self.i+n]
  59. self.i += n
  60. if self.i > len(self.by):
  61. raise Exception("invalid read")
  62. return slice
  63. def read_u8(cur):
  64. b = cur.read(1)
  65. return int.from_bytes(b, "little")
  66. def read_u16(cur):
  67. b = cur.read(2)
  68. return int.from_bytes(b, "little")
  69. def read_u32(cur):
  70. b = cur.read(4)
  71. return int.from_bytes(b, "little")
  72. def read_u64(cur):
  73. b = cur.read(8)
  74. return int.from_bytes(b, "little")
  75. def read_f32(cur):
  76. by = cur.read(4)
  77. return struct.unpack("<f", by)[0]
  78. def decode_varint(cur):
  79. n = read_u8(cur)
  80. match n:
  81. case 0xff:
  82. x = read_u64(cur)
  83. assert x >= 0x100000000
  84. return x
  85. case 0xfe:
  86. x = read_u32(cur)
  87. assert x >= 0x10000
  88. return x
  89. case 0xfd:
  90. x = read_u16(cur)
  91. assert x >= 0xfd
  92. return x
  93. return n
  94. def decode_str(cur):
  95. return decode_buf(cur).decode("utf-8")
  96. def decode_buf(cur):
  97. size = decode_varint(cur)
  98. return cur.read(size)
  99. def decode_opt(cur, read_fn):
  100. is_some = bool(read_u8(cur))
  101. if is_some:
  102. return read_fn(cur)
  103. else:
  104. return None
  105. def decode_arr(cur, read_fn):
  106. arr_len = decode_varint(cur)
  107. vals = []
  108. for _ in range(arr_len):
  109. vals.append(read_fn(cur))
  110. return vals