serial.py 2.4 KB

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