diff options
Diffstat (limited to 'nexgb/xgbgen/go.go')
-rw-r--r-- | nexgb/xgbgen/go.go | 102 |
1 files changed, 65 insertions, 37 deletions
diff --git a/nexgb/xgbgen/go.go b/nexgb/xgbgen/go.go index bfc54dd..b939b3a 100644 --- a/nexgb/xgbgen/go.go +++ b/nexgb/xgbgen/go.go @@ -23,6 +23,7 @@ package main */ import ( + "fmt" "log" "strings" ) @@ -214,16 +215,12 @@ func (bitcase *Bitcase) MorphDefine(c *Context) { bitcase.Fields.MorphDefine(c) } -func (fields Fields) MorphRead(c *Context, kind int, evNoSeq bool) { - var nextByte uint - - switch kind { - case FieldsEvent: - nextByte = 1 - } +func (fields Fields) MorphRead(c *Context, kind int, evNoSeq bool, + prefix string, byt uint) uint { + nextByte := byt for _, field := range fields { - nextByte = field.MorphRead(c, kind, nextByte) + nextByte = field.MorphRead(c, kind, nextByte, prefix) switch kind { case FieldsEvent: // Skip the sequence id @@ -232,45 +229,76 @@ func (fields Fields) MorphRead(c *Context, kind int, evNoSeq bool) { } } } + return nextByte } -func (field *Field) MorphRead(c *Context, kind int, byt uint) uint { - consumed := uint(0) +func (field *Field) MorphRead(c *Context, kind int, byt uint, + prefix string) uint { + + nextByte := byt switch field.XMLName.Local { case "pad": - consumed = uint(field.Bytes) + nextByte += uint(field.Bytes) case "field": - if field.Type == "ClientMessageData" { - break - } - size := field.Type.Size(c) + nextByte = field.MorphReadField(c, kind, nextByte, prefix) + case "list": typ := field.Type.Morph(c) - name := field.Name.Morph(c) - _, isBase := BaseTypeMap[string(field.Type)] - c.Put("v.%s = ", name) - if !isBase { - c.Put("%s(", typ) - } - switch size { - case 1: c.Put("buf[%d]", byt) - case 2: c.Put("get16(buf[%d:])", byt) - case 4: c.Put("get32(buf[%d:])", byt) - case 8: c.Put("get64(buf[%d:])", byt) - default: - log.Fatalf("Unsupported field size '%d' for field '%s'.", - size, field) - } - if !isBase { - c.Put(")") + // Create a temporary Field so we can use MorphReadField. + // temp := &Field{ + // XMLName: xml.Name{Local: "field"}, + // Name: field.Name, + // Type: field.Type, + // } + + // Special case: if the list is just raw bytes, use copy! + if typ == "byte" { + c.Putln("copy(%s%s, buf[%d:])", prefix, field.Name.Morph(c), + byt) + nextByte = byt + 20 + } else { + c.Putln("//list!") } - c.Putln("") + } + return nextByte +} - consumed = size - case "list": +func (field *Field) MorphReadField(c *Context, kind int, byt uint, + prefix string) uint { + + if union := field.Type.Union(c); union != nil { c.Putln("") + c.Putln("%s%s = %s{}", prefix, field.Name.Morph(c), field.Type.Morph(c)) + union.Fields.MorphRead(c, kind, false, + fmt.Sprintf("%s%s.", prefix, field.Name.Morph(c)), byt) + c.Putln("") + return byt } - return byt + consumed + + size := field.Type.Size(c) + typ := field.Type.Morph(c) + name := field.Name.Morph(c) + _, isBase := BaseTypeMap[string(field.Type)] + + c.Put("%s%s = ", prefix, name) + if !isBase { + c.Put("%s(", typ) + } + switch size { + case 1: c.Put("buf[%d]", byt) + case 2: c.Put("get16(buf[%d:])", byt) + case 4: c.Put("get32(buf[%d:])", byt) + case 8: c.Put("get64(buf[%d:])", byt) + default: + log.Fatalf("Unsupported field size '%d' for field '%s'.", + size, field) + } + if !isBase { + c.Put(")") + } + c.Putln("") + + return byt + size } func (fields Fields) MorphWrite(c *Context, kind int) { @@ -377,7 +405,7 @@ func (ev *Event) Morph(c *Context) { c.Putln("") c.Putln("func New%s(buf []byte) %sEvent {", name, name) c.Putln("var v %sEvent", name) - ev.Fields.MorphRead(c, FieldsEvent, ev.NoSequence) + ev.Fields.MorphRead(c, FieldsEvent, ev.NoSequence, "v.", 1) c.Putln("return v") c.Putln("}") c.Putln("") |