#!/usr/bin/python3 # -*- coding: utf-8 -*- import struct import copy from collections import OrderedDict def safe_cast(val, to_type, default=None): try: return to_type(val) except (ValueError, TypeError): return default def listToInt(a, signed=False): res = 0 for x in reversed(a): res = res * 256 + x if signed and res >= 256 ** len(a) / 2: res -= 256 ** len(a) return res def listToDouble(a): return struct.unpack('d', a)[0] def listToFloat(a): return struct.unpack('f', a)[0] def listToVector(a, double=True): if double: return struct.unpack('ddd', a) else: return struct.unpack('iii', a) def listToVector_Uint(a): return struct.unpack('iii', a) def getSettings(set, name, default=None): val = set.value(name) if val == None: return default return val class PktParser(): def __init__(self, struct, offset=0): self.props = OrderedDict() for line in struct.splitlines(): prop = self._getInfo(line) if prop: length, cb, name = prop #print("{:4d} {:2d} {}".format(offset, length, name)) self.props[name] = lambda data, c=cb, o=offset, l=length: c(data[o:o+l]) offset += length self.end = offset self.offset = offset def _getInfo(self, line): i = 0 type = None name = None for word in line.split(): if word == "": #print("(empty)") continue if word[:2] in ["//", "/*"]: #print(word) break if word == "struct": continue if i == 0: #type type = self._getType(word) if type: i += 1 continue if i == 1: #name p = word.find(";") name = word[:p] if type and name: return type + (name,) def _getType(self, name): if name == "uint32_t": return (4, listToInt) if name == "int32_t": return (4, lambda v: listToInt(v, True)) if name == "float": return (4, listToFloat) if name == "double": return (8, listToDouble) if name == "vector_Uint": return (12, listToVector_Uint) if name == "vector": return (24, listToVector) print("Type {} invalid".format(name)) return None def parse(self, data): if len(data) < self.end: print("data too short {} < {}".format(len(data), self.end)) return ret = OrderedDict() for prop in self.props.keys(): ret[prop] = self.props[prop](data) d = {} for key in ret: if type(ret[key]) is tuple: d.update(dict(zip((key+"_x",key+"_y",key+"_z"), ret[key]))) ret.update(d) return ret def keys(self): tmp = b'\x00' * self.end return self.parse(tmp).keys() def confirm(prompt=None, resp=False): if prompt is None: prompt = 'Confirm' if resp: prompt = '%s [%s]|%s: ' % (prompt, 'y', 'n') else: prompt = '%s [%s]|%s: ' % (prompt, 'n', 'y') while True: ans = raw_input(prompt) if not ans: return resp if ans not in ['y', 'Y', 'n', 'N']: print ('please enter y or n.') continue if ans == 'y' or ans == 'Y': return True if ans == 'n' or ans == 'N': return False