serial.py 2.5 KB

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