aboutsummaryrefslogtreecommitdiff
path: root/nexgb/xgbgen/go_single_field.go
diff options
context:
space:
mode:
Diffstat (limited to 'nexgb/xgbgen/go_single_field.go')
-rw-r--r--nexgb/xgbgen/go_single_field.go166
1 files changed, 166 insertions, 0 deletions
diff --git a/nexgb/xgbgen/go_single_field.go b/nexgb/xgbgen/go_single_field.go
new file mode 100644
index 0000000..6c7218e
--- /dev/null
+++ b/nexgb/xgbgen/go_single_field.go
@@ -0,0 +1,166 @@
+package main
+
+import (
+ "fmt"
+ "log"
+)
+
+func (f *SingleField) Define(c *Context) {
+ c.Putln("%s %s", f.SrcName(), f.Type.SrcName())
+}
+
+func ReadSimpleSingleField(c *Context, name string, typ Type) {
+ switch t := typ.(type) {
+ case *Resource:
+ c.Putln("%s = %s(xgb.Get32(buf[b:]))", name, t.SrcName())
+ case *TypeDef:
+ switch t.Size().Eval() {
+ case 1:
+ c.Putln("%s = %s(buf[b])", name, t.SrcName())
+ case 2:
+ c.Putln("%s = %s(xgb.Get16(buf[b:]))", name, t.SrcName())
+ case 4:
+ c.Putln("%s = %s(xgb.Get32(buf[b:]))", name, t.SrcName())
+ case 8:
+ c.Putln("%s = %s(xgb.Get64(buf[b:]))", name, t.SrcName())
+ }
+ case *Base:
+ // If this is a bool, stop short and do something special.
+ if t.SrcName() == "bool" {
+ c.Putln("if buf[b] == 1 {")
+ c.Putln("%s = true", name)
+ c.Putln("} else {")
+ c.Putln("%s = false", name)
+ c.Putln("}")
+ break
+ }
+
+ var val string
+ switch t.Size().Eval() {
+ case 1:
+ val = fmt.Sprintf("buf[b]")
+ case 2:
+ val = fmt.Sprintf("xgb.Get16(buf[b:])")
+ case 4:
+ val = fmt.Sprintf("xgb.Get32(buf[b:])")
+ case 8:
+ val = fmt.Sprintf("xgb.Get64(buf[b:])")
+ }
+
+ // We need to convert base types if they aren't uintXX or byte
+ ty := t.SrcName()
+ if ty != "byte" && ty != "uint16" && ty != "uint32" && ty != "uint64" {
+ val = fmt.Sprintf("%s(%s)", ty, val)
+ }
+ c.Putln("%s = %s", name, val)
+ default:
+ log.Panicf("Cannot read field '%s' as a simple field with %T type.",
+ name, typ)
+ }
+
+ c.Putln("b += %s", typ.Size())
+}
+
+func (f *SingleField) Read(c *Context, prefix string) {
+ switch t := f.Type.(type) {
+ case *Resource:
+ ReadSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t)
+ case *TypeDef:
+ ReadSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t)
+ case *Base:
+ ReadSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t)
+ case *Struct:
+ c.Putln("%s%s = %s{}", prefix, f.SrcName(), t.SrcName())
+ c.Putln("b += %sRead(buf[b:], &%s%s)", t.SrcName(), prefix, f.SrcName())
+ case *Union:
+ c.Putln("%s%s = %s{}", prefix, f.SrcName(), t.SrcName())
+ c.Putln("b += %sRead(buf[b:], &%s%s)", t.SrcName(), prefix, f.SrcName())
+ default:
+ log.Panicf("Cannot read field '%s' with %T type.", f.XmlName(), f.Type)
+ }
+}
+
+func WriteSimpleSingleField(c *Context, name string, typ Type) {
+ switch t := typ.(type) {
+ case *Resource:
+ c.Putln("xgb.Put32(buf[b:], uint32(%s))", name)
+ case *TypeDef:
+ switch t.Size().Eval() {
+ case 1:
+ c.Putln("buf[b] = byte(%s)", name)
+ case 2:
+ c.Putln("xgb.Put16(buf[b:], uint16(%s))", name)
+ case 4:
+ c.Putln("xgb.Put32(buf[b:], uint32(%s))", name)
+ case 8:
+ c.Putln("xgb.Put64(buf[b:], uint64(%s))", name)
+ }
+ case *Base:
+ // If this is a bool, stop short and do something special.
+ if t.SrcName() == "bool" {
+ c.Putln("if %s {", name)
+ c.Putln("buf[b] = 1")
+ c.Putln("} else {")
+ c.Putln("buf[b] = 0")
+ c.Putln("}")
+ break
+ }
+
+ switch t.Size().Eval() {
+ case 1:
+ if t.SrcName() != "byte" {
+ c.Putln("buf[b] = byte(%s)", name)
+ } else {
+ c.Putln("buf[b] = %s", name)
+ }
+ case 2:
+ if t.SrcName() != "uint16" {
+ c.Putln("xgb.Put16(buf[b:], uint16(%s))", name)
+ } else {
+ c.Putln("xgb.Put16(buf[b:], %s)", name)
+ }
+ case 4:
+ if t.SrcName() != "uint32" {
+ c.Putln("xgb.Put32(buf[b:], uint32(%s))", name)
+ } else {
+ c.Putln("xgb.Put32(buf[b:], %s)", name)
+ }
+ case 8:
+ if t.SrcName() != "uint64" {
+ c.Putln("xgb.Put64(buf[b:], uint64(%s))", name)
+ } else {
+ c.Putln("xgb.Put64(buf[b:], %s)", name)
+ }
+ }
+ default:
+ log.Fatalf("Cannot read field '%s' as a simple field with %T type.",
+ name, typ)
+ }
+
+ c.Putln("b += %s", typ.Size())
+}
+
+func (f *SingleField) Write(c *Context, prefix string) {
+ switch t := f.Type.(type) {
+ case *Resource:
+ WriteSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t)
+ case *TypeDef:
+ WriteSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t)
+ case *Base:
+ WriteSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t)
+ case *Union:
+ c.Putln("{")
+ c.Putln("unionBytes := %s%s.Bytes()", prefix, f.SrcName())
+ c.Putln("copy(buf[b:], unionBytes)")
+ c.Putln("b += len(unionBytes)")
+ c.Putln("}")
+ case *Struct:
+ c.Putln("{")
+ c.Putln("structBytes := %s%s.Bytes()", prefix, f.SrcName())
+ c.Putln("copy(buf[b:], structBytes)")
+ c.Putln("b += len(structBytes)")
+ c.Putln("}")
+ default:
+ log.Fatalf("Cannot read field '%s' with %T type.", f.XmlName(), f.Type)
+ }
+}