holy toldeo... things might actually be working
This commit is contained in:
parent
39507f86ab
commit
5cdae5950c
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("")
|
||||
}
|
||||
}
|
||||
|
|
@ -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,8 +22,11 @@ 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
|
||||
|
@ -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
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue