finally starting on the crescendo: requests and replies.
This commit is contained in:
parent
f48b6fafc6
commit
39507f86ab
|
@ -51,4 +51,7 @@ func (c *Context) Morph(xmlBytes []byte) {
|
|||
for _, typ := range c.protocol.Types {
|
||||
typ.Define(c)
|
||||
}
|
||||
for _, req := range c.protocol.Requests {
|
||||
req.Define(c)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,8 +102,10 @@ func (f *ListField) Size() Size {
|
|||
return newExpressionSize(simpleLen)
|
||||
case *Resource:
|
||||
return newExpressionSize(simpleLen)
|
||||
case *TypeDef:
|
||||
return newExpressionSize(simpleLen)
|
||||
default:
|
||||
log.Fatalf("Cannot compute list size with type '%T'.", f.Type)
|
||||
log.Panicf("Cannot compute list size with type '%T'.", f.Type)
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
|
|
@ -105,57 +105,48 @@ func (f *PadField) Write(c *Context) {
|
|||
// Local fields
|
||||
func (f *LocalField) Define(c *Context) {
|
||||
c.Putln("// local field: %s %s", f.SrcName(), f.Type.SrcName())
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
func (f *LocalField) Read(c *Context) {
|
||||
c.Putln("// reading local field: %s (%s) :: %s",
|
||||
f.SrcName(), f.Size(), f.Type.SrcName())
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
func (f *LocalField) Write(c *Context) {
|
||||
c.Putln("// writing local field: %s (%s) :: %s",
|
||||
f.SrcName(), f.Size(), f.Type.SrcName())
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
// Expr fields
|
||||
func (f *ExprField) Define(c *Context) {
|
||||
c.Putln("// expression field: %s %s (%s)",
|
||||
f.SrcName(), f.Type.SrcName(), f.Expr)
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
func (f *ExprField) Read(c *Context) {
|
||||
c.Putln("// reading expression field: %s (%s) (%s) :: %s",
|
||||
f.SrcName(), f.Size(), f.Expr, f.Type.SrcName())
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
func (f *ExprField) Write(c *Context) {
|
||||
c.Putln("// writing expression field: %s (%s) (%s) :: %s",
|
||||
f.SrcName(), f.Size(), f.Expr, f.Type.SrcName())
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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)
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
// Switch field
|
||||
|
|
|
@ -3,15 +3,53 @@ package main
|
|||
// Error types
|
||||
func (e *Error) Define(c *Context) {
|
||||
c.Putln("// Error definition %s (%d)", e.SrcName(), e.Number)
|
||||
c.Putln("// Size: %s", e.Size())
|
||||
c.Putln("")
|
||||
c.Putln("const %s = %d", e.ErrConst(), e.Number)
|
||||
c.Putln("")
|
||||
c.Putln("type %s struct {", e.ErrType())
|
||||
c.Putln("Sequence uint16")
|
||||
c.Putln("NiceName string")
|
||||
for _, field := range e.Fields {
|
||||
field.Define(c)
|
||||
}
|
||||
c.Putln("}")
|
||||
c.Putln("")
|
||||
|
||||
// Read defines a function that transforms a byte slice into this
|
||||
// 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("")
|
||||
|
||||
// Let's the XGB event loop read this error.
|
||||
c.Putln("func init() {")
|
||||
c.Putln("newErrorFuncs[%d] = New%s", e.Number, e.ErrType())
|
||||
c.Putln("}")
|
||||
c.Putln("")
|
||||
}
|
||||
|
||||
func (e *Error) Read(c *Context, prefix string) {
|
||||
func (e *Error) Read(c *Context) {
|
||||
c.Putln("// Error read %s", e.SrcName())
|
||||
}
|
||||
|
||||
func (e *Error) Write(c *Context, prefix string) {
|
||||
c.Putln("// Error write %s", e.SrcName())
|
||||
c.Putln("func New%s(buf []byte) %s {", e.ErrType(), 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("b += 2")
|
||||
c.Putln("")
|
||||
for _, field := range e.Fields {
|
||||
field.Read(c)
|
||||
c.Putln("")
|
||||
}
|
||||
c.Putln("return v")
|
||||
c.Putln("}")
|
||||
c.Putln("")
|
||||
}
|
||||
|
||||
// ErrorCopy types
|
||||
|
@ -27,31 +65,20 @@ func (e *ErrorCopy) Define(c *Context) {
|
|||
// error struct.
|
||||
e.Read(c)
|
||||
|
||||
// Write defines a function that transoforms this error struct into
|
||||
// a byte slice.
|
||||
e.Write(c)
|
||||
|
||||
// Makes sure that this error type is an Error interface.
|
||||
c.Putln("func (err %s) ImplementsError() { }", e.ErrType())
|
||||
c.Putln("")
|
||||
|
||||
// Let's the XGB know how to read this error.
|
||||
c.Putln("func init() {")
|
||||
c.Putln("newErrorFuncs[%d] = New%s", e.Number, e.SrcName())
|
||||
c.Putln("newErrorFuncs[%d] = New%s", e.Number, e.ErrType())
|
||||
c.Putln("}")
|
||||
c.Putln("")
|
||||
}
|
||||
|
||||
func (e *ErrorCopy) Read(c *Context) {
|
||||
c.Putln("func New%s(buf []byte) %s {", e.SrcName(), e.ErrType())
|
||||
c.Putln("return (%s)(New%s(buf))", e.ErrType(), e.Old.SrcName())
|
||||
c.Putln("}")
|
||||
c.Putln("")
|
||||
}
|
||||
|
||||
func (e *ErrorCopy) Write(c *Context) {
|
||||
c.Putln("func (err %s) Bytes() []byte {", e.ErrType())
|
||||
c.Putln("return (%s)(err).Bytes()", e.Old.(*Error).ErrType())
|
||||
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("}")
|
||||
c.Putln("")
|
||||
}
|
||||
|
|
|
@ -4,8 +4,13 @@ package main
|
|||
func (e *Event) Define(c *Context) {
|
||||
c.Putln("// Event definition %s (%d)", e.SrcName(), e.Number)
|
||||
c.Putln("// Size: %s", e.Size())
|
||||
c.Putln("")
|
||||
c.Putln("const %s = %d", e.SrcName(), e.Number)
|
||||
c.Putln("")
|
||||
c.Putln("type %s struct {", e.EvType())
|
||||
c.Putln("Sequence uint16")
|
||||
if !e.NoSequence {
|
||||
c.Putln("Sequence uint16")
|
||||
}
|
||||
for _, field := range e.Fields {
|
||||
field.Define(c)
|
||||
}
|
||||
|
@ -16,7 +21,7 @@ func (e *Event) Define(c *Context) {
|
|||
// event struct.
|
||||
e.Read(c)
|
||||
|
||||
// Write defines a function that transoforms this event struct into
|
||||
// Write defines a function that transforms this event struct into
|
||||
// a byte slice.
|
||||
e.Write(c)
|
||||
|
||||
|
@ -26,14 +31,14 @@ func (e *Event) Define(c *Context) {
|
|||
|
||||
// Let's the XGB event loop read this event.
|
||||
c.Putln("func init() {")
|
||||
c.Putln("newEventFuncs[%d] = New%s", e.Number, e.SrcName())
|
||||
c.Putln("newEventFuncs[%d] = New%s", e.Number, e.EvType())
|
||||
c.Putln("}")
|
||||
c.Putln("")
|
||||
}
|
||||
|
||||
func (e *Event) Read(c *Context) {
|
||||
c.Putln("// Event read %s", e.SrcName())
|
||||
c.Putln("func New%s(buf []byte) %s {", e.SrcName(), e.EvType())
|
||||
c.Putln("func New%s(buf []byte) %s {", e.EvType(), e.EvType())
|
||||
c.Putln("v := %s{}", e.EvType())
|
||||
c.Putln("b := 1 // don't read event number")
|
||||
c.Putln("")
|
||||
|
@ -97,21 +102,21 @@ func (e *EventCopy) Define(c *Context) {
|
|||
|
||||
// Let's the XGB event loop read this event.
|
||||
c.Putln("func init() {")
|
||||
c.Putln("newEventFuncs[%d] = New%s", e.Number, e.SrcName())
|
||||
c.Putln("newEventFuncs[%d] = New%s", e.Number, e.EvType())
|
||||
c.Putln("}")
|
||||
c.Putln("")
|
||||
}
|
||||
|
||||
func (e *EventCopy) Read(c *Context) {
|
||||
c.Putln("func New%s(buf []byte) %s {", e.SrcName(), e.EvType())
|
||||
c.Putln("return (%s)(New%s(buf))", e.EvType(), e.Old.SrcName())
|
||||
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("}")
|
||||
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(ev).Bytes()", e.Old.(*Event).EvType())
|
||||
c.Putln("}")
|
||||
c.Putln("")
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ func (f *ListField) Read(c *Context) {
|
|||
f.SrcName(), t.SrcName(), f.LengthExpr.Reduce("v.", ""))
|
||||
c.Putln("b += Read%sList(buf[b:], v.%s)", t.SrcName(), f.SrcName())
|
||||
default:
|
||||
log.Fatalf("Cannot read list field '%s' with %T type.",
|
||||
log.Panicf("Cannot read list field '%s' with %T type.",
|
||||
f.XmlName(), f.Type)
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ func (f *ListField) Write(c *Context) {
|
|||
case *Struct:
|
||||
c.Putln("b += %sListBytes(buf[b:], v.%s)", t.SrcName(), f.SrcName())
|
||||
default:
|
||||
log.Fatalf("Cannot read list field '%s' with %T type.",
|
||||
log.Panicf("Cannot read list field '%s' with %T type.",
|
||||
f.XmlName(), f.Type)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
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("")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,10 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
type Protocol struct {
|
||||
Name string
|
||||
ExtXName string
|
||||
|
@ -44,10 +49,58 @@ func (r *Request) Initialize(p *Protocol) {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *Request) SrcName() string {
|
||||
return r.srcName
|
||||
}
|
||||
|
||||
func (r *Request) XmlName() string {
|
||||
return r.xmlName
|
||||
}
|
||||
|
||||
func (r *Request) ReplyName() string {
|
||||
if r.Reply == nil {
|
||||
log.Panicf("Cannot call 'ReplyName' on request %s, which has no reply.",
|
||||
r.SrcName())
|
||||
}
|
||||
return fmt.Sprintf("%sReply", 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).
|
||||
// If it's a core protocol request, then we only account for *three*
|
||||
// bytes of the header (remove the extension opcode).
|
||||
func (r *Request) Size(c *Context) Size {
|
||||
size := newFixedSize(0)
|
||||
|
||||
if c.protocol.Name == "xproto" {
|
||||
size = size.Add(newFixedSize(3))
|
||||
} else {
|
||||
size = size.Add(newFixedSize(4))
|
||||
}
|
||||
|
||||
for _, field := range r.Fields {
|
||||
size = size.Add(field.Size())
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
type Reply struct {
|
||||
Fields []Field
|
||||
}
|
||||
|
||||
func (r *Reply) Size() Size {
|
||||
size := newFixedSize(0)
|
||||
|
||||
// Account for reply discriminant, sequence number and reply length
|
||||
size = size.Add(newFixedSize(7))
|
||||
|
||||
for _, field := range r.Fields {
|
||||
size = size.Add(field.Size())
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
func (r *Reply) Initialize(p *Protocol) {
|
||||
for _, field := range r.Fields {
|
||||
field.Initialize(p)
|
||||
|
|
|
@ -210,11 +210,13 @@ func (x *XMLRequest) Translate() *Request {
|
|||
// computation of the 'odd_length' field. However, 'string_len' is not
|
||||
// defined. Therefore, let's forcefully add it as a 'local field'.
|
||||
// (i.e., a parameter in the caller but does not get send over the wire.)
|
||||
stringLenLocal := &LocalField{&SingleField{
|
||||
xmlName: "string_len",
|
||||
Type: newTranslation("CARD16"),
|
||||
}}
|
||||
r.Fields = append(r.Fields, stringLenLocal)
|
||||
if x.Name == "QueryTextExtents" {
|
||||
stringLenLocal := &LocalField{&SingleField{
|
||||
xmlName: "string_len",
|
||||
Type: newTranslation("CARD16"),
|
||||
}}
|
||||
r.Fields = append(r.Fields, stringLenLocal)
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
|
|
@ -221,7 +221,7 @@ func (e *EventCopy) XmlName() string {
|
|||
}
|
||||
|
||||
func (e *EventCopy) Size() Size {
|
||||
panic("Cannot take size of EventCopy type.")
|
||||
return newExpressionSize(&Value{v: 32})
|
||||
}
|
||||
|
||||
func (e *EventCopy) Initialize(p *Protocol) {
|
||||
|
@ -252,11 +252,14 @@ func (e *Error) XmlName() string {
|
|||
}
|
||||
|
||||
func (e *Error) Size() Size {
|
||||
panic("Cannot take size of Error type.")
|
||||
return newExpressionSize(&Value{v: 32})
|
||||
}
|
||||
|
||||
func (e *Error) Initialize(p *Protocol) {
|
||||
e.srcName = TypeSrcName(p, e)
|
||||
for _, field := range e.Fields {
|
||||
field.Initialize(p)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Error) ErrConst() string {
|
||||
|
@ -283,7 +286,7 @@ func (e *ErrorCopy) XmlName() string {
|
|||
}
|
||||
|
||||
func (e *ErrorCopy) Size() Size {
|
||||
panic("Cannot take size of ErrorCopy type.")
|
||||
return newExpressionSize(&Value{v: 32})
|
||||
}
|
||||
|
||||
func (e *ErrorCopy) Initialize(p *Protocol) {
|
||||
|
|
|
@ -135,7 +135,7 @@ type XMLEvents []*XMLEvent
|
|||
type XMLEvent struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Number int `xml:"number,attr"`
|
||||
NoSequence bool `xml:"no-sequence-number,true"`
|
||||
NoSequence bool `xml:"no-sequence-number,attr"`
|
||||
Fields XMLFields `xml:",any"`
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue