aboutsummaryrefslogtreecommitdiff
path: root/nexgb/xgbgen/go_request_reply.go
diff options
context:
space:
mode:
Diffstat (limited to 'nexgb/xgbgen/go_request_reply.go')
-rw-r--r--nexgb/xgbgen/go_request_reply.go140
1 files changed, 140 insertions, 0 deletions
diff --git a/nexgb/xgbgen/go_request_reply.go b/nexgb/xgbgen/go_request_reply.go
new file mode 100644
index 0000000..e6180a1
--- /dev/null
+++ b/nexgb/xgbgen/go_request_reply.go
@@ -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, ",")
+}