Exemple #1
0
    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