diff options
Diffstat (limited to 'nexgb/xgbgen/go_list.go')
-rw-r--r-- | nexgb/xgbgen/go_list.go | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/nexgb/xgbgen/go_list.go b/nexgb/xgbgen/go_list.go new file mode 100644 index 0000000..1e85d9f --- /dev/null +++ b/nexgb/xgbgen/go_list.go @@ -0,0 +1,107 @@ +package main + +import ( + "fmt" + "log" + "strings" +) + +// List fields +func (f *ListField) Define(c *Context) { + c.Putln("%s %s // size: %s", + f.SrcName(), f.SrcType(), f.Size()) +} + +func (f *ListField) Read(c *Context, prefix string) { + switch t := f.Type.(type) { + case *Resource: + length := f.LengthExpr.Reduce(prefix) + c.Putln("%s%s = make([]%s, %s)", + prefix, f.SrcName(), t.SrcName(), length) + c.Putln("for i := 0; i < int(%s); i++ {", length) + ReadSimpleSingleField(c, fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) + c.Putln("}") + case *Base: + length := f.LengthExpr.Reduce(prefix) + if strings.ToLower(t.XmlName()) == "char" { + c.Putln("{") + c.Putln("byteString := make([]%s, %s)", t.SrcName(), length) + c.Putln("copy(byteString[:%s], buf[b:])", length) + c.Putln("%s%s = string(byteString)", prefix, f.SrcName()) + // This is apparently a special case. The "Str" type itself + // doesn't specify any padding. I suppose it's up to the + // request/reply spec that uses it to get the padding right? + c.Putln("b += int(%s)", length) + c.Putln("}") + } else if t.SrcName() == "byte" { + c.Putln("%s%s = make([]%s, %s)", + prefix, f.SrcName(), t.SrcName(), length) + c.Putln("copy(%s%s[:%s], buf[b:])", prefix, f.SrcName(), length) + c.Putln("b += int(%s)", length) + } else { + c.Putln("%s%s = make([]%s, %s)", + prefix, f.SrcName(), t.SrcName(), length) + c.Putln("for i := 0; i < int(%s); i++ {", length) + ReadSimpleSingleField(c, + fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) + c.Putln("}") + } + case *TypeDef: + length := f.LengthExpr.Reduce(prefix) + c.Putln("%s%s = make([]%s, %s)", + prefix, f.SrcName(), t.SrcName(), length) + c.Putln("for i := 0; i < int(%s); i++ {", length) + ReadSimpleSingleField(c, fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) + c.Putln("}") + case *Union: + c.Putln("%s%s = make([]%s, %s)", + prefix, f.SrcName(), t.SrcName(), f.LengthExpr.Reduce(prefix)) + c.Putln("b += %sReadList(buf[b:], %s%s)", + t.SrcName(), prefix, f.SrcName()) + case *Struct: + c.Putln("%s%s = make([]%s, %s)", + prefix, f.SrcName(), t.SrcName(), f.LengthExpr.Reduce(prefix)) + c.Putln("b += %sReadList(buf[b:], %s%s)", + t.SrcName(), prefix, f.SrcName()) + default: + log.Panicf("Cannot read list field '%s' with %T type.", + f.XmlName(), f.Type) + } +} + +func (f *ListField) Write(c *Context, prefix string) { + switch t := f.Type.(type) { + case *Resource: + length := f.Length().Reduce(prefix) + c.Putln("for i := 0; i < int(%s); i++ {", length) + WriteSimpleSingleField(c, + fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) + c.Putln("}") + case *Base: + length := f.Length().Reduce(prefix) + if t.SrcName() == "byte" { + c.Putln("copy(buf[b:], %s%s[:%s])", prefix, f.SrcName(), length) + c.Putln("b += int(%s)", length) + } else { + c.Putln("for i := 0; i < int(%s); i++ {", length) + WriteSimpleSingleField(c, + fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) + c.Putln("}") + } + case *TypeDef: + length := f.Length().Reduce(prefix) + c.Putln("for i := 0; i < int(%s); i++ {", length) + WriteSimpleSingleField(c, + fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) + c.Putln("}") + case *Union: + c.Putln("b += %sListBytes(buf[b:], %s%s)", + t.SrcName(), prefix, f.SrcName()) + case *Struct: + c.Putln("b += %sListBytes(buf[b:], %s%s)", + t.SrcName(), prefix, f.SrcName()) + default: + log.Panicf("Cannot write list field '%s' with %T type.", + f.XmlName(), f.Type) + } +} |