serial.py 2.6 KB

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