last commit before i tear everything down

This commit is contained in:
Andrew Gallant (Ocelot) 2012-04-29 14:09:03 -04:00
parent 6bf0191fb0
commit 3115c13e88
5 changed files with 140 additions and 42 deletions

2
nexgb/.gitignore vendored
View File

@ -1,2 +1,2 @@
xgbgen
xgbgen/xgbgen
.*.swp

13
nexgb/xgbgen/COPYING Normal file
View 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
View 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
}

View File

@ -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("")

View File

@ -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 {