def __init__(self, buf): self.buffer = BufferIterator(StringBuffer(buf)) self.state = 0 self.stringIndex = [] self.objectLayoutIndex = []
class Parser(): def __init__(self, buf): self.buffer = BufferIterator(StringBuffer(buf)) self.state = 0 self.stringIndex = [] self.objectLayoutIndex = [] def setSpec(self, spec): self.spec = spec return self def readString(self): ret = "" while (True): char = self.buffer.readUInt8() if (char is 0): break ret += unichr(char) return ret def parseSI(self): self.stringIndexType = self.buffer.readUInt8() if self.stringIndexType is CHAR or self.stringIndexType is SHORT or self.stringIndexType is INT: stringCount = self.buffer.readValue(self.stringIndexType) elif self.stringIndexType is EMPTY: stringCount = 0 else: raise Exception('Invalid LEON.') i = 0 while i < stringCount: self.stringIndex.append(self.readString()) i += 1 self.state |= PARSED_SI return self def parseOLI(self): if len(self.stringIndex) is 0: return self self.OLItype = self.buffer.readUInt8() if self.OLItype is CHAR or self.OLItype is SHORT or self.OLItype is INT: count = self.buffer.readValue(self.OLItype) elif self.OLItype is EMPTY: return self else: raise Exception('Invalid LEON.') i = 0 while i < count: self.objectLayoutIndex.append([]) numFields = self.buffer.readValue(self.buffer.readUInt8()) j = 0 while j < numFields: self.objectLayoutIndex[i].append(self.buffer.readValue(self.stringIndexType)) j += 1 i += 1 return self def parseValueWithSpec(self, *args): if len(args) is 0: spec = self.spec else: spec = args[0] if spec is STRING: return self.readString() elif type(spec) is list: spec = spec[0] valtype = self.buffer.readUInt8() length = self.buffer.readValue(valtype) ret = [] i = 0 while i < length: ret.append(self.parseValueWithSpec(spec)) i += 1 return ret elif type(spec) is dict: ret = {} od = collections.OrderedDict(sorted(spec.items())) for prop in od.items(): ret[prop[0]] = self.parseValueWithSpec(spec[prop[0]]) return ret; elif spec is (TRUE & FALSE): return self.parseValue() else: return self.parseValue(spec) def parseValue(self, *args): if len(args) is 0: valtype = self.buffer.readUInt8() else: valtype = args[0] if valtype < OBJECT: return self.buffer.readValue(valtype) elif valtype is VARARRAY: valtype = self.buffer.readUInt8() length = self.buffer.readValue(valtype) ret = [] i = 0 while i < length: ret.append(self.parseValue()) i += 1 return ret elif valtype is OBJECT: index = self.objectLayoutIndex[self.buffer.readValue(self.OLItype)] ret = {} i = 0 while i < len(index): ret[self.stringIndex[index[i]]] = self.parseValue() i += 1 elif valtype is STRING: return self.stringIndex[self.buffer.readValue(self.stringIndexType)] elif valtype is UNDEFINED or valtype is NULL or valtype is NAN: return None elif valtype is TRUE: return True elif valtype is FALSE: return False elif valtype is DATE: return date.fromtimestamp(self.readValue(self.buffer.readUInt8())) elif valtype is REGEXP: return re.compile(self.readString()) else: raise Exception('Invalid LEON.') return ret