def _parse_std_schema(self, hexcode, strict): hexoffset = 0 binoffset = 0 if type(hexcode) == Hex: bc = hexcode else: bc = Hex(hexcode) if self.tag.startswith("bl-schema"): tag = "bl:"+self.tag.split(":")[1] else: tag = self.tag matched = Bytelet([tag,{},[],'']) for child in self.children(): if hexoffset>=len(bc): if strict: content = child._tree[-1] if isinstance(content, FlowFieldVal): content.set_node(child, matched) n = content.flow_value().num() if n == 0: continue else: n = child.hex().num() if n == 0: continue raise ByteletError("[01]: Schema too short. Field `%s` of ByteletSchema `%s` does not match any hexcode."%(child.tag, self.tag)) break content = child._tree[-1] if isinstance(content, FlowFieldVal): # print "MATCH FlowFieldVal" content.set_node(child, matched) n = content.flow_value().num() if strict and hexoffset+n>len(bc): raise ByteletError("[02]:Incorrect number of bytes for field `%s`. Expected `%s` bytes but `%s` bytes found."%(child.tag, n, hexoffset+n-len(bc))) (hexoffset, binoffset),v = bc.section(hexoffset, binoffset, n) matched._children.append(Bytelet([child.tag, {}, [], v], matched)) elif isinstance(content, FlowLen): # print "MATCH FlowLen" lgt = bc.byte(hexoffset, binoffset) if lgt & 0x80: lenlen = 1 + (lgt & 0x0F) (hexoffset, binoffset),v = bc.section(hexoffset, binoffset, lenlen.num()) else: v = lgt hexoffset+=1 # print "NEW HEXOFFSET", hexoffset # set new flow len value flen = copy(content) flen.set_flow_value(v) matched._children.append(Bytelet([child.tag, {}, [], flen], matched)) elif len(child._children)>0: # print "MATCH children" if not isinstance(child, ByteletSchema): child_schema = ByteletSchema(child._tree, child._parent) else: child_schema = child mi = child_schema.parse(bc.rest(hexoffset, binoffset), strict) # print "MATCHED", mi matched._children.append(mi) hexoffset+=len(mi) elif isinstance(content, Bin): # print "MATCH bits" n = content.num() #print "REST", bc[hexoffset:] (hexoffset, binoffset),v = bc.section(hexoffset, binoffset, n, bit = True) #print "V",v matched._children.append(Bytelet([child.tag, {"w":n}, [], v], matched)) elif isinstance(content, Hex): # print "MATCH HX exact" n = len(content) (hexoffset, binoffset), section = bc.section(hexoffset,binoffset,n) if strict and section != content: raise ByteletError("[03]:Expected content of field `%s` = `%s`. Received: `%s`."%(child.tag, content, section)) matched._children.append(Bytelet([child.tag, {}, [], content], matched)) else: # print "MATCH bytes" n = Hex(content).num() (hexoffset, binoffset),section = bc.section(hexoffset,binoffset,n) matched._children.append(Bytelet([child.tag, {}, [], section], matched)) if strict: n = hexoffset - len(bc) if n<0 and self._parent is None: n = len(bc) - hexoffset if binoffset: raise ByteletError("[041]: Schema too short. ByteletSchema `%s` did not scan %s bits of hexcode."%(self.tag, 8*n-binoffset)) else: raise ByteletError("[042]: Schema too short. ByteletSchema `%s` did not scan %s bytes of hexcode."%(self.tag,n)) elif n>0 or binoffset: if n>0: raise ByteletError("[051]: Schema too long. ByteletSchema `%s` specified %d bytes that did not match."%(self.tag, n)) else: raise ByteletError("[052]: Schema too long. ByteletSchema `%s` specified %d bits that did not match."%(self.tag, binoffset)) matched._remap() return matched