holy toldeo... things might actually be working
This commit is contained in:
		
							
								
								
									
										72
									
								
								nexgb/xgb.go
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								nexgb/xgb.go
									
									
									
									
									
								
							@@ -95,31 +95,20 @@ type Event interface {
 | 
			
		||||
 | 
			
		||||
// newEventFuncs is a map from event numbers to functions that create
 | 
			
		||||
// the corresponding event.
 | 
			
		||||
var newEventFuncs map[int]func(buf []byte) Event
 | 
			
		||||
var newEventFuncs = map[int]func(buf []byte) Event{}
 | 
			
		||||
 | 
			
		||||
// Error contains protocol errors returned to us by the X server.
 | 
			
		||||
type Error struct {
 | 
			
		||||
	Detail uint8
 | 
			
		||||
	Major  uint8
 | 
			
		||||
	Minor  uint16
 | 
			
		||||
	Cookie uint16
 | 
			
		||||
	Id     Id
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Error2 is an interface that can contain any of the errors returned by
 | 
			
		||||
// Error is an interface that can contain any of the errors returned by
 | 
			
		||||
// the server. Use a type assertion switch to extract the Error structs.
 | 
			
		||||
type Error2 interface {
 | 
			
		||||
type Error interface {
 | 
			
		||||
	ImplementsError()
 | 
			
		||||
	SequenceId() uint16
 | 
			
		||||
	BadId() Id
 | 
			
		||||
	Error() string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// newErrorFuncs is a map from error numbers to functions that create
 | 
			
		||||
// the corresponding error.
 | 
			
		||||
var newErrorFuncs map[int]func(buf []byte) Error2
 | 
			
		||||
 | 
			
		||||
func (e *Error) Error() string {
 | 
			
		||||
	return fmt.Sprintf("Bad%s (major=%d minor=%d cookie=%d id=0x%x)",
 | 
			
		||||
		errorNames[e.Detail], e.Major, e.Minor, e.Cookie, e.Id)
 | 
			
		||||
}
 | 
			
		||||
var newErrorFuncs = map[int]func(buf []byte) Error{}
 | 
			
		||||
 | 
			
		||||
// NewID generates a new unused ID for use with requests like CreateWindow.
 | 
			
		||||
func (c *Conn) NewId() Id {
 | 
			
		||||
@@ -136,7 +125,7 @@ func (c *Conn) NewId() Id {
 | 
			
		||||
// the extensions map.
 | 
			
		||||
func (c *Conn) RegisterExtension(name string) error {
 | 
			
		||||
	nameUpper := strings.ToUpper(name)
 | 
			
		||||
	reply, err := c.QueryExtension(nameUpper)
 | 
			
		||||
	reply, err := c.QueryExtension(uint16(len(nameUpper)), nameUpper)
 | 
			
		||||
 | 
			
		||||
	switch {
 | 
			
		||||
	case err != nil:
 | 
			
		||||
@@ -253,25 +242,26 @@ func (c *Conn) newReadChannels() {
 | 
			
		||||
 | 
			
		||||
			switch buf[0] {
 | 
			
		||||
			case 0:
 | 
			
		||||
				err := &Error{
 | 
			
		||||
					Detail: buf[1],
 | 
			
		||||
					Cookie: uint16(get16(buf[2:])),
 | 
			
		||||
					Id:     Id(get32(buf[4:])),
 | 
			
		||||
					Minor:  get16(buf[8:]),
 | 
			
		||||
					Major:  buf[10],
 | 
			
		||||
				}
 | 
			
		||||
				if cookie, ok := c.cookies[err.Cookie]; ok {
 | 
			
		||||
				// err := &Error{ 
 | 
			
		||||
					// Detail: buf[1], 
 | 
			
		||||
					// Cookie: uint16(get16(buf[2:])), 
 | 
			
		||||
					// Id:     Id(get32(buf[4:])), 
 | 
			
		||||
					// Minor:  get16(buf[8:]), 
 | 
			
		||||
					// Major:  buf[10], 
 | 
			
		||||
				// } 
 | 
			
		||||
				err := newErrorFuncs[int(buf[1])](buf)
 | 
			
		||||
				if cookie, ok := c.cookies[err.SequenceId()]; ok {
 | 
			
		||||
					cookie.errorChan <- err
 | 
			
		||||
				} else {
 | 
			
		||||
					fmt.Fprintf(os.Stderr, "x protocol error: %s\n", err)
 | 
			
		||||
				}
 | 
			
		||||
			case 1:
 | 
			
		||||
				seq := uint16(get16(buf[2:]))
 | 
			
		||||
				seq := uint16(Get16(buf[2:]))
 | 
			
		||||
				if _, ok := c.cookies[seq]; !ok {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				size := get32(buf[4:])
 | 
			
		||||
				size := Get32(buf[4:])
 | 
			
		||||
				if size > 0 {
 | 
			
		||||
					bigbuf := make([]byte, 32+size*4, 32+size*4)
 | 
			
		||||
					copy(bigbuf[0:32], buf)
 | 
			
		||||
@@ -317,7 +307,8 @@ func (c *Conn) waitForReply(cookie *Cookie) ([]byte, error) {
 | 
			
		||||
func (c *Conn) WaitForEvent() (Event, error) {
 | 
			
		||||
	for {
 | 
			
		||||
		if reply := c.events.dequeue(c); reply != nil {
 | 
			
		||||
			return parseEvent(reply)
 | 
			
		||||
			evCode := reply[0] & 0x7f
 | 
			
		||||
			return newEventFuncs[int(evCode)](reply), nil
 | 
			
		||||
		}
 | 
			
		||||
		if !<-c.eventChan {
 | 
			
		||||
			return nil, errors.New("Event channel has been closed.")
 | 
			
		||||
@@ -331,7 +322,8 @@ func (c *Conn) WaitForEvent() (Event, error) {
 | 
			
		||||
// Only use this function to empty the queue without blocking.
 | 
			
		||||
func (c *Conn) PollForEvent() (Event, error) {
 | 
			
		||||
	if reply := c.events.dequeue(c); reply != nil {
 | 
			
		||||
		return parseEvent(reply)
 | 
			
		||||
		evCode := reply[0] & 0x7f
 | 
			
		||||
		return newEventFuncs[int(evCode)](reply), nil
 | 
			
		||||
	}
 | 
			
		||||
	return nil, nil
 | 
			
		||||
}
 | 
			
		||||
@@ -369,11 +361,11 @@ func Dial(display string) (*Conn, error) {
 | 
			
		||||
	buf := make([]byte, 12+pad(len(authName))+pad(len(authData)))
 | 
			
		||||
	buf[0] = 0x6c
 | 
			
		||||
	buf[1] = 0
 | 
			
		||||
	put16(buf[2:], 11)
 | 
			
		||||
	put16(buf[4:], 0)
 | 
			
		||||
	put16(buf[6:], uint16(len(authName)))
 | 
			
		||||
	put16(buf[8:], uint16(len(authData)))
 | 
			
		||||
	put16(buf[10:], 0)
 | 
			
		||||
	Put16(buf[2:], 11)
 | 
			
		||||
	Put16(buf[4:], 0)
 | 
			
		||||
	Put16(buf[6:], uint16(len(authName)))
 | 
			
		||||
	Put16(buf[8:], uint16(len(authData)))
 | 
			
		||||
	Put16(buf[10:], 0)
 | 
			
		||||
	copy(buf[12:], []byte(authName))
 | 
			
		||||
	copy(buf[12+pad(len(authName)):], authData)
 | 
			
		||||
	if _, err = c.conn.Write(buf); err != nil {
 | 
			
		||||
@@ -386,9 +378,9 @@ func Dial(display string) (*Conn, error) {
 | 
			
		||||
	}
 | 
			
		||||
	code := head[0]
 | 
			
		||||
	reasonLen := head[1]
 | 
			
		||||
	major := get16(head[2:])
 | 
			
		||||
	minor := get16(head[4:])
 | 
			
		||||
	dataLen := get16(head[6:])
 | 
			
		||||
	major := Get16(head[2:])
 | 
			
		||||
	minor := Get16(head[4:])
 | 
			
		||||
	dataLen := Get16(head[6:])
 | 
			
		||||
 | 
			
		||||
	if major != 11 || minor != 0 {
 | 
			
		||||
		return nil, errors.New(fmt.Sprintf("x protocol version mismatch: %d.%d", major, minor))
 | 
			
		||||
@@ -405,7 +397,7 @@ func Dial(display string) (*Conn, error) {
 | 
			
		||||
		return nil, errors.New(fmt.Sprintf("x protocol authentication refused: %s", string(reason)))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	getSetupInfo(buf, &c.Setup)
 | 
			
		||||
	ReadSetupInfo(buf, &c.Setup)
 | 
			
		||||
 | 
			
		||||
	if c.defaultScreen >= len(c.Setup.Roots) {
 | 
			
		||||
		c.defaultScreen = 0
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,10 @@
 | 
			
		||||
package xgb
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// getExtensionOpcode retrieves the extension opcode from the extensions map.
 | 
			
		||||
// If one doesn't exist, just return 0. An X error will likely result.
 | 
			
		||||
func (c *Conn) getExtensionOpcode(name string) byte {
 | 
			
		||||
@@ -14,52 +19,50 @@ func (c *Conn) bytesString(str string) []byte {
 | 
			
		||||
	return c.bytesPadding([]byte(str))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Conn) bytesStrList(list []Str, length int) []byte {
 | 
			
		||||
	buf := make([]byte, 0)
 | 
			
		||||
	for _, str := range list {
 | 
			
		||||
		buf = append(buf, []byte(str.Name)...)
 | 
			
		||||
	}
 | 
			
		||||
	return c.bytesPadding(buf)
 | 
			
		||||
// stringsJoin is an alias to strings.Join. It allows us to avoid having to
 | 
			
		||||
// import 'strings' in each of the generated Go files.
 | 
			
		||||
func stringsJoin(ss []string, sep string) string {
 | 
			
		||||
	return strings.Join(ss, sep)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Conn) bytesUInt32List(list []uint32) []byte {
 | 
			
		||||
	buf := make([]byte, len(list)*4)
 | 
			
		||||
	for i, item := range list {
 | 
			
		||||
		put32(buf[i*4:], item)
 | 
			
		||||
	}
 | 
			
		||||
	return c.bytesPadding(buf)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Conn) bytesIdList(list []Id, length int) []byte {
 | 
			
		||||
	buf := make([]byte, length*4)
 | 
			
		||||
	for i, item := range list {
 | 
			
		||||
		put32(buf[i*4:], uint32(item))
 | 
			
		||||
	}
 | 
			
		||||
	return c.bytesPadding(buf)
 | 
			
		||||
// sprintf is so we don't need to import 'fmt' in the generated Go files.
 | 
			
		||||
func sprintf(format string, v ...interface{}) string {
 | 
			
		||||
	return fmt.Sprintf(format, v...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pad a length to align on 4 bytes.
 | 
			
		||||
func pad(n int) int { return (n + 3) & ^3 }
 | 
			
		||||
 | 
			
		||||
func put16(buf []byte, v uint16) {
 | 
			
		||||
func Put16(buf []byte, v uint16) {
 | 
			
		||||
	buf[0] = byte(v)
 | 
			
		||||
	buf[1] = byte(v >> 8)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func put32(buf []byte, v uint32) {
 | 
			
		||||
func Put32(buf []byte, v uint32) {
 | 
			
		||||
	buf[0] = byte(v)
 | 
			
		||||
	buf[1] = byte(v >> 8)
 | 
			
		||||
	buf[2] = byte(v >> 16)
 | 
			
		||||
	buf[3] = byte(v >> 24)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func get16(buf []byte) uint16 {
 | 
			
		||||
func Put64(buf []byte, v uint64) {
 | 
			
		||||
	buf[0] = byte(v)
 | 
			
		||||
	buf[1] = byte(v >> 8)
 | 
			
		||||
	buf[2] = byte(v >> 16)
 | 
			
		||||
	buf[3] = byte(v >> 24)
 | 
			
		||||
	buf[4] = byte(v >> 32)
 | 
			
		||||
	buf[5] = byte(v >> 40)
 | 
			
		||||
	buf[6] = byte(v >> 48)
 | 
			
		||||
	buf[7] = byte(v >> 56)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Get16(buf []byte) uint16 {
 | 
			
		||||
	v := uint16(buf[0])
 | 
			
		||||
	v |= uint16(buf[1]) << 8
 | 
			
		||||
	return v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func get32(buf []byte) uint32 {
 | 
			
		||||
func Get32(buf []byte) uint32 {
 | 
			
		||||
	v := uint32(buf[0])
 | 
			
		||||
	v |= uint32(buf[1]) << 8
 | 
			
		||||
	v |= uint32(buf[2]) << 16
 | 
			
		||||
@@ -67,6 +70,18 @@ func get32(buf []byte) uint32 {
 | 
			
		||||
	return v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Get64(buf []byte) uint64 {
 | 
			
		||||
	v := uint64(buf[0])
 | 
			
		||||
	v |= uint64(buf[1]) << 8
 | 
			
		||||
	v |= uint64(buf[2]) << 16
 | 
			
		||||
	v |= uint64(buf[3]) << 24
 | 
			
		||||
	v |= uint64(buf[4]) << 32
 | 
			
		||||
	v |= uint64(buf[5]) << 40
 | 
			
		||||
	v |= uint64(buf[6]) << 48
 | 
			
		||||
	v |= uint64(buf[7]) << 56
 | 
			
		||||
	return v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Voodoo to count the number of bits set in a value list mask.
 | 
			
		||||
func popCount(mask0 int) int {
 | 
			
		||||
	mask := uint32(mask0)
 | 
			
		||||
@@ -82,22 +97,3 @@ func popCount(mask0 int) int {
 | 
			
		||||
// DefaultScreen returns the Screen info for the default screen, which is
 | 
			
		||||
// 0 or the one given in the display argument to Dial.
 | 
			
		||||
func (c *Conn) DefaultScreen() *ScreenInfo { return &c.Setup.Roots[c.defaultScreen] }
 | 
			
		||||
 | 
			
		||||
// ClientMessageData holds the data from a client message,
 | 
			
		||||
// duplicated in three forms because Go doesn't have unions.
 | 
			
		||||
// type ClientMessageData struct { 
 | 
			
		||||
	// Data8  [20]byte 
 | 
			
		||||
	// Data16 [10]uint16 
 | 
			
		||||
	// Data32 [5]uint32 
 | 
			
		||||
// } 
 | 
			
		||||
//  
 | 
			
		||||
// func getClientMessageData(b []byte, v *ClientMessageData) int { 
 | 
			
		||||
	// copy(v.Data8[:], b) 
 | 
			
		||||
	// for i := 0; i < 10; i++ { 
 | 
			
		||||
		// v.Data16[i] = get16(b[i*2:]) 
 | 
			
		||||
	// } 
 | 
			
		||||
	// for i := 0; i < 5; i++ { 
 | 
			
		||||
		// v.Data32[i] = get32(b[i*4:]) 
 | 
			
		||||
	// } 
 | 
			
		||||
	// return 20 
 | 
			
		||||
// } 
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import (
 | 
			
		||||
	"encoding/xml"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Context struct {
 | 
			
		||||
@@ -47,6 +48,26 @@ func (c *Context) Morph(xmlBytes []byte) {
 | 
			
		||||
	// Translate XML types to nice types
 | 
			
		||||
	c.protocol = parsedXml.Translate()
 | 
			
		||||
 | 
			
		||||
	// Start with Go header.
 | 
			
		||||
	c.Putln("package xgb")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	c.Putln("/*")
 | 
			
		||||
	c.Putln("\tThis file was generated by %s.xml on %s.",
 | 
			
		||||
		c.protocol.Name, time.Now().Format("Jan 2 2006 3:04:05pm MST"))
 | 
			
		||||
	c.Putln("\tThis file is automatically generated. Edit at your peril!")
 | 
			
		||||
	c.Putln("*/")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
 | 
			
		||||
	// Write imports in comments
 | 
			
		||||
	if len(c.protocol.Imports) > 0 {
 | 
			
		||||
		c.Putln("// Imports are not necessary for XGB because everything is ")
 | 
			
		||||
		c.Putln("// in one package. They are still listed here for reference.")
 | 
			
		||||
		for _, imp := range c.protocol.Imports {
 | 
			
		||||
			c.Putln("// import \"%s\"", imp.Name)
 | 
			
		||||
		}
 | 
			
		||||
		c.Putln("")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Now write Go source code
 | 
			
		||||
	for _, typ := range c.protocol.Types {
 | 
			
		||||
		typ.Define(c)
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ import (
 | 
			
		||||
type Expression interface {
 | 
			
		||||
	Concrete() bool
 | 
			
		||||
	Eval() uint
 | 
			
		||||
	Reduce(prefix, fun string) string
 | 
			
		||||
	Reduce(prefix string) string
 | 
			
		||||
	String() string
 | 
			
		||||
	Initialize(p *Protocol)
 | 
			
		||||
}
 | 
			
		||||
@@ -29,12 +29,12 @@ func (e *Function) Eval() uint {
 | 
			
		||||
	panic("unreachable")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *Function) Reduce(prefix, fun string) string {
 | 
			
		||||
	return fmt.Sprintf("%s(%s)", e.Name, e.Expr.Reduce(prefix, fun))
 | 
			
		||||
func (e *Function) Reduce(prefix string) string {
 | 
			
		||||
	return fmt.Sprintf("%s(%s)", e.Name, e.Expr.Reduce(prefix))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *Function) String() string {
 | 
			
		||||
	return e.Reduce("", "")
 | 
			
		||||
	return e.Reduce("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *Function) Initialize(p *Protocol) {
 | 
			
		||||
@@ -89,16 +89,34 @@ func (e *BinaryOp) Eval() uint {
 | 
			
		||||
	panic("unreachable")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *BinaryOp) Reduce(prefix, fun string) string {
 | 
			
		||||
func (e *BinaryOp) Reduce(prefix string) string {
 | 
			
		||||
	if e.Concrete() {
 | 
			
		||||
		return fmt.Sprintf("%d", e.Eval())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// An incredibly dirty hack to make sure any time we perform an operation
 | 
			
		||||
	// on a field, we're dealing with ints...
 | 
			
		||||
	expr1, expr2 := e.Expr1, e.Expr2
 | 
			
		||||
	switch expr1.(type) {
 | 
			
		||||
	case *FieldRef:
 | 
			
		||||
		expr1 = &Function{
 | 
			
		||||
			Name: "int",
 | 
			
		||||
			Expr: expr1,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	switch expr2.(type) {
 | 
			
		||||
	case *FieldRef:
 | 
			
		||||
		expr2 = &Function{
 | 
			
		||||
			Name: "int",
 | 
			
		||||
			Expr: expr2,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("(%s %s %s)",
 | 
			
		||||
		e.Expr1.Reduce(prefix, fun), e.Op, e.Expr2.Reduce(prefix, fun))
 | 
			
		||||
		expr1.Reduce(prefix), e.Op, expr2.Reduce(prefix))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *BinaryOp) String() string {
 | 
			
		||||
	return e.Reduce("", "")
 | 
			
		||||
	return e.Reduce("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *BinaryOp) Initialize(p *Protocol) {
 | 
			
		||||
@@ -125,15 +143,15 @@ func (e *UnaryOp) Eval() uint {
 | 
			
		||||
	panic("unreachable")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *UnaryOp) Reduce(prefix, fun string) string {
 | 
			
		||||
func (e *UnaryOp) Reduce(prefix string) string {
 | 
			
		||||
	if e.Concrete() {
 | 
			
		||||
		return fmt.Sprintf("%d", e.Eval())
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("(%s (%s))", e.Op, e.Expr.Reduce(prefix, fun))
 | 
			
		||||
	return fmt.Sprintf("(%s (%s))", e.Op, e.Expr.Reduce(prefix))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *UnaryOp) String() string {
 | 
			
		||||
	return e.Reduce("", "")
 | 
			
		||||
	return e.Reduce("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *UnaryOp) Initialize(p *Protocol) {
 | 
			
		||||
@@ -152,15 +170,15 @@ func (e *PopCount) Eval() uint {
 | 
			
		||||
	return popCount(e.Expr.Eval())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *PopCount) Reduce(prefix, fun string) string {
 | 
			
		||||
func (e *PopCount) Reduce(prefix string) string {
 | 
			
		||||
	if e.Concrete() {
 | 
			
		||||
		return fmt.Sprintf("%d", e.Eval())
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("popCount(%s)", e.Expr.Reduce(prefix, fun))
 | 
			
		||||
	return fmt.Sprintf("popCount(%s)", e.Expr.Reduce(prefix))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *PopCount) String() string {
 | 
			
		||||
	return e.Reduce("", "")
 | 
			
		||||
	return e.Reduce("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *PopCount) Initialize(p *Protocol) {
 | 
			
		||||
@@ -179,12 +197,12 @@ func (e *Value) Eval() uint {
 | 
			
		||||
	return e.v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *Value) Reduce(prefix, fun string) string {
 | 
			
		||||
func (e *Value) Reduce(prefix string) string {
 | 
			
		||||
	return fmt.Sprintf("%d", e.v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *Value) String() string {
 | 
			
		||||
	return e.Reduce("", "")
 | 
			
		||||
	return e.Reduce("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *Value) Initialize(p *Protocol) {}
 | 
			
		||||
@@ -201,12 +219,12 @@ func (e *Bit) Eval() uint {
 | 
			
		||||
	return 1 << e.b
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *Bit) Reduce(prefix, fun string) string {
 | 
			
		||||
func (e *Bit) Reduce(prefix string) string {
 | 
			
		||||
	return fmt.Sprintf("%d", e.Eval())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *Bit) String() string {
 | 
			
		||||
	return e.Reduce("", "")
 | 
			
		||||
	return e.Reduce("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *Bit) Initialize(p *Protocol) {}
 | 
			
		||||
@@ -224,19 +242,16 @@ func (e *FieldRef) Eval() uint {
 | 
			
		||||
	panic("unreachable")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *FieldRef) Reduce(prefix, fun string) string {
 | 
			
		||||
func (e *FieldRef) Reduce(prefix string) string {
 | 
			
		||||
	val := e.Name
 | 
			
		||||
	if len(prefix) > 0 {
 | 
			
		||||
		val = fmt.Sprintf("%s%s", prefix, val)
 | 
			
		||||
	}
 | 
			
		||||
	if len(fun) > 0 {
 | 
			
		||||
		val = fmt.Sprintf("%s(%s)", fun, val)
 | 
			
		||||
	}
 | 
			
		||||
	return val
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *FieldRef) String() string {
 | 
			
		||||
	return e.Reduce("", "")
 | 
			
		||||
	return e.Reduce("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *FieldRef) Initialize(p *Protocol) {
 | 
			
		||||
@@ -257,16 +272,12 @@ func (e *EnumRef) Eval() uint {
 | 
			
		||||
	panic("unreachable")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *EnumRef) Reduce(prefix, fun string) string {
 | 
			
		||||
	val := fmt.Sprintf("%s%s", e.EnumKind, e.EnumItem)
 | 
			
		||||
	if len(fun) > 0 {
 | 
			
		||||
		val = fmt.Sprintf("%s(%s)", fun, val)
 | 
			
		||||
	}
 | 
			
		||||
	return val
 | 
			
		||||
func (e *EnumRef) Reduce(prefix string) string {
 | 
			
		||||
	return fmt.Sprintf("%s%s", e.EnumKind, e.EnumItem)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *EnumRef) String() string {
 | 
			
		||||
	return e.Reduce("", "")
 | 
			
		||||
	return e.Reduce("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *EnumRef) Initialize(p *Protocol) {
 | 
			
		||||
@@ -287,7 +298,7 @@ func (e *SumOf) Eval() uint {
 | 
			
		||||
	panic("unreachable")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *SumOf) Reduce(prefix, fun string) string {
 | 
			
		||||
func (e *SumOf) Reduce(prefix string) string {
 | 
			
		||||
	if len(prefix) > 0 {
 | 
			
		||||
		return fmt.Sprintf("sum(%s%s)", prefix, e.Name)
 | 
			
		||||
	}
 | 
			
		||||
@@ -295,7 +306,7 @@ func (e *SumOf) Reduce(prefix, fun string) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *SumOf) String() string {
 | 
			
		||||
	return e.Reduce("", "")
 | 
			
		||||
	return e.Reduce("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *SumOf) Initialize(p *Protocol) {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ package main
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Field interface {
 | 
			
		||||
@@ -13,8 +14,8 @@ type Field interface {
 | 
			
		||||
	Size() Size
 | 
			
		||||
 | 
			
		||||
	Define(c *Context)
 | 
			
		||||
	Read(c *Context)
 | 
			
		||||
	Write(c *Context)
 | 
			
		||||
	Read(c *Context, prefix string)
 | 
			
		||||
	Write(c *Context, prefix string)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (pad *PadField) Initialize(p *Protocol) {}
 | 
			
		||||
@@ -32,7 +33,7 @@ func (p *PadField) XmlName() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *PadField) SrcType() string {
 | 
			
		||||
	panic("it is illegal to call SrcType on a SwitchField field")
 | 
			
		||||
	panic("it is illegal to call SrcType on a PadField field")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *PadField) Size() Size {
 | 
			
		||||
@@ -82,22 +83,48 @@ func (f *ListField) XmlName() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *ListField) SrcType() string {
 | 
			
		||||
	if strings.ToLower(f.Type.XmlName()) == "char" {
 | 
			
		||||
		return fmt.Sprintf("string")
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("[]%s", f.Type.SrcName())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *ListField) Length() Size {
 | 
			
		||||
	if f.LengthExpr == nil {
 | 
			
		||||
		return newExpressionSize(&Function{
 | 
			
		||||
			Name: "len",
 | 
			
		||||
			Expr: &FieldRef{
 | 
			
		||||
				Name: f.SrcName(),
 | 
			
		||||
			},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	return newExpressionSize(f.LengthExpr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *ListField) Size() Size {
 | 
			
		||||
	simpleLen := &Function{
 | 
			
		||||
		Name: "pad",
 | 
			
		||||
		Expr: newBinaryOp("*", f.LengthExpr, f.Type.Size().Expression),
 | 
			
		||||
		Expr: newBinaryOp("*", f.Length().Expression, f.Type.Size().Expression),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch f.Type.(type) {
 | 
			
		||||
	switch field := f.Type.(type) {
 | 
			
		||||
	case *Struct:
 | 
			
		||||
		if field.HasList() {
 | 
			
		||||
			sizeFun := &Function{
 | 
			
		||||
				Name: fmt.Sprintf("%sListSize", f.Type.SrcName()),
 | 
			
		||||
				Expr: &FieldRef{Name: f.SrcName()},
 | 
			
		||||
			}
 | 
			
		||||
			return newExpressionSize(sizeFun)
 | 
			
		||||
		} else {
 | 
			
		||||
			return newExpressionSize(simpleLen)
 | 
			
		||||
		}
 | 
			
		||||
	case *Union:
 | 
			
		||||
		return newExpressionSize(simpleLen)
 | 
			
		||||
		// sizeFun := &Function{ 
 | 
			
		||||
			// Name: fmt.Sprintf("%sListSize", f.Type.SrcName()), 
 | 
			
		||||
			// Expr: &FieldRef{Name: f.SrcName()}, 
 | 
			
		||||
		// } 
 | 
			
		||||
		// return newExpressionSize(sizeFun) 
 | 
			
		||||
	case *Base:
 | 
			
		||||
		return newExpressionSize(simpleLen)
 | 
			
		||||
	case *Resource:
 | 
			
		||||
@@ -152,6 +179,7 @@ func (f *ExprField) Initialize(p *Protocol) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ValueField struct {
 | 
			
		||||
	Parent interface{}
 | 
			
		||||
	MaskType Type
 | 
			
		||||
	MaskName string
 | 
			
		||||
	ListName string
 | 
			
		||||
@@ -170,7 +198,34 @@ func (f *ValueField) SrcType() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *ValueField) Size() Size {
 | 
			
		||||
	return f.MaskType.Size()
 | 
			
		||||
	maskSize := f.MaskType.Size()
 | 
			
		||||
	listSize := newExpressionSize(&Function{
 | 
			
		||||
		Name: "pad",
 | 
			
		||||
		Expr: &BinaryOp{
 | 
			
		||||
			Op: "*",
 | 
			
		||||
			Expr1: &Value{v: 4},
 | 
			
		||||
			Expr2: &PopCount{
 | 
			
		||||
				Expr: &Function{
 | 
			
		||||
					Name: "int",
 | 
			
		||||
					Expr: &FieldRef{
 | 
			
		||||
						Name: f.MaskName,
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
	return maskSize.Add(listSize)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *ValueField) ListLength() Size {
 | 
			
		||||
	return newExpressionSize(&PopCount{
 | 
			
		||||
		Expr: &Function{
 | 
			
		||||
			Name: "int",
 | 
			
		||||
			Expr: &FieldRef{
 | 
			
		||||
				Name: f.MaskName,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *ValueField) Initialize(p *Protocol) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,9 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// xgbResourceIdName is the name of the type used for all resource identifiers.
 | 
			
		||||
// As of right now, it needs to be declared somewhere manually.
 | 
			
		||||
var xgbGenResourceIdName = "Id"
 | 
			
		||||
@@ -94,26 +98,28 @@ func (f *PadField) Define(c *Context) {
 | 
			
		||||
	c.Putln("// padding: %d bytes", f.Bytes)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *PadField) Read(c *Context) {
 | 
			
		||||
func (f *PadField) Read(c *Context, prefix string) {
 | 
			
		||||
	c.Putln("b += %s // padding", f.Size())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *PadField) Write(c *Context) {
 | 
			
		||||
func (f *PadField) Write(c *Context, prefix string) {
 | 
			
		||||
	c.Putln("b += %s // padding", f.Size())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Local fields
 | 
			
		||||
func (f *LocalField) Define(c *Context) {
 | 
			
		||||
	c.Putln("// local field: %s %s", f.SrcName(), f.Type.SrcName())
 | 
			
		||||
	panic("unreachable")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *LocalField) Read(c *Context) {
 | 
			
		||||
func (f *LocalField) Read(c *Context, prefix string) {
 | 
			
		||||
	c.Putln("// reading local field: %s (%s) :: %s",
 | 
			
		||||
		f.SrcName(), f.Size(), f.Type.SrcName())
 | 
			
		||||
	panic("unreachable")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *LocalField) Write(c *Context) {
 | 
			
		||||
	c.Putln("// writing local field: %s (%s) :: %s",
 | 
			
		||||
func (f *LocalField) Write(c *Context, prefix string) {
 | 
			
		||||
	c.Putln("// skip writing local field: %s (%s) :: %s",
 | 
			
		||||
		f.SrcName(), f.Size(), f.Type.SrcName())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -121,32 +127,49 @@ func (f *LocalField) Write(c *Context) {
 | 
			
		||||
func (f *ExprField) Define(c *Context) {
 | 
			
		||||
	c.Putln("// expression field: %s %s (%s)",
 | 
			
		||||
		f.SrcName(), f.Type.SrcName(), f.Expr)
 | 
			
		||||
	panic("unreachable")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *ExprField) Read(c *Context) {
 | 
			
		||||
func (f *ExprField) Read(c *Context, prefix string) {
 | 
			
		||||
	c.Putln("// reading expression field: %s (%s) (%s) :: %s",
 | 
			
		||||
		f.SrcName(), f.Size(), f.Expr, f.Type.SrcName())
 | 
			
		||||
	panic("unreachable")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *ExprField) Write(c *Context) {
 | 
			
		||||
	c.Putln("// writing expression field: %s (%s) (%s) :: %s",
 | 
			
		||||
		f.SrcName(), f.Size(), f.Expr, f.Type.SrcName())
 | 
			
		||||
func (f *ExprField) Write(c *Context, prefix string) {
 | 
			
		||||
	// Special case for bools, grrr.
 | 
			
		||||
	if f.Type.SrcName() == "bool" {
 | 
			
		||||
		c.Putln("buf[b] = byte(%s)", f.Expr.Reduce(prefix))
 | 
			
		||||
		c.Putln("b += 1")
 | 
			
		||||
	} else {
 | 
			
		||||
		WriteSimpleSingleField(c, f.Expr.Reduce(prefix), f.Type)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Value field
 | 
			
		||||
func (f *ValueField) Define(c *Context) {
 | 
			
		||||
	c.Putln("// valueparam field: type: %s, mask name: %s, list name: %s",
 | 
			
		||||
		f.MaskType.SrcName(), f.MaskName, f.ListName)
 | 
			
		||||
	panic("todo")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *ValueField) Read(c *Context) {
 | 
			
		||||
func (f *ValueField) Read(c *Context, prefix string) {
 | 
			
		||||
	c.Putln("// reading valueparam: type: %s, mask name: %s, list name: %s",
 | 
			
		||||
		f.MaskType.SrcName(), f.MaskName, f.ListName)
 | 
			
		||||
	panic("todo")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *ValueField) Write(c *Context) {
 | 
			
		||||
	c.Putln("// writing valueparam: type: %s, mask name: %s, list name: %s",
 | 
			
		||||
		f.MaskType.SrcName(), f.MaskName, f.ListName)
 | 
			
		||||
func (f *ValueField) Write(c *Context, prefix string) {
 | 
			
		||||
	// big time mofos
 | 
			
		||||
	if rq, ok := f.Parent.(*Request); !ok || rq.SrcName() != "ConfigureWindow" {
 | 
			
		||||
		WriteSimpleSingleField(c,
 | 
			
		||||
			fmt.Sprintf("%s%s", prefix, f.MaskName), f.MaskType)
 | 
			
		||||
	}
 | 
			
		||||
	c.Putln("for i := 0; i < %s; i++ {", f.ListLength().Reduce(prefix))
 | 
			
		||||
	c.Putln("Put32(buf[b:], %s%s[i])", prefix, f.ListName)
 | 
			
		||||
	c.Putln("b += 4")
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("b = pad(b)")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Switch field
 | 
			
		||||
@@ -155,12 +178,12 @@ func (f *SwitchField) Define(c *Context) {
 | 
			
		||||
	panic("todo")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *SwitchField) Read(c *Context) {
 | 
			
		||||
func (f *SwitchField) Read(c *Context, prefix string) {
 | 
			
		||||
	c.Putln("// reading switch field: %s (%s)", f.Name, f.Expr)
 | 
			
		||||
	panic("todo")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *SwitchField) Write(c *Context) {
 | 
			
		||||
func (f *SwitchField) Write(c *Context, prefix string) {
 | 
			
		||||
	c.Putln("// writing switch field: %s (%s)", f.Name, f.Expr)
 | 
			
		||||
	panic("todo")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,9 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Error types
 | 
			
		||||
func (e *Error) Define(c *Context) {
 | 
			
		||||
	c.Putln("// Error definition %s (%d)", e.SrcName(), e.Number)
 | 
			
		||||
@@ -20,9 +24,8 @@ func (e *Error) Define(c *Context) {
 | 
			
		||||
	// error struct.
 | 
			
		||||
	e.Read(c)
 | 
			
		||||
 | 
			
		||||
	// Makes sure that this error type is an Error interface.
 | 
			
		||||
	c.Putln("func (v %s) ImplementsError() { }", e.ErrType())
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	// Makes sure this error type implements the xgb.Error interface.
 | 
			
		||||
	e.ImplementsError(c)
 | 
			
		||||
 | 
			
		||||
	// Let's the XGB event loop read this error.
 | 
			
		||||
	c.Putln("func init() {")
 | 
			
		||||
@@ -33,18 +36,18 @@ func (e *Error) Define(c *Context) {
 | 
			
		||||
 | 
			
		||||
func (e *Error) Read(c *Context) {
 | 
			
		||||
	c.Putln("// Error read %s", e.SrcName())
 | 
			
		||||
	c.Putln("func New%s(buf []byte) %s {", e.ErrType(), e.ErrType())
 | 
			
		||||
	c.Putln("func New%s(buf []byte) Error {", e.ErrType())
 | 
			
		||||
	c.Putln("v := %s{}", e.ErrType())
 | 
			
		||||
	c.Putln("v.NiceName = \"%s\"", e.SrcName())
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	c.Putln("b := 1 // skip error determinant")
 | 
			
		||||
	c.Putln("b += 1 // don't read error number")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	c.Putln("v.Sequence = get16(buf[b:])")
 | 
			
		||||
	c.Putln("v.Sequence = Get16(buf[b:])")
 | 
			
		||||
	c.Putln("b += 2")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	for _, field := range e.Fields {
 | 
			
		||||
		field.Read(c)
 | 
			
		||||
		field.Read(c, "v.")
 | 
			
		||||
		c.Putln("")
 | 
			
		||||
	}
 | 
			
		||||
	c.Putln("return v")
 | 
			
		||||
@@ -52,6 +55,24 @@ func (e *Error) Read(c *Context) {
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ImplementsError writes functions to implement the XGB Error interface.
 | 
			
		||||
func (e *Error) ImplementsError(c *Context) {
 | 
			
		||||
	c.Putln("func (err %s) ImplementsError() { }", e.ErrType())
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	c.Putln("func (err %s) SequenceId() uint16 {", e.ErrType())
 | 
			
		||||
	c.Putln("return err.Sequence")
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	c.Putln("func (err %s) BadId() Id {", e.ErrType())
 | 
			
		||||
	c.Putln("return Id(err.BadValue)")
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	c.Putln("func (err %s) Error() string {", e.ErrType())
 | 
			
		||||
	FieldString(c, e.Fields, e.ErrConst())
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ErrorCopy types
 | 
			
		||||
func (e *ErrorCopy) Define(c *Context) {
 | 
			
		||||
	c.Putln("// ErrorCopy definition %s (%d)", e.SrcName(), e.Number)
 | 
			
		||||
@@ -65,9 +86,8 @@ func (e *ErrorCopy) Define(c *Context) {
 | 
			
		||||
	// error struct.
 | 
			
		||||
	e.Read(c)
 | 
			
		||||
 | 
			
		||||
	// Makes sure that this error type is an Error interface.
 | 
			
		||||
	c.Putln("func (err %s) ImplementsError() { }", e.ErrType())
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	// Makes sure this error type implements the xgb.Error interface.
 | 
			
		||||
	e.ImplementsError(c)
 | 
			
		||||
 | 
			
		||||
	// Let's the XGB know how to read this error.
 | 
			
		||||
	c.Putln("func init() {")
 | 
			
		||||
@@ -77,8 +97,54 @@ func (e *ErrorCopy) Define(c *Context) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *ErrorCopy) Read(c *Context) {
 | 
			
		||||
	c.Putln("func New%s(buf []byte) %s {", e.ErrType(), e.ErrType())
 | 
			
		||||
	c.Putln("return %s(New%s(buf))", e.ErrType(), e.Old.(*Error).ErrType())
 | 
			
		||||
	c.Putln("func New%s(buf []byte) Error {", e.ErrType())
 | 
			
		||||
	c.Putln("v := %s(New%s(buf).(%s))",
 | 
			
		||||
		e.ErrType(), e.Old.(*Error).ErrType(), e.Old.(*Error).ErrType())
 | 
			
		||||
	c.Putln("v.NiceName = \"%s\"", e.SrcName())
 | 
			
		||||
	c.Putln("return v")
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ImplementsError writes functions to implement the XGB Error interface.
 | 
			
		||||
func (e *ErrorCopy) ImplementsError(c *Context) {
 | 
			
		||||
	c.Putln("func (err %s) ImplementsError() { }", e.ErrType())
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	c.Putln("func (err %s) SequenceId() uint16 {", e.ErrType())
 | 
			
		||||
	c.Putln("return err.Sequence")
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	c.Putln("func (err %s) BadId() Id {", e.ErrType())
 | 
			
		||||
	c.Putln("return Id(err.BadValue)")
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	c.Putln("func (err %s) Error() string {", e.ErrType())
 | 
			
		||||
	FieldString(c, e.Old.(*Error).Fields, e.ErrConst())
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FieldString works for both Error and ErrorCopy. It assembles all of the
 | 
			
		||||
// fields in an error and formats them into a single string.
 | 
			
		||||
func FieldString(c *Context, fields []Field, errName string) {
 | 
			
		||||
	c.Putln("fieldVals := make([]string, 0, %d)", len(fields))
 | 
			
		||||
	c.Putln("fieldVals = append(fieldVals, \"NiceName: \" + err.NiceName)")
 | 
			
		||||
	c.Putln("fieldVals = append(fieldVals, " +
 | 
			
		||||
		"sprintf(\"Sequence: %s\", err.Sequence))", "%d")
 | 
			
		||||
	for _, field := range fields {
 | 
			
		||||
		switch field.(type) {
 | 
			
		||||
		case *PadField:
 | 
			
		||||
			continue
 | 
			
		||||
		default:
 | 
			
		||||
			if field.SrcType() == "string" {
 | 
			
		||||
				c.Putln("fieldVals = append(fieldVals, \"%s: \" + err.%s)",
 | 
			
		||||
					field.SrcName(), field.SrcName())
 | 
			
		||||
			} else {
 | 
			
		||||
				format := fmt.Sprintf("sprintf(\"%s: %s\", err.%s)",
 | 
			
		||||
					field.SrcName(), "%d", field.SrcName())
 | 
			
		||||
				c.Putln("fieldVals = append(fieldVals, %s)", format)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	c.Putln("return \"%s {\" + stringsJoin(fieldVals, \", \") + \"}\"", errName)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -38,17 +38,17 @@ func (e *Event) Define(c *Context) {
 | 
			
		||||
 | 
			
		||||
func (e *Event) Read(c *Context) {
 | 
			
		||||
	c.Putln("// Event read %s", e.SrcName())
 | 
			
		||||
	c.Putln("func New%s(buf []byte) %s {", e.EvType(), e.EvType())
 | 
			
		||||
	c.Putln("func New%s(buf []byte) Event {", e.EvType())
 | 
			
		||||
	c.Putln("v := %s{}", e.EvType())
 | 
			
		||||
	c.Putln("b := 1 // don't read event number")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	for i, field := range e.Fields {
 | 
			
		||||
		if i == 1 && !e.NoSequence {
 | 
			
		||||
			c.Putln("v.Sequence = get16(buf[b:])")
 | 
			
		||||
			c.Putln("v.Sequence = Get16(buf[b:])")
 | 
			
		||||
			c.Putln("b += 2")
 | 
			
		||||
			c.Putln("")
 | 
			
		||||
		}
 | 
			
		||||
		field.Read(c)
 | 
			
		||||
		field.Read(c, "v.")
 | 
			
		||||
		c.Putln("")
 | 
			
		||||
	}
 | 
			
		||||
	c.Putln("return v")
 | 
			
		||||
@@ -71,7 +71,7 @@ func (e *Event) Write(c *Context) {
 | 
			
		||||
			c.Putln("b += 2 // skip sequence number")
 | 
			
		||||
			c.Putln("")
 | 
			
		||||
		}
 | 
			
		||||
		field.Write(c)
 | 
			
		||||
		field.Write(c, "v.")
 | 
			
		||||
		c.Putln("")
 | 
			
		||||
	}
 | 
			
		||||
	c.Putln("return buf")
 | 
			
		||||
@@ -108,15 +108,16 @@ func (e *EventCopy) Define(c *Context) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *EventCopy) Read(c *Context) {
 | 
			
		||||
	c.Putln("func New%s(buf []byte) %s {", e.EvType(), e.EvType())
 | 
			
		||||
	c.Putln("return %s(New%s(buf))", e.EvType(), e.Old.(*Event).EvType())
 | 
			
		||||
	c.Putln("func New%s(buf []byte) Event {", e.EvType())
 | 
			
		||||
	c.Putln("return %s(New%s(buf).(%s))",
 | 
			
		||||
		e.EvType(), e.Old.(*Event).EvType(), e.Old.(*Event).EvType())
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *EventCopy) Write(c *Context) {
 | 
			
		||||
	c.Putln("func (v %s) Bytes() []byte {", e.EvType())
 | 
			
		||||
	c.Putln("return %s(ev).Bytes()", e.Old.(*Event).EvType())
 | 
			
		||||
	c.Putln("return %s(v).Bytes()", e.Old.(*Event).EvType())
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,74 +3,107 @@ package main
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// List fields
 | 
			
		||||
func (f *ListField) Define(c *Context) {
 | 
			
		||||
	c.Putln("%s []%s // size: %s",
 | 
			
		||||
		f.SrcName(), f.Type.SrcName(), f.Size())
 | 
			
		||||
	c.Putln("%s %s // size: %s",
 | 
			
		||||
		f.SrcName(), f.SrcType(), f.Size())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *ListField) Read(c *Context) {
 | 
			
		||||
func (f *ListField) Read(c *Context, prefix string) {
 | 
			
		||||
	switch t := f.Type.(type) {
 | 
			
		||||
	case *Resource:
 | 
			
		||||
		length := f.LengthExpr.Reduce("v.", "")
 | 
			
		||||
		c.Putln("v.%s = make([]Id, %s)", f.SrcName(), length)
 | 
			
		||||
		c.Putln("for i := 0; i < %s; i++ {", length)
 | 
			
		||||
		ReadSimpleSingleField(c, fmt.Sprintf("v.%s[i]", f.SrcName()), t)
 | 
			
		||||
		length := f.LengthExpr.Reduce(prefix)
 | 
			
		||||
		c.Putln("%s%s = make([]Id, %s)", prefix, f.SrcName(), length)
 | 
			
		||||
		c.Putln("for i := 0; i < int(%s); i++ {", length)
 | 
			
		||||
		ReadSimpleSingleField(c, fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t)
 | 
			
		||||
		c.Putln("}")
 | 
			
		||||
		c.Putln("b = pad(b)")
 | 
			
		||||
	case *Base:
 | 
			
		||||
		length := f.LengthExpr.Reduce("v.", "")
 | 
			
		||||
		c.Putln("v.%s = make([]%s, %s)", f.SrcName(), t.SrcName(), length)
 | 
			
		||||
		if t.SrcName() == "byte" {
 | 
			
		||||
			c.Putln("copy(v.%s[:%s], buf[b:])", f.SrcName(), length)
 | 
			
		||||
			c.Putln("b += pad(%s)", length)
 | 
			
		||||
		length := f.LengthExpr.Reduce(prefix)
 | 
			
		||||
		if strings.ToLower(t.XmlName()) == "char" {
 | 
			
		||||
			c.Putln("{")
 | 
			
		||||
			c.Putln("byteString := make([]%s, %s)", t.SrcName(), length)
 | 
			
		||||
			c.Putln("copy(byteString[:%s], buf[b:])", length)
 | 
			
		||||
			c.Putln("%s%s = string(byteString)", prefix, f.SrcName())
 | 
			
		||||
			c.Putln("b += pad(int(%s))", length)
 | 
			
		||||
			c.Putln("}")
 | 
			
		||||
		} else if t.SrcName() == "byte" {
 | 
			
		||||
			c.Putln("%s%s = make([]%s, %s)",
 | 
			
		||||
				prefix, f.SrcName(), t.SrcName(), length)
 | 
			
		||||
			c.Putln("copy(%s%s[:%s], buf[b:])", prefix, f.SrcName(), length)
 | 
			
		||||
			c.Putln("b += pad(int(%s))", length)
 | 
			
		||||
		} else {
 | 
			
		||||
			c.Putln("for i := 0; i < %s; i++ {", length)
 | 
			
		||||
			ReadSimpleSingleField(c, fmt.Sprintf("v.%s[i]", f.SrcName()), t)
 | 
			
		||||
			c.Putln("%s%s = make([]%s, %s)",
 | 
			
		||||
				prefix, f.SrcName(), t.SrcName(), length)
 | 
			
		||||
			c.Putln("for i := 0; i < int(%s); i++ {", length)
 | 
			
		||||
			ReadSimpleSingleField(c,
 | 
			
		||||
				fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t)
 | 
			
		||||
			c.Putln("}")
 | 
			
		||||
			c.Putln("b = pad(b)")
 | 
			
		||||
		}
 | 
			
		||||
	case *TypeDef:
 | 
			
		||||
		length := f.LengthExpr.Reduce(prefix)
 | 
			
		||||
		c.Putln("%s%s = make([]%s, %s)",
 | 
			
		||||
			prefix, f.SrcName(), t.SrcName(), length)
 | 
			
		||||
		c.Putln("for i := 0; i < int(%s); i++ {", length)
 | 
			
		||||
		ReadSimpleSingleField(c, fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t)
 | 
			
		||||
		c.Putln("}")
 | 
			
		||||
		c.Putln("b = pad(b)")
 | 
			
		||||
	case *Union:
 | 
			
		||||
		c.Putln("v.%s = make([]%s, %s)",
 | 
			
		||||
			f.SrcName(), t.SrcName(), f.LengthExpr.Reduce("v.", ""))
 | 
			
		||||
		c.Putln("b += Read%sList(buf[b:], v.%s)", t.SrcName(), f.SrcName())
 | 
			
		||||
		c.Putln("%s%s = make([]%s, %s)",
 | 
			
		||||
			prefix, f.SrcName(), t.SrcName(), f.LengthExpr.Reduce(prefix))
 | 
			
		||||
		c.Putln("b += Read%sList(buf[b:], %s%s)",
 | 
			
		||||
			t.SrcName(), prefix, f.SrcName())
 | 
			
		||||
	case *Struct:
 | 
			
		||||
		c.Putln("v.%s = make([]%s, %s)",
 | 
			
		||||
			f.SrcName(), t.SrcName(), f.LengthExpr.Reduce("v.", ""))
 | 
			
		||||
		c.Putln("b += Read%sList(buf[b:], v.%s)", t.SrcName(), f.SrcName())
 | 
			
		||||
		c.Putln("%s%s = make([]%s, %s)",
 | 
			
		||||
			prefix, f.SrcName(), t.SrcName(), f.LengthExpr.Reduce(prefix))
 | 
			
		||||
		c.Putln("b += Read%sList(buf[b:], %s%s)",
 | 
			
		||||
			t.SrcName(), prefix, f.SrcName())
 | 
			
		||||
	default:
 | 
			
		||||
		log.Panicf("Cannot read list field '%s' with %T type.",
 | 
			
		||||
			f.XmlName(), f.Type)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *ListField) Write(c *Context) {
 | 
			
		||||
func (f *ListField) Write(c *Context, prefix string) {
 | 
			
		||||
	switch t := f.Type.(type) {
 | 
			
		||||
	case *Resource:
 | 
			
		||||
		length := f.LengthExpr.Reduce("v.", "")
 | 
			
		||||
		c.Putln("for i := 0; i < %s; i++", length)
 | 
			
		||||
		WriteSimpleSingleField(c, fmt.Sprintf("v.%s[i]", f.SrcName()), t)
 | 
			
		||||
		length := f.Length().Reduce(prefix)
 | 
			
		||||
		c.Putln("for i := 0; i < int(%s); i++ {", length)
 | 
			
		||||
		WriteSimpleSingleField(c,
 | 
			
		||||
			fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t)
 | 
			
		||||
		c.Putln("}")
 | 
			
		||||
		c.Putln("b = pad(b)")
 | 
			
		||||
	case *Base:
 | 
			
		||||
		length := f.LengthExpr.Reduce("v.", "")
 | 
			
		||||
		length := f.Length().Reduce(prefix)
 | 
			
		||||
		if t.SrcName() == "byte" {
 | 
			
		||||
			c.Putln("copy(buf[b:], v.%s[:%s])", f.SrcName(), length)
 | 
			
		||||
			c.Putln("b += pad(%s)", length)
 | 
			
		||||
			c.Putln("copy(buf[b:], %s%s[:%s])", prefix, f.SrcName(), length)
 | 
			
		||||
			c.Putln("b += pad(int(%s))", length)
 | 
			
		||||
		} else {
 | 
			
		||||
			c.Putln("for i := 0; i < %s; i++ {", length)
 | 
			
		||||
			WriteSimpleSingleField(c, fmt.Sprintf("v.%s[i]", f.SrcName()), t)
 | 
			
		||||
			c.Putln("for i := 0; i < int(%s); i++ {", length)
 | 
			
		||||
			WriteSimpleSingleField(c,
 | 
			
		||||
				fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t)
 | 
			
		||||
			c.Putln("}")
 | 
			
		||||
			c.Putln("b = pad(b)")
 | 
			
		||||
		}
 | 
			
		||||
	case *TypeDef:
 | 
			
		||||
		length := f.Length().Reduce(prefix)
 | 
			
		||||
		c.Putln("for i := 0; i < int(%s); i++ {", length)
 | 
			
		||||
		WriteSimpleSingleField(c,
 | 
			
		||||
			fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t)
 | 
			
		||||
		c.Putln("}")
 | 
			
		||||
		c.Putln("b = pad(b)")
 | 
			
		||||
	case *Union:
 | 
			
		||||
		c.Putln("b += %sListBytes(buf[b:], v.%s)", t.SrcName(), f.SrcName())
 | 
			
		||||
		c.Putln("b += %sListBytes(buf[b:], %s%s)",
 | 
			
		||||
			t.SrcName(), prefix, f.SrcName())
 | 
			
		||||
	case *Struct:
 | 
			
		||||
		c.Putln("b += %sListBytes(buf[b:], v.%s)", t.SrcName(), f.SrcName())
 | 
			
		||||
		c.Putln("b += %sListBytes(buf[b:], %s%s)",
 | 
			
		||||
			t.SrcName(), prefix, f.SrcName())
 | 
			
		||||
	default:
 | 
			
		||||
		log.Panicf("Cannot read list field '%s' with %T type.",
 | 
			
		||||
		log.Panicf("Cannot write list field '%s' with %T type.",
 | 
			
		||||
			f.XmlName(), f.Type)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
func (r *Request) Define(c *Context) {
 | 
			
		||||
	c.Putln("// Request %s", r.SrcName())
 | 
			
		||||
	c.Putln("// size: %s", r.Size(c))
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	if r.Reply != nil {
 | 
			
		||||
		c.Putln("// Request reply for %s", r.SrcName())
 | 
			
		||||
		c.Putln("// size: %s", r.Reply.Size())
 | 
			
		||||
		c.Putln("type %s struct {", r.ReplyName())
 | 
			
		||||
		c.Putln("Sequence uint16")
 | 
			
		||||
		for _, field := range r.Reply.Fields {
 | 
			
		||||
			field.Define(c)
 | 
			
		||||
		}
 | 
			
		||||
		c.Putln("}")
 | 
			
		||||
		c.Putln("")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										140
									
								
								nexgb/xgbgen/go_request_reply.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								nexgb/xgbgen/go_request_reply.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,140 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (r *Request) Define(c *Context) {
 | 
			
		||||
	c.Putln("// Request %s", r.SrcName())
 | 
			
		||||
	c.Putln("// size: %s", r.Size(c))
 | 
			
		||||
	if r.Reply != nil {
 | 
			
		||||
		c.Putln("func (c *Conn) %s(%s) (*%s, error) {",
 | 
			
		||||
			r.SrcName(), r.ParamNameTypes(), r.ReplyName())
 | 
			
		||||
		c.Putln("return c.%s(c.%s(%s))",
 | 
			
		||||
			r.ReplyName(), r.ReqName(), r.ParamNames())
 | 
			
		||||
		c.Putln("}")
 | 
			
		||||
		c.Putln("")
 | 
			
		||||
 | 
			
		||||
		r.WriteRequest(c)
 | 
			
		||||
		r.ReadReply(c)
 | 
			
		||||
	} else {
 | 
			
		||||
		c.Putln("// Write request to wire for %s", r.SrcName())
 | 
			
		||||
		c.Putln("func (c *Conn) %s(%s) {", r.SrcName(), r.ParamNameTypes())
 | 
			
		||||
		r.WriteRequestFields(c)
 | 
			
		||||
		c.Putln("c.sendRequest(false, buf)")
 | 
			
		||||
		c.Putln("}")
 | 
			
		||||
		c.Putln("")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *Request) ReadReply(c *Context) {
 | 
			
		||||
	c.Putln("// Request reply for %s", r.SrcName())
 | 
			
		||||
	c.Putln("// size: %s", r.Reply.Size())
 | 
			
		||||
	c.Putln("type %s struct {", r.ReplyName())
 | 
			
		||||
	c.Putln("Sequence uint16")
 | 
			
		||||
	c.Putln("Length uint32")
 | 
			
		||||
	for _, field := range r.Reply.Fields {
 | 
			
		||||
		field.Define(c)
 | 
			
		||||
	}
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
 | 
			
		||||
	c.Putln("// Read reply %s", r.SrcName())
 | 
			
		||||
	c.Putln("func (c *Conn) %s(cook *Cookie) (*%s, error) {",
 | 
			
		||||
		r.ReplyName(), r.ReplyName())
 | 
			
		||||
	c.Putln("buf, err := c.waitForReply(cook)")
 | 
			
		||||
	c.Putln("if err != nil {")
 | 
			
		||||
	c.Putln("return nil, err")
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	c.Putln("v := new(%s)", r.ReplyName())
 | 
			
		||||
	c.Putln("b := 1 // skip reply determinant")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	for i, field := range r.Reply.Fields {
 | 
			
		||||
		if i == 1 {
 | 
			
		||||
			c.Putln("v.Sequence = Get16(buf[b:])")
 | 
			
		||||
			c.Putln("b += 2")
 | 
			
		||||
			c.Putln("")
 | 
			
		||||
			c.Putln("v.Length = Get32(buf[b:]) // 4-byte units")
 | 
			
		||||
			c.Putln("b += 4")
 | 
			
		||||
			c.Putln("")
 | 
			
		||||
		}
 | 
			
		||||
		field.Read(c, "v.")
 | 
			
		||||
		c.Putln("")
 | 
			
		||||
	}
 | 
			
		||||
	c.Putln("return v, nil")
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *Request) WriteRequest(c *Context) {
 | 
			
		||||
	c.Putln("// Write request to wire for %s", r.SrcName())
 | 
			
		||||
	c.Putln("func (c *Conn) %s(%s) *Cookie {", r.ReqName(), r.ParamNameTypes())
 | 
			
		||||
	r.WriteRequestFields(c)
 | 
			
		||||
	c.Putln("return c.sendRequest(true, buf)")
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *Request) WriteRequestFields(c *Context) {
 | 
			
		||||
	c.Putln("size := %s", r.Size(c))
 | 
			
		||||
	c.Putln("b := 0")
 | 
			
		||||
	c.Putln("buf := make([]byte, size)")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	c.Putln("buf[b] = %d // request opcode", r.Opcode)
 | 
			
		||||
	c.Putln("b += 1")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	for i, field := range r.Fields {
 | 
			
		||||
		if i == 1 {
 | 
			
		||||
			c.Putln("Put16(buf[b:], uint16(size / 4)) "+
 | 
			
		||||
				"// write request size in 4-byte units")
 | 
			
		||||
			c.Putln("b += 2")
 | 
			
		||||
			c.Putln("")
 | 
			
		||||
		}
 | 
			
		||||
		field.Write(c, "")
 | 
			
		||||
		c.Putln("")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *Request) ParamNames() string {
 | 
			
		||||
	names := make([]string, 0, len(r.Fields))
 | 
			
		||||
	for _, field := range r.Fields {
 | 
			
		||||
		switch f := field.(type) {
 | 
			
		||||
		case *ValueField:
 | 
			
		||||
			names = append(names, f.MaskName)
 | 
			
		||||
			names = append(names, f.ListName)
 | 
			
		||||
		case *PadField:
 | 
			
		||||
			continue
 | 
			
		||||
		case *ExprField:
 | 
			
		||||
			continue
 | 
			
		||||
		default:
 | 
			
		||||
			names = append(names, fmt.Sprintf("%s", field.SrcName()))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return strings.Join(names, ",")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *Request) ParamNameTypes() string {
 | 
			
		||||
	nameTypes := make([]string, 0, len(r.Fields))
 | 
			
		||||
	for _, field := range r.Fields {
 | 
			
		||||
		switch f := field.(type) {
 | 
			
		||||
		case *ValueField:
 | 
			
		||||
			// mofos...
 | 
			
		||||
			if r.SrcName() != "ConfigureWindow" {
 | 
			
		||||
				nameTypes = append(nameTypes,
 | 
			
		||||
					fmt.Sprintf("%s %s", f.MaskName, f.MaskType.SrcName()))
 | 
			
		||||
			}
 | 
			
		||||
			nameTypes = append(nameTypes,
 | 
			
		||||
				fmt.Sprintf("%s []uint32", f.ListName))
 | 
			
		||||
		case *PadField:
 | 
			
		||||
			continue
 | 
			
		||||
		case *ExprField:
 | 
			
		||||
			continue
 | 
			
		||||
		default:
 | 
			
		||||
			nameTypes = append(nameTypes,
 | 
			
		||||
				fmt.Sprintf("%s %s", field.SrcName(), field.SrcType()))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return strings.Join(nameTypes, ",")
 | 
			
		||||
}
 | 
			
		||||
@@ -12,17 +12,17 @@ func (f *SingleField) Define(c *Context) {
 | 
			
		||||
func ReadSimpleSingleField(c *Context, name string, typ Type) {
 | 
			
		||||
	switch t := typ.(type) {
 | 
			
		||||
	case *Resource:
 | 
			
		||||
		c.Putln("%s = get32(buf[b:])", name)
 | 
			
		||||
		c.Putln("%s = Id(Get32(buf[b:]))", name)
 | 
			
		||||
	case *TypeDef:
 | 
			
		||||
		switch t.Size().Eval() {
 | 
			
		||||
		case 1:
 | 
			
		||||
			c.Putln("%s = %s(buf[b])", name, t.SrcName())
 | 
			
		||||
		case 2:
 | 
			
		||||
			c.Putln("%s = %s(get16(buf[b:]))", name, t.SrcName())
 | 
			
		||||
			c.Putln("%s = %s(Get16(buf[b:]))", name, t.SrcName())
 | 
			
		||||
		case 4:
 | 
			
		||||
			c.Putln("%s = %s(get32(buf[b:]))", name, t.SrcName())
 | 
			
		||||
			c.Putln("%s = %s(Get32(buf[b:]))", name, t.SrcName())
 | 
			
		||||
		case 8:
 | 
			
		||||
			c.Putln("%s = %s(get64(buf[b:]))", name, t.SrcName())
 | 
			
		||||
			c.Putln("%s = %s(Get64(buf[b:]))", name, t.SrcName())
 | 
			
		||||
		}
 | 
			
		||||
	case *Base:
 | 
			
		||||
		// If this is a bool, stop short and do something special.
 | 
			
		||||
@@ -40,11 +40,11 @@ func ReadSimpleSingleField(c *Context, name string, typ Type) {
 | 
			
		||||
		case 1:
 | 
			
		||||
			val = fmt.Sprintf("buf[b]")
 | 
			
		||||
		case 2:
 | 
			
		||||
			val = fmt.Sprintf("get16(buf[b:])")
 | 
			
		||||
			val = fmt.Sprintf("Get16(buf[b:])")
 | 
			
		||||
		case 4:
 | 
			
		||||
			val = fmt.Sprintf("get32(buf[b:])")
 | 
			
		||||
			val = fmt.Sprintf("Get32(buf[b:])")
 | 
			
		||||
		case 8:
 | 
			
		||||
			val = fmt.Sprintf("get64(buf[b:])")
 | 
			
		||||
			val = fmt.Sprintf("Get64(buf[b:])")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// We need to convert base types if they aren't uintXX or byte
 | 
			
		||||
@@ -61,20 +61,20 @@ func ReadSimpleSingleField(c *Context, name string, typ Type) {
 | 
			
		||||
	c.Putln("b += %s", typ.Size())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *SingleField) Read(c *Context) {
 | 
			
		||||
func (f *SingleField) Read(c *Context, prefix string) {
 | 
			
		||||
	switch t := f.Type.(type) {
 | 
			
		||||
	case *Resource:
 | 
			
		||||
		ReadSimpleSingleField(c, fmt.Sprintf("v.%s", f.SrcName()), t)
 | 
			
		||||
		ReadSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t)
 | 
			
		||||
	case *TypeDef:
 | 
			
		||||
		ReadSimpleSingleField(c, fmt.Sprintf("v.%s", f.SrcName()), t)
 | 
			
		||||
		ReadSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t)
 | 
			
		||||
	case *Base:
 | 
			
		||||
		ReadSimpleSingleField(c, fmt.Sprintf("v.%s", f.SrcName()), t)
 | 
			
		||||
		ReadSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t)
 | 
			
		||||
	case *Struct:
 | 
			
		||||
		c.Putln("v.%s = %s{}", f.SrcName(), t.SrcName())
 | 
			
		||||
		c.Putln("b += Read%s(buf[b:], &v.%s)", t.SrcName(), f.SrcName())
 | 
			
		||||
		c.Putln("%s%s = %s{}", prefix, f.SrcName(), t.SrcName())
 | 
			
		||||
		c.Putln("b += Read%s(buf[b:], &%s%s)", t.SrcName(), prefix, f.SrcName())
 | 
			
		||||
	case *Union:
 | 
			
		||||
		c.Putln("v.%s = %s{}", f.SrcName(), t.SrcName())
 | 
			
		||||
		c.Putln("b += Read%s(buf[b:], &v.%s)", t.SrcName(), f.SrcName())
 | 
			
		||||
		c.Putln("%s%s = %s{}", prefix, f.SrcName(), t.SrcName())
 | 
			
		||||
		c.Putln("b += Read%s(buf[b:], &%s%s)", t.SrcName(), prefix, f.SrcName())
 | 
			
		||||
	default:
 | 
			
		||||
		log.Panicf("Cannot read field '%s' with %T type.", f.XmlName(), f.Type)
 | 
			
		||||
	}
 | 
			
		||||
@@ -83,17 +83,17 @@ func (f *SingleField) Read(c *Context) {
 | 
			
		||||
func WriteSimpleSingleField(c *Context, name string, typ Type) {
 | 
			
		||||
	switch t := typ.(type) {
 | 
			
		||||
	case *Resource:
 | 
			
		||||
		c.Putln("put32(buf[b:], uint32(%s))", name)
 | 
			
		||||
		c.Putln("Put32(buf[b:], uint32(%s))", name)
 | 
			
		||||
	case *TypeDef:
 | 
			
		||||
		switch t.Size().Eval() {
 | 
			
		||||
		case 1:
 | 
			
		||||
			c.Putln("buf[b] = byte(%s)", name)
 | 
			
		||||
		case 2:
 | 
			
		||||
			c.Putln("put16(buf[b:], uint16(%s))", name)
 | 
			
		||||
			c.Putln("Put16(buf[b:], uint16(%s))", name)
 | 
			
		||||
		case 4:
 | 
			
		||||
			c.Putln("put32(buf[b:], uint32(%s))", name)
 | 
			
		||||
			c.Putln("Put32(buf[b:], uint32(%s))", name)
 | 
			
		||||
		case 8:
 | 
			
		||||
			c.Putln("put64(buf[b:], uint64(%s))", name)
 | 
			
		||||
			c.Putln("Put64(buf[b:], uint64(%s))", name)
 | 
			
		||||
		}
 | 
			
		||||
	case *Base:
 | 
			
		||||
		// If this is a bool, stop short and do something special.
 | 
			
		||||
@@ -115,21 +115,21 @@ func WriteSimpleSingleField(c *Context, name string, typ Type) {
 | 
			
		||||
			}
 | 
			
		||||
		case 2:
 | 
			
		||||
			if t.SrcName() != "uint16" {
 | 
			
		||||
				c.Putln("put16(buf[b:], uint16(%s))", name)
 | 
			
		||||
				c.Putln("Put16(buf[b:], uint16(%s))", name)
 | 
			
		||||
			} else {
 | 
			
		||||
				c.Putln("put16(buf[b:], %s)", name)
 | 
			
		||||
				c.Putln("Put16(buf[b:], %s)", name)
 | 
			
		||||
			}
 | 
			
		||||
		case 4:
 | 
			
		||||
			if t.SrcName() != "uint32" {
 | 
			
		||||
				c.Putln("put32(buf[b:], uint32(%s))", name)
 | 
			
		||||
				c.Putln("Put32(buf[b:], uint32(%s))", name)
 | 
			
		||||
			} else {
 | 
			
		||||
				c.Putln("put32(buf[b:], %s)", name)
 | 
			
		||||
				c.Putln("Put32(buf[b:], %s)", name)
 | 
			
		||||
			}
 | 
			
		||||
		case 8:
 | 
			
		||||
			if t.SrcName() != "uint64" {
 | 
			
		||||
				c.Putln("put64(buf[b:], uint64(%s))", name)
 | 
			
		||||
				c.Putln("Put64(buf[b:], uint64(%s))", name)
 | 
			
		||||
			} else {
 | 
			
		||||
				c.Putln("put64(buf[b:], %s)", name)
 | 
			
		||||
				c.Putln("Put64(buf[b:], %s)", name)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
@@ -140,23 +140,23 @@ func WriteSimpleSingleField(c *Context, name string, typ Type) {
 | 
			
		||||
	c.Putln("b += %s", typ.Size())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *SingleField) Write(c *Context) {
 | 
			
		||||
func (f *SingleField) Write(c *Context, prefix string) {
 | 
			
		||||
	switch t := f.Type.(type) {
 | 
			
		||||
	case *Resource:
 | 
			
		||||
		ReadSimpleSingleField(c, fmt.Sprintf("v.%s", f.SrcName()), t)
 | 
			
		||||
		WriteSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t)
 | 
			
		||||
	case *TypeDef:
 | 
			
		||||
		ReadSimpleSingleField(c, fmt.Sprintf("v.%s", f.SrcName()), t)
 | 
			
		||||
		WriteSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t)
 | 
			
		||||
	case *Base:
 | 
			
		||||
		ReadSimpleSingleField(c, fmt.Sprintf("v.%s", f.SrcName()), t)
 | 
			
		||||
		WriteSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t)
 | 
			
		||||
	case *Union:
 | 
			
		||||
		c.Putln("{")
 | 
			
		||||
		c.Putln("unionBytes := v.%s.Bytes()", f.SrcName())
 | 
			
		||||
		c.Putln("unionBytes := %s%s.Bytes()", prefix, f.SrcName())
 | 
			
		||||
		c.Putln("copy(buf[b:], unionBytes)")
 | 
			
		||||
		c.Putln("b += pad(len(unionBytes))")
 | 
			
		||||
		c.Putln("}")
 | 
			
		||||
	case *Struct:
 | 
			
		||||
		c.Putln("{")
 | 
			
		||||
		c.Putln("structBytes := v.%s.Bytes()", f.SrcName())
 | 
			
		||||
		c.Putln("structBytes := %s%s.Bytes()", prefix, f.SrcName())
 | 
			
		||||
		c.Putln("copy(buf[b:], structBytes)")
 | 
			
		||||
		c.Putln("b += pad(len(structBytes))")
 | 
			
		||||
		c.Putln("}")
 | 
			
		||||
 
 | 
			
		||||
@@ -22,9 +22,12 @@ func (s *Struct) Define(c *Context) {
 | 
			
		||||
	// Write function that writes a list of this struct.
 | 
			
		||||
	s.WriteList(c)
 | 
			
		||||
 | 
			
		||||
	// Write function that computes the size of a list of these structs.
 | 
			
		||||
	// Write function that computes the size of a list of these structs,
 | 
			
		||||
	// IF there is a list field in this struct.
 | 
			
		||||
	if s.HasList() {
 | 
			
		||||
		s.WriteListSize(c)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Read for a struct creates a function 'ReadStructName' that takes a source 
 | 
			
		||||
// byte slice (i.e., the buffer) and a destination struct, and returns
 | 
			
		||||
@@ -37,7 +40,8 @@ func (s *Struct) Read(c *Context) {
 | 
			
		||||
	c.Putln("b := 0")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	for _, field := range s.Fields {
 | 
			
		||||
		field.Read(c)
 | 
			
		||||
		field.Read(c, "v.")
 | 
			
		||||
		c.Putln("")
 | 
			
		||||
	}
 | 
			
		||||
	c.Putln("return b")
 | 
			
		||||
 | 
			
		||||
@@ -68,11 +72,12 @@ func (s *Struct) ReadList(c *Context) {
 | 
			
		||||
func (s *Struct) Write(c *Context) {
 | 
			
		||||
	c.Putln("// Struct write %s", s.SrcName())
 | 
			
		||||
	c.Putln("func (v %s) Bytes() []byte {", s.SrcName())
 | 
			
		||||
	c.Putln("buf := make([]byte, %s)", s.Size().Reduce("v.", ""))
 | 
			
		||||
	c.Putln("buf := make([]byte, %s)", s.Size().Reduce("v."))
 | 
			
		||||
	c.Putln("b := 0")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	for _, field := range s.Fields {
 | 
			
		||||
		field.Write(c)
 | 
			
		||||
		field.Write(c, "v.")
 | 
			
		||||
		c.Putln("")
 | 
			
		||||
	}
 | 
			
		||||
	c.Putln("return buf")
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
@@ -87,7 +92,7 @@ func (s *Struct) WriteList(c *Context) {
 | 
			
		||||
	c.Putln("var structBytes []byte")
 | 
			
		||||
	c.Putln("for _, item := range list {")
 | 
			
		||||
	c.Putln("structBytes = item.Bytes()")
 | 
			
		||||
	c.Putln("copy(buf[b:], len(structBytes))")
 | 
			
		||||
	c.Putln("copy(buf[b:], structBytes)")
 | 
			
		||||
	c.Putln("b += pad(len(structBytes))")
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("return b")
 | 
			
		||||
@@ -100,7 +105,7 @@ func (s *Struct) WriteListSize(c *Context) {
 | 
			
		||||
	c.Putln("func %sListSize(list []%s) int {", s.SrcName(), s.SrcName())
 | 
			
		||||
	c.Putln("size := 0")
 | 
			
		||||
	c.Putln("for _, item := range list {")
 | 
			
		||||
	c.Putln("size += %s", s.Size().Reduce("item.", ""))
 | 
			
		||||
	c.Putln("size += %s", s.Size().Reduce("item."))
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("return size")
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
 
 | 
			
		||||
@@ -34,9 +34,6 @@ func (u *Union) Define(c *Context) {
 | 
			
		||||
 | 
			
		||||
	// Write function that writes a list of this union.
 | 
			
		||||
	u.WriteList(c)
 | 
			
		||||
 | 
			
		||||
	// Write function that computes the size of a list of these unions.
 | 
			
		||||
	u.WriteListSize(c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (u *Union) New(c *Context) {
 | 
			
		||||
@@ -49,7 +46,7 @@ func (u *Union) New(c *Context) {
 | 
			
		||||
		c.Putln("var b int")
 | 
			
		||||
		c.Putln("buf := make([]byte, %s)", u.Size())
 | 
			
		||||
		c.Putln("")
 | 
			
		||||
		field.Write(c)
 | 
			
		||||
		field.Write(c, "")
 | 
			
		||||
		c.Putln("")
 | 
			
		||||
		c.Putln("// Create the Union type")
 | 
			
		||||
		c.Putln("v := %s{}", u.SrcName())
 | 
			
		||||
@@ -58,7 +55,7 @@ func (u *Union) New(c *Context) {
 | 
			
		||||
		c.Putln("")
 | 
			
		||||
		for _, field2 := range u.Fields {
 | 
			
		||||
			c.Putln("b = 0 // always read the same bytes")
 | 
			
		||||
			field2.Read(c)
 | 
			
		||||
			field2.Read(c, "v.")
 | 
			
		||||
			c.Putln("")
 | 
			
		||||
		}
 | 
			
		||||
		c.Putln("return v")
 | 
			
		||||
@@ -74,7 +71,7 @@ func (u *Union) Read(c *Context) {
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	for _, field := range u.Fields {
 | 
			
		||||
		c.Putln("b = 0 // re-read the same bytes")
 | 
			
		||||
		field.Read(c)
 | 
			
		||||
		field.Read(c, "v.")
 | 
			
		||||
		c.Putln("")
 | 
			
		||||
	}
 | 
			
		||||
	c.Putln("return %s", u.Size())
 | 
			
		||||
@@ -106,10 +103,10 @@ func (u *Union) Write(c *Context) {
 | 
			
		||||
	c.Putln("// Each field in a union must contain the same data.")
 | 
			
		||||
	c.Putln("// So simply pick the first field and write that to the wire.")
 | 
			
		||||
	c.Putln("func (v %s) Bytes() []byte {", u.SrcName())
 | 
			
		||||
	c.Putln("buf := make([]byte, %s)", u.Size().Reduce("v.", ""))
 | 
			
		||||
	c.Putln("buf := make([]byte, %s)", u.Size().Reduce("v."))
 | 
			
		||||
	c.Putln("b := 0")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
	u.Fields[0].Write(c)
 | 
			
		||||
	u.Fields[0].Write(c, "v.")
 | 
			
		||||
	c.Putln("return buf")
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("")
 | 
			
		||||
@@ -123,7 +120,7 @@ func (u *Union) WriteList(c *Context) {
 | 
			
		||||
	c.Putln("var unionBytes []byte")
 | 
			
		||||
	c.Putln("for _, item := range list {")
 | 
			
		||||
	c.Putln("unionBytes = item.Bytes()")
 | 
			
		||||
	c.Putln("copy(buf[b:], len(unionBytes))")
 | 
			
		||||
	c.Putln("copy(buf[b:], unionBytes)")
 | 
			
		||||
	c.Putln("b += pad(len(unionBytes))")
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("return b")
 | 
			
		||||
@@ -136,7 +133,7 @@ func (u *Union) WriteListSize(c *Context) {
 | 
			
		||||
	c.Putln("func %sListSize(list []%s) int {", u.SrcName(), u.SrcName())
 | 
			
		||||
	c.Putln("size := 0")
 | 
			
		||||
	c.Putln("for _, item := range list {")
 | 
			
		||||
	c.Putln("size += %s", u.Size().Reduce("item.", ""))
 | 
			
		||||
	c.Putln("size += %s", u.Size().Reduce("item."))
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
	c.Putln("return size")
 | 
			
		||||
	c.Putln("}")
 | 
			
		||||
 
 | 
			
		||||
@@ -65,6 +65,10 @@ func (r *Request) ReplyName() string {
 | 
			
		||||
	return fmt.Sprintf("%sReply", r.SrcName())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *Request) ReqName() string {
 | 
			
		||||
	return fmt.Sprintf("%sRequest", r.SrcName())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Size for Request needs a context.
 | 
			
		||||
// Namely, if this is an extension, we need to account for *four* bytes
 | 
			
		||||
// of a header (extension opcode, request opcode, and the sequence number).
 | 
			
		||||
@@ -80,7 +84,20 @@ func (r *Request) Size(c *Context) Size {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, field := range r.Fields {
 | 
			
		||||
		switch field.(type) {
 | 
			
		||||
		case *LocalField:
 | 
			
		||||
			continue
 | 
			
		||||
		case *SingleField:
 | 
			
		||||
			// mofos!!!
 | 
			
		||||
			if r.SrcName() == "ConfigureWindow" &&
 | 
			
		||||
				field.SrcName() == "ValueMask" {
 | 
			
		||||
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			size = size.Add(field.Size())
 | 
			
		||||
		default:
 | 
			
		||||
			size = size.Add(field.Size())
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return size
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -138,7 +138,7 @@ func (x *XMLEvent) Translate() *Event {
 | 
			
		||||
		Fields:     make([]Field, len(x.Fields)),
 | 
			
		||||
	}
 | 
			
		||||
	for i, field := range x.Fields {
 | 
			
		||||
		ev.Fields[i] = field.Translate()
 | 
			
		||||
		ev.Fields[i] = field.Translate(ev)
 | 
			
		||||
	}
 | 
			
		||||
	return ev
 | 
			
		||||
}
 | 
			
		||||
@@ -158,7 +158,7 @@ func (x *XMLError) Translate() *Error {
 | 
			
		||||
		Fields:  make([]Field, len(x.Fields)),
 | 
			
		||||
	}
 | 
			
		||||
	for i, field := range x.Fields {
 | 
			
		||||
		err.Fields[i] = field.Translate()
 | 
			
		||||
		err.Fields[i] = field.Translate(err)
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
@@ -177,7 +177,7 @@ func (x *XMLStruct) Translate() *Struct {
 | 
			
		||||
		Fields:  make([]Field, len(x.Fields)),
 | 
			
		||||
	}
 | 
			
		||||
	for i, field := range x.Fields {
 | 
			
		||||
		s.Fields[i] = field.Translate()
 | 
			
		||||
		s.Fields[i] = field.Translate(s)
 | 
			
		||||
	}
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
@@ -188,7 +188,7 @@ func (x *XMLUnion) Translate() *Union {
 | 
			
		||||
		Fields:  make([]Field, len(x.Fields)),
 | 
			
		||||
	}
 | 
			
		||||
	for i, field := range x.Fields {
 | 
			
		||||
		u.Fields[i] = field.Translate()
 | 
			
		||||
		u.Fields[i] = field.Translate(u)
 | 
			
		||||
	}
 | 
			
		||||
	return u
 | 
			
		||||
}
 | 
			
		||||
@@ -202,7 +202,7 @@ func (x *XMLRequest) Translate() *Request {
 | 
			
		||||
		Reply:   x.Reply.Translate(),
 | 
			
		||||
	}
 | 
			
		||||
	for i, field := range x.Fields {
 | 
			
		||||
		r.Fields[i] = field.Translate()
 | 
			
		||||
		r.Fields[i] = field.Translate(r)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Address bug (or legacy code) in QueryTextExtents.
 | 
			
		||||
@@ -230,7 +230,7 @@ func (x *XMLReply) Translate() *Reply {
 | 
			
		||||
		Fields: make([]Field, len(x.Fields)),
 | 
			
		||||
	}
 | 
			
		||||
	for i, field := range x.Fields {
 | 
			
		||||
		r.Fields[i] = field.Translate()
 | 
			
		||||
		r.Fields[i] = field.Translate(r)
 | 
			
		||||
	}
 | 
			
		||||
	return r
 | 
			
		||||
}
 | 
			
		||||
@@ -309,7 +309,7 @@ func (x *XMLExpression) Translate() Expression {
 | 
			
		||||
	panic("unreachable")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *XMLField) Translate() Field {
 | 
			
		||||
func (x *XMLField) Translate(parent interface{}) Field {
 | 
			
		||||
	switch x.XMLName.Local {
 | 
			
		||||
	case "pad":
 | 
			
		||||
		return &PadField{
 | 
			
		||||
@@ -339,6 +339,7 @@ func (x *XMLField) Translate() Field {
 | 
			
		||||
		}
 | 
			
		||||
	case "valueparam":
 | 
			
		||||
		return &ValueField{
 | 
			
		||||
			Parent: parent,
 | 
			
		||||
			MaskType: newTranslation(x.ValueMaskType),
 | 
			
		||||
			MaskName: x.ValueMaskName,
 | 
			
		||||
			ListName: x.ValueListName,
 | 
			
		||||
@@ -365,7 +366,7 @@ func (x *XMLBitcase) Translate() *Bitcase {
 | 
			
		||||
		Fields: make([]Field, len(x.Fields)),
 | 
			
		||||
	}
 | 
			
		||||
	for i, field := range x.Fields {
 | 
			
		||||
		b.Fields[i] = field.Translate()
 | 
			
		||||
		b.Fields[i] = field.Translate(b)
 | 
			
		||||
	}
 | 
			
		||||
	return b
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -334,6 +334,18 @@ func (s *Struct) Initialize(p *Protocol) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HasList returns whether there is a field in this struct that is a list.
 | 
			
		||||
// When true, a more involved calculation is necessary to compute this struct's
 | 
			
		||||
// size.
 | 
			
		||||
func (s *Struct) HasList() bool {
 | 
			
		||||
	for _, field := range s.Fields {
 | 
			
		||||
		if _, ok := field.(*ListField); ok {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Union struct {
 | 
			
		||||
	srcName string
 | 
			
		||||
	xmlName string
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11215
									
								
								nexgb/xproto.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11215
									
								
								nexgb/xproto.go
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user