aboutsummaryrefslogtreecommitdiff
path: root/nexgb/xgbgen/go_list.go
diff options
context:
space:
mode:
authorPřemysl Janouch <p@janouch.name>2018-09-08 16:54:17 +0200
committerPřemysl Janouch <p@janouch.name>2018-09-08 16:54:17 +0200
commit3173202cc1e08762c6e156a8fffd23269a5ddb2b (patch)
tree95c4a06f8384d41b15e9c22afac0a387de79dc51 /nexgb/xgbgen/go_list.go
parent632b3ae494d45755525644fe5d04475c95aae364 (diff)
parent3906399e7c2a40fbaf355de572cf50a314083f64 (diff)
downloadhaven-3173202cc1e08762c6e156a8fffd23269a5ddb2b.tar.gz
haven-3173202cc1e08762c6e156a8fffd23269a5ddb2b.tar.xz
haven-3173202cc1e08762c6e156a8fffd23269a5ddb2b.zip
Merge aarzilli/xgb, branch xcb1.12 as nexgb
History has been linearized and rewritten to stay under the new subdirectory. I want to make changes incompatible to BurntSushi/xgb. The history begs for being thrown away entirely because of its quality and because it doesn't cover the Google period but it is still useful for copyright tracking.
Diffstat (limited to 'nexgb/xgbgen/go_list.go')
-rw-r--r--nexgb/xgbgen/go_list.go107
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)
+ }
+}