last commit before i tear everything down
This commit is contained in:
parent
6bf0191fb0
commit
3115c13e88
2
nexgb/.gitignore
vendored
2
nexgb/.gitignore
vendored
@ -1,2 +1,2 @@
|
||||
xgbgen
|
||||
xgbgen/xgbgen
|
||||
.*.swp
|
||||
|
13
nexgb/xgbgen/COPYING
Normal file
13
nexgb/xgbgen/COPYING
Normal file
@ -0,0 +1,13 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
15
nexgb/xgbgen/bufcount.go
Normal file
15
nexgb/xgbgen/bufcount.go
Normal file
@ -0,0 +1,15 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
A buffer count is a mechanism by which to keep track of which byte one
|
||||
is reading or writing to/from the wire.
|
||||
|
||||
It's an abstraction over the fact that while such a counter is usually
|
||||
fixed, it can be made variable based on values at run-time.
|
||||
*/
|
||||
|
||||
type BufCount struct {
|
||||
Fixed int
|
||||
Exprs []*Expression
|
||||
}
|
||||
|
@ -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)
|
||||
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(")")
|
||||
}
|
||||
c.Putln("")
|
||||
|
||||
consumed = size
|
||||
nextByte = field.MorphReadField(c, kind, nextByte, prefix)
|
||||
case "list":
|
||||
c.Putln("")
|
||||
typ := field.Type.Morph(c)
|
||||
|
||||
// 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!")
|
||||
}
|
||||
}
|
||||
return byt + consumed
|
||||
return nextByte
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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("")
|
||||
|
@ -166,6 +166,48 @@ type Name string
|
||||
|
||||
type Type string
|
||||
|
||||
// Union returns the 'Union' struct corresponding to this type, if
|
||||
// one exists.
|
||||
func (typ Type) Union(c *Context) *Union {
|
||||
// If this is a typedef, use that instead.
|
||||
if oldTyp, ok := typ.TypeDef(c); ok {
|
||||
return oldTyp.Union(c)
|
||||
}
|
||||
|
||||
// Otherwise, just look for a union type with 'typ' name.
|
||||
for _, union := range c.xml.Unions {
|
||||
if typ == union.Name {
|
||||
return union
|
||||
}
|
||||
}
|
||||
for _, imp := range c.xml.Imports {
|
||||
for _, union := range imp.xml.Unions {
|
||||
if typ == union.Name {
|
||||
return union
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TypeDef returns the 'old' type corresponding to this type, if it's found
|
||||
// in a type def. If not found, the second return value is false.
|
||||
func (typ Type) TypeDef(c *Context) (Type, bool) {
|
||||
for _, typedef := range c.xml.TypeDefs {
|
||||
if typ == typedef.New {
|
||||
return typedef.Old, true
|
||||
}
|
||||
}
|
||||
for _, imp := range c.xml.Imports {
|
||||
for _, typedef := range imp.xml.TypeDefs {
|
||||
if typ == typedef.New {
|
||||
return typedef.Old, true
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Size is a nifty function that takes any type and digs until it finds
|
||||
// its underlying base type. At which point, the size can be determined.
|
||||
func (typ Type) Size(c *Context) uint {
|
||||
|
Loading…
Reference in New Issue
Block a user