last commit before i tear everything down
This commit is contained in:
		
							
								
								
									
										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 {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user