generate: Decode arrays (but don't validate their length yet)
This commit is contained in:
parent
7dcfc08678
commit
2cbf58d558
@ -555,17 +555,88 @@ func (this *Generator) generateDecodeBranch(hash [16]byte, typ Type) (n int, err
|
||||
n += nn; if err != nil { return n, err }
|
||||
nn, err = this.printf(" decoder *tape.Decoder, tag tape.Tag) (nn int, err error) \n{")
|
||||
n += nn; if err != nil { return n, err }
|
||||
this.push()
|
||||
|
||||
nn, err = this.iprintf("var nn int\n")
|
||||
n += nn; if err != nil { return n, err }
|
||||
|
||||
switch typ := typ.(type) {
|
||||
case TypeArray:
|
||||
// OTA: <length: UN> <elementTag: tape.Tag> <values>*
|
||||
// read header
|
||||
lengthVar := this.newTemporaryVar("length")
|
||||
nn, err := this.iprintf("var %s uint64\n", lengthVar)
|
||||
n += nn; if err != nil { return n, err }
|
||||
nn, err = this.iprintf("%s, nn, err = decoder.ReadUintN(int(tag.CN()))\n", lengthVar)
|
||||
n += nn; if err != nil { return n, err }
|
||||
nn, err = this.generateErrorCheck()
|
||||
n += nn; if err != nil { return n, err }
|
||||
elementTagVar := this.newTemporaryVar("elementTag")
|
||||
nn, err = this.iprintf("var %s uint64\n", lengthVar)
|
||||
n += nn; if err != nil { return n, err }
|
||||
nn, err = this.iprintf("%s, nn, err = decoder.ReadTag()\n", elementTagVar)
|
||||
n += nn; if err != nil { return n, err }
|
||||
nn, err = this.generateErrorCheck()
|
||||
n += nn; if err != nil { return n, err }
|
||||
|
||||
// abort macro
|
||||
abort := func() (n int, err error) {
|
||||
// skim entire array
|
||||
nn, err = this.iprintf("for _ = range %s {\n", lengthVar)
|
||||
n += nn; if err != nil { return n, err }
|
||||
this.push()
|
||||
nn, err = this.iprintf("nn, err = tape.Skim(decoder, tag)")
|
||||
n += nn; if err != nil { return n, err }
|
||||
nn, err = this.generateErrorCheck()
|
||||
n += nn; if err != nil { return n, err }
|
||||
this.pop()
|
||||
nn, err = this.iprintf("}\n")
|
||||
n += nn; if err != nil { return n, err }
|
||||
nn, err = this.iprintf("return n, nil")
|
||||
n += nn; if err != nil { return n, err }
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// validate header
|
||||
// TODO: here, validate that length is less than the
|
||||
// max, whatever that is configured to be. the reason we
|
||||
// want to read it here is that we would have to skip
|
||||
// the tag anyway so why not.
|
||||
nn, err = this.iprintf("if %s != ", elementTagVar)
|
||||
n += nn; if err != nil { return n, err }
|
||||
nn, err = this.generateTag(typ.Element, "(*this)")
|
||||
n += nn; if err != nil { return n, err }
|
||||
nn, err = this.printf(" {\n")
|
||||
n += nn; if err != nil { return n, err }
|
||||
this.push()
|
||||
nn, err = abort()
|
||||
n += nn; if err != nil { return n, err }
|
||||
this.pop()
|
||||
nn, err = this.iprintf("}\n")
|
||||
n += nn; if err != nil { return n, err }
|
||||
|
||||
// decode payloads
|
||||
nn, err = this.iprintf("*this = make(")
|
||||
n += nn; if err != nil { return n, err }
|
||||
nn, err = this.generateType(typ)
|
||||
n += nn; if err != nil { return n, err }
|
||||
nn, err = this.printf(", %s)\n", lengthVar)
|
||||
n += nn; if err != nil { return n, err }
|
||||
nn, err = this.iprintf("for index := range %s {\n", lengthVar)
|
||||
n += nn; if err != nil { return n, err }
|
||||
this.push()
|
||||
nn, err = this.generateDecodeValue(typ.Element, "(*this)[index]", elementTagVar)
|
||||
n += nn; if err != nil { return n, err }
|
||||
this.pop()
|
||||
nn, err = this.iprintf("}\n")
|
||||
n += nn; if err != nil { return n, err }
|
||||
case TypeTableDefined:
|
||||
// KTV: <length: UN> (<key: U16> <tag: Tag> <value>)*
|
||||
// TODO
|
||||
default: return n, fmt.Errorf("unexpected type: %T", typ)
|
||||
}
|
||||
|
||||
this.pop()
|
||||
nn, err = this.iprintf("}")
|
||||
n += nn; if err != nil { return n, err }
|
||||
return n, nil
|
||||
|
Loading…
x
Reference in New Issue
Block a user