github.com/robotn/xgb@v0.0.0-20190912153532-2cb92d044934/xgbgen/go_single_field.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "log" 6 ) 7 8 func (f *SingleField) Define(c *Context) { 9 c.Putln("%s %s", f.SrcName(), f.Type.SrcName()) 10 } 11 12 func ReadSimpleSingleField(c *Context, name string, typ Type) { 13 switch t := typ.(type) { 14 case *Resource: 15 c.Putln("%s = %s(xgb.Get32(buf[b:]))", name, t.SrcName()) 16 case *TypeDef: 17 switch t.Size().Eval() { 18 case 1: 19 c.Putln("%s = %s(buf[b])", name, t.SrcName()) 20 case 2: 21 c.Putln("%s = %s(xgb.Get16(buf[b:]))", name, t.SrcName()) 22 case 4: 23 c.Putln("%s = %s(xgb.Get32(buf[b:]))", name, t.SrcName()) 24 case 8: 25 c.Putln("%s = %s(xgb.Get64(buf[b:]))", name, t.SrcName()) 26 } 27 case *Base: 28 // If this is a bool, stop short and do something special. 29 if t.SrcName() == "bool" { 30 c.Putln("if buf[b] == 1 {") 31 c.Putln("%s = true", name) 32 c.Putln("} else {") 33 c.Putln("%s = false", name) 34 c.Putln("}") 35 break 36 } 37 38 var val string 39 switch t.Size().Eval() { 40 case 1: 41 val = fmt.Sprintf("buf[b]") 42 case 2: 43 val = fmt.Sprintf("xgb.Get16(buf[b:])") 44 case 4: 45 val = fmt.Sprintf("xgb.Get32(buf[b:])") 46 case 8: 47 val = fmt.Sprintf("xgb.Get64(buf[b:])") 48 } 49 50 // We need to convert base types if they aren't uintXX or byte 51 ty := t.SrcName() 52 if ty != "byte" && ty != "uint16" && ty != "uint32" && ty != "uint64" { 53 val = fmt.Sprintf("%s(%s)", ty, val) 54 } 55 c.Putln("%s = %s", name, val) 56 default: 57 log.Panicf("Cannot read field '%s' as a simple field with %T type.", 58 name, typ) 59 } 60 61 c.Putln("b += %s", typ.Size()) 62 } 63 64 func (f *SingleField) Read(c *Context, prefix string) { 65 switch t := f.Type.(type) { 66 case *Resource: 67 ReadSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t) 68 case *TypeDef: 69 ReadSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t) 70 case *Base: 71 ReadSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t) 72 case *Struct: 73 c.Putln("%s%s = %s{}", prefix, f.SrcName(), t.SrcName()) 74 c.Putln("b += %sRead(buf[b:], &%s%s)", t.SrcName(), prefix, f.SrcName()) 75 case *Union: 76 c.Putln("%s%s = %s{}", prefix, f.SrcName(), t.SrcName()) 77 c.Putln("b += %sRead(buf[b:], &%s%s)", t.SrcName(), prefix, f.SrcName()) 78 default: 79 log.Panicf("Cannot read field '%s' with %T type.", f.XmlName(), f.Type) 80 } 81 } 82 83 func WriteSimpleSingleField(c *Context, name string, typ Type) { 84 switch t := typ.(type) { 85 case *Resource: 86 c.Putln("xgb.Put32(buf[b:], uint32(%s))", name) 87 case *TypeDef: 88 switch t.Size().Eval() { 89 case 1: 90 c.Putln("buf[b] = byte(%s)", name) 91 case 2: 92 c.Putln("xgb.Put16(buf[b:], uint16(%s))", name) 93 case 4: 94 c.Putln("xgb.Put32(buf[b:], uint32(%s))", name) 95 case 8: 96 c.Putln("xgb.Put64(buf[b:], uint64(%s))", name) 97 } 98 case *Base: 99 // If this is a bool, stop short and do something special. 100 if t.SrcName() == "bool" { 101 c.Putln("if %s {", name) 102 c.Putln("buf[b] = 1") 103 c.Putln("} else {") 104 c.Putln("buf[b] = 0") 105 c.Putln("}") 106 break 107 } 108 109 switch t.Size().Eval() { 110 case 1: 111 if t.SrcName() != "byte" { 112 c.Putln("buf[b] = byte(%s)", name) 113 } else { 114 c.Putln("buf[b] = %s", name) 115 } 116 case 2: 117 if t.SrcName() != "uint16" { 118 c.Putln("xgb.Put16(buf[b:], uint16(%s))", name) 119 } else { 120 c.Putln("xgb.Put16(buf[b:], %s)", name) 121 } 122 case 4: 123 if t.SrcName() != "uint32" { 124 c.Putln("xgb.Put32(buf[b:], uint32(%s))", name) 125 } else { 126 c.Putln("xgb.Put32(buf[b:], %s)", name) 127 } 128 case 8: 129 if t.SrcName() != "uint64" { 130 c.Putln("xgb.Put64(buf[b:], uint64(%s))", name) 131 } else { 132 c.Putln("xgb.Put64(buf[b:], %s)", name) 133 } 134 } 135 default: 136 log.Fatalf("Cannot read field '%s' as a simple field with %T type.", 137 name, typ) 138 } 139 140 c.Putln("b += %s", typ.Size()) 141 } 142 143 func (f *SingleField) Write(c *Context, prefix string) { 144 switch t := f.Type.(type) { 145 case *Resource: 146 WriteSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t) 147 case *TypeDef: 148 WriteSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t) 149 case *Base: 150 WriteSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t) 151 case *Union: 152 c.Putln("{") 153 c.Putln("unionBytes := %s%s.Bytes()", prefix, f.SrcName()) 154 c.Putln("copy(buf[b:], unionBytes)") 155 c.Putln("b += len(unionBytes)") 156 c.Putln("}") 157 case *Struct: 158 c.Putln("{") 159 c.Putln("structBytes := %s%s.Bytes()", prefix, f.SrcName()) 160 c.Putln("copy(buf[b:], structBytes)") 161 c.Putln("b += len(structBytes)") 162 c.Putln("}") 163 default: 164 log.Fatalf("Cannot read field '%s' with %T type.", f.XmlName(), f.Type) 165 } 166 }