From c222d406b09de529388fcd248476e9ae258895b8 Mon Sep 17 00:00:00 2001 From: "Andrew Gallant (Ocelot)" Date: Sat, 5 May 2012 02:55:38 -0400 Subject: [PATCH] converting to new reply/cookie scheme --- nexgb/xgbgen/expression.go | 27 ++++++++++ nexgb/xgbgen/go_event.go | 16 ++++++ nexgb/xgbgen/go_request_reply.go | 84 ++++++++++++++++++++++---------- nexgb/xgbgen/representation.go | 23 ++++++++- 4 files changed, 122 insertions(+), 28 deletions(-) diff --git a/nexgb/xgbgen/expression.go b/nexgb/xgbgen/expression.go index 12bcb19..6a8aa52 100644 --- a/nexgb/xgbgen/expression.go +++ b/nexgb/xgbgen/expression.go @@ -158,6 +158,33 @@ func (e *UnaryOp) Initialize(p *Protocol) { e.Expr.Initialize(p) } +type Padding struct { + Expr Expression +} + +func (e *Padding) Concrete() bool { + return e.Expr.Concrete() +} + +func (e *Padding) Eval() uint { + return uint(pad(int(e.Expr.Eval()))) +} + +func (e *Padding) Reduce(prefix string) string { + if e.Concrete() { + return fmt.Sprintf("%d", e.Eval()) + } + return fmt.Sprintf("pad(%s)", e.Expr.Reduce(prefix)) +} + +func (e *Padding) String() string { + return e.Reduce("") +} + +func (e *Padding) Initialize(p *Protocol) { + e.Expr.Initialize(p) +} + type PopCount struct { Expr Expression } diff --git a/nexgb/xgbgen/go_event.go b/nexgb/xgbgen/go_event.go index 71252a7..41f9320 100644 --- a/nexgb/xgbgen/go_event.go +++ b/nexgb/xgbgen/go_event.go @@ -28,6 +28,14 @@ func (e *Event) Define(c *Context) { // Makes sure that this event type is an Event interface. c.Putln("func (v %s) ImplementsEvent() { }", e.EvType()) c.Putln("") + c.Putln("func (v %s) SequenceId() uint16 {", e.EvType()) + if e.NoSequence { + c.Putln("return uint16(0)") + } else { + c.Putln("return v.Sequence") + } + c.Putln("}") + c.Putln("") // Let's the XGB event loop read this event. c.Putln("func init() {") @@ -99,6 +107,14 @@ func (e *EventCopy) Define(c *Context) { // Makes sure that this event type is an Event interface. c.Putln("func (v %s) ImplementsEvent() { }", e.EvType()) c.Putln("") + c.Putln("func (v %s) SequenceId() uint16 {", e.EvType()) + if e.Old.(*Event).NoSequence { + c.Putln("return uint16(0)") + } else { + c.Putln("return v.Sequence") + } + c.Putln("}") + c.Putln("") // Let's the XGB event loop read this event. c.Putln("func init() {") diff --git a/nexgb/xgbgen/go_request_reply.go b/nexgb/xgbgen/go_request_reply.go index e6180a1..00c48f9 100644 --- a/nexgb/xgbgen/go_request_reply.go +++ b/nexgb/xgbgen/go_request_reply.go @@ -8,30 +8,51 @@ import ( func (r *Request) Define(c *Context) { c.Putln("// Request %s", r.SrcName()) c.Putln("// size: %s", r.Size(c)) + c.Putln("type %s cookie", r.CookieName()) 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("func (c *Conn) %s(%s) %s {", + r.SrcName(), r.ParamNameTypes(), r.CookieName()) + c.Putln("cookie := c.newCookie(true, true)") + c.Putln("c.newRequest(%s(%s), cookie)", r.ReqName(), r.ParamNames()) + c.Putln("return %s(cookie)", r.CookieName()) + c.Putln("}") + c.Putln("") + + c.Putln("func (c *Conn) %sUnchecked(%s) %s {", + r.SrcName(), r.ParamNameTypes(), r.CookieName()) + c.Putln("cookie := c.newCookie(false, true)") + c.Putln("c.newRequest(%s(%s), cookie)", r.ReqName(), r.ParamNames()) + c.Putln("return %s(cookie)", r.CookieName()) 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("func (c *Conn) %s(%s) %s {", + r.SrcName(), r.ParamNameTypes(), r.CookieName()) + c.Putln("cookie := c.newCookie(false, false)") + c.Putln("c.newRequest(%s(%s), cookie)", r.ReqName(), r.ParamNames()) + c.Putln("return %s(cookie)", r.CookieName()) + c.Putln("}") + c.Putln("") + + c.Putln("func (c *Conn) %sChecked(%s) %s {", + r.SrcName(), r.ParamNameTypes(), r.CookieName()) + c.Putln("cookie := c.newCookie(true, false)") + c.Putln("c.newRequest(%s(%s), cookie)", r.ReqName(), r.ParamNames()) + c.Putln("return %s(cookie)", r.CookieName()) c.Putln("}") c.Putln("") } + + r.WriteRequest(c) } 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("type %s struct {", r.ReplyTypeName()) c.Putln("Sequence uint16") c.Putln("Length uint32") for _, field := range r.Reply.Fields { @@ -40,15 +61,21 @@ func (r *Request) ReadReply(c *Context) { 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("// Waits and reads reply data from request %s", r.SrcName()) + c.Putln("func (cook %s) Reply() (*%s, error) {", + r.CookieName(), r.ReplyTypeName()) + c.Putln("buf, err := cookie(cook).reply()") + c.Putln("if err != nil {") + c.Putln("return nil, err") + c.Putln("}") + c.Putln("return %s(buf), nil", r.ReplyName()) c.Putln("}") c.Putln("") - c.Putln("v := new(%s)", r.ReplyName()) + + c.Putln("// Read reply into structure from buffer for %s", r.SrcName()) + c.Putln("func %s(buf []byte) *%s {", + r.ReplyName(), r.ReplyTypeName()) + c.Putln("v := new(%s)", r.ReplyTypeName()) c.Putln("b := 1 // skip reply determinant") c.Putln("") for i, field := range r.Reply.Fields { @@ -63,21 +90,14 @@ func (r *Request) ReadReply(c *Context) { field.Read(c, "v.") c.Putln("") } - c.Putln("return v, nil") + c.Putln("return v") 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("func %s(%s) []byte {", r.ReqName(), r.ParamNameTypes()) c.Putln("size := %s", r.Size(c)) c.Putln("b := 0") c.Putln("buf := make([]byte, size)") @@ -85,6 +105,12 @@ func (r *Request) WriteRequestFields(c *Context) { c.Putln("buf[b] = %d // request opcode", r.Opcode) c.Putln("b += 1") c.Putln("") + if strings.ToLower(c.protocol.Name) != "xproto" { + c.Putln("buf[b] = c.extensions[\"%s\"]", + strings.ToUpper(c.protocol.ExtXName)) + c.Putln("b += 1") + c.Putln("") + } for i, field := range r.Fields { if i == 1 { c.Putln("Put16(buf[b:], uint16(size / 4)) "+ @@ -95,6 +121,9 @@ func (r *Request) WriteRequestFields(c *Context) { field.Write(c, "") c.Putln("") } + c.Putln("return buf") + c.Putln("}") + c.Putln("") } func (r *Request) ParamNames() string { @@ -102,7 +131,10 @@ func (r *Request) ParamNames() string { for _, field := range r.Fields { switch f := field.(type) { case *ValueField: - names = append(names, f.MaskName) + // mofos... + if r.SrcName() != "ConfigureWindow" { + names = append(names, f.MaskName) + } names = append(names, f.ListName) case *PadField: continue diff --git a/nexgb/xgbgen/representation.go b/nexgb/xgbgen/representation.go index ef62157..be7accd 100644 --- a/nexgb/xgbgen/representation.go +++ b/nexgb/xgbgen/representation.go @@ -3,6 +3,7 @@ package main import ( "fmt" "log" + "unicode" ) type Protocol struct { @@ -58,6 +59,16 @@ func (r *Request) XmlName() string { } func (r *Request) ReplyName() string { + if r.Reply == nil { + log.Panicf("Cannot call 'ReplyName' on request %s, which has no reply.", + r.SrcName()) + } + name := r.SrcName() + lower := string(unicode.ToLower(rune(name[0]))) + name[1:] + return fmt.Sprintf("%sReply", lower) +} + +func (r *Request) ReplyTypeName() string { if r.Reply == nil { log.Panicf("Cannot call 'ReplyName' on request %s, which has no reply.", r.SrcName()) @@ -66,7 +77,13 @@ func (r *Request) ReplyName() string { } func (r *Request) ReqName() string { - return fmt.Sprintf("%sRequest", r.SrcName()) + name := r.SrcName() + lower := string(unicode.ToLower(rune(name[0]))) + name[1:] + return fmt.Sprintf("%sRequest", lower) +} + +func (r *Request) CookieName() string { + return fmt.Sprintf("%sCookie", r.SrcName()) } // Size for Request needs a context. @@ -99,7 +116,9 @@ func (r *Request) Size(c *Context) Size { size = size.Add(field.Size()) } } - return size + return newExpressionSize(&Padding{ + Expr: size.Expression, + }) } type Reply struct {