functions.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #!/usr/bin/python3
  2. # -*- coding: utf-8 -*-
  3. import struct
  4. import copy
  5. from collections import OrderedDict
  6. def safe_cast(val, to_type, default=None):
  7. try:
  8. return to_type(val)
  9. except (ValueError, TypeError):
  10. return default
  11. def listToInt(a, signed=False):
  12. res = 0
  13. for x in reversed(a):
  14. res = res * 256 + x
  15. if signed and res >= 256 ** len(a) / 2:
  16. res -= 256 ** len(a)
  17. return res
  18. def listToDouble(a):
  19. return struct.unpack('d', a)[0]
  20. def listToFloat(a):
  21. return struct.unpack('f', a)[0]
  22. def listToVector(a, double=True):
  23. if double:
  24. return struct.unpack('ddd', a)
  25. else:
  26. return struct.unpack('iii', a)
  27. def listToVector_Uint(a):
  28. return struct.unpack('iii', a)
  29. def getSettings(set, name, default=None):
  30. val = set.value(name)
  31. if val == None:
  32. return default
  33. return val
  34. class PktParser():
  35. def __init__(self, struct, offset=0):
  36. self.props = OrderedDict()
  37. for line in struct.splitlines():
  38. prop = self._getInfo(line)
  39. if prop:
  40. length, cb, name = prop
  41. #print("{:4d} {:2d} {}".format(offset, length, name))
  42. self.props[name] = lambda data, c=cb, o=offset, l=length: c(data[o:o+l])
  43. offset += length
  44. self.end = offset
  45. self.offset = offset
  46. def _getInfo(self, line):
  47. i = 0
  48. type = None
  49. name = None
  50. for word in line.split():
  51. if word == "":
  52. #print("(empty)")
  53. continue
  54. if word[:2] in ["//", "/*"]:
  55. #print(word)
  56. break
  57. if word == "struct":
  58. continue
  59. if i == 0: #type
  60. type = self._getType(word)
  61. if type:
  62. i += 1
  63. continue
  64. if i == 1: #name
  65. p = word.find(";")
  66. name = word[:p]
  67. if type and name:
  68. return type + (name,)
  69. def _getType(self, name):
  70. if name == "uint32_t":
  71. return (4, listToInt)
  72. if name == "int32_t":
  73. return (4, lambda v: listToInt(v, True))
  74. if name == "float":
  75. return (4, listToFloat)
  76. if name == "double":
  77. return (8, listToDouble)
  78. if name == "vector_Uint":
  79. return (12, listToVector_Uint)
  80. if name == "vector":
  81. return (24, listToVector)
  82. print("Type {} invalid".format(name))
  83. return None
  84. def parse(self, data):
  85. if len(data) < self.end:
  86. print("data too short {} < {}".format(len(data), self.end))
  87. return
  88. ret = OrderedDict()
  89. for prop in self.props.keys():
  90. ret[prop] = self.props[prop](data)
  91. d = {}
  92. for key in ret:
  93. if type(ret[key]) is tuple:
  94. d.update(dict(zip((key+"_x",key+"_y",key+"_z"), ret[key])))
  95. ret.update(d)
  96. return ret
  97. def keys(self):
  98. tmp = b'\x00' * self.end
  99. return self.parse(tmp).keys()
  100. def confirm(prompt=None, resp=False):
  101. if prompt is None:
  102. prompt = 'Confirm'
  103. if resp:
  104. prompt = '%s [%s]|%s: ' % (prompt, 'y', 'n')
  105. else:
  106. prompt = '%s [%s]|%s: ' % (prompt, 'n', 'y')
  107. while True:
  108. ans = raw_input(prompt)
  109. if not ans:
  110. return resp
  111. if ans not in ['y', 'Y', 'n', 'N']:
  112. print ('please enter y or n.')
  113. continue
  114. if ans == 'y' or ans == 'Y':
  115. return True
  116. if ans == 'n' or ans == 'N':
  117. return False