1 package main
2
3
4 func (u *Union) Define(c *Context) {
5 c.Putln("// %s is a represention of the %s union type.",
6 u.SrcName(), u.SrcName())
7 c.Putln("// Note that to *create* a Union, you should *never* create")
8 c.Putln("// this struct directly (unless you know what you're doing).")
9 c.Putln("// Instead use one of the following constructors for '%s':",
10 u.SrcName())
11 for _, field := range u.Fields {
12 c.Putln("// %s%sNew(%s %s) %s", u.SrcName(), field.SrcName(),
13 field.SrcName(), field.SrcType(), u.SrcName())
14 }
15
16 c.Putln("type %s struct {", u.SrcName())
17 for _, field := range u.Fields {
18 field.Define(c)
19 }
20 c.Putln("}")
21 c.Putln("")
22
23
24
25 u.New(c)
26
27
28 u.Read(c)
29
30
31 u.ReadList(c)
32
33
34 u.Write(c)
35
36
37 u.WriteList(c)
38 }
39
40 func (u *Union) New(c *Context) {
41 for _, field := range u.Fields {
42 c.Putln("// %s%sNew constructs a new %s union type with the %s field.",
43 u.SrcName(), field.SrcName(), u.SrcName(), field.SrcName())
44 c.Putln("func %s%sNew(%s %s) %s {",
45 u.SrcName(), field.SrcName(), field.SrcName(),
46 field.SrcType(), u.SrcName())
47 c.Putln("var b int")
48 c.Putln("buf := make([]byte, %s)", u.Size())
49 c.Putln("")
50 field.Write(c, "")
51 c.Putln("")
52 c.Putln("// Create the Union type")
53 c.Putln("v := %s{}", u.SrcName())
54 c.Putln("")
55 c.Putln("// Now copy buf into all fields")
56 c.Putln("")
57 for _, field2 := range u.Fields {
58 c.Putln("b = 0 // always read the same bytes")
59 field2.Read(c, "v.")
60 c.Putln("")
61 }
62 c.Putln("return v")
63 c.Putln("}")
64 c.Putln("")
65 }
66 }
67
68 func (u *Union) Read(c *Context) {
69 c.Putln("// %sRead reads a byte slice into a %s value.",
70 u.SrcName(), u.SrcName())
71 c.Putln("func %sRead(buf []byte, v *%s) int {", u.SrcName(), u.SrcName())
72 c.Putln("var b int")
73 c.Putln("")
74 for _, field := range u.Fields {
75 c.Putln("b = 0 // re-read the same bytes")
76 field.Read(c, "v.")
77 c.Putln("")
78 }
79 c.Putln("return %s", u.Size())
80 c.Putln("}")
81 c.Putln("")
82 }
83
84 func (u *Union) ReadList(c *Context) {
85 c.Putln("// %sReadList reads a byte slice into a list of %s values.",
86 u.SrcName(), u.SrcName())
87 c.Putln("func %sReadList(buf []byte, dest []%s) int {",
88 u.SrcName(), u.SrcName())
89 c.Putln("b := 0")
90 c.Putln("for i := 0; i < len(dest); i++ {")
91 c.Putln("dest[i] = %s{}", u.SrcName())
92 c.Putln("b += %sRead(buf[b:], &dest[i])", u.SrcName())
93 c.Putln("}")
94 c.Putln("return xgb.Pad(b)")
95 c.Putln("}")
96 c.Putln("")
97 }
98
99
100
101
102
103
104 func (u *Union) Write(c *Context) {
105 c.Putln("// Bytes writes a %s value to a byte slice.", u.SrcName())
106 c.Putln("// Each field in a union must contain the same data.")
107 c.Putln("// So simply pick the first field and write that to the wire.")
108 c.Putln("func (v %s) Bytes() []byte {", u.SrcName())
109 c.Putln("buf := make([]byte, %s)", u.Size().Reduce("v."))
110 c.Putln("b := 0")
111 c.Putln("")
112 u.Fields[0].Write(c, "v.")
113 c.Putln("return buf")
114 c.Putln("}")
115 c.Putln("")
116 }
117
118 func (u *Union) WriteList(c *Context) {
119 c.Putln("// %sListBytes writes a list of %s values to a byte slice.",
120 u.SrcName(), u.SrcName())
121 c.Putln("func %sListBytes(buf []byte, list []%s) int {",
122 u.SrcName(), u.SrcName())
123 c.Putln("b := 0")
124 c.Putln("var unionBytes []byte")
125 c.Putln("for _, item := range list {")
126 c.Putln("unionBytes = item.Bytes()")
127 c.Putln("copy(buf[b:], unionBytes)")
128 c.Putln("b += xgb.Pad(len(unionBytes))")
129 c.Putln("}")
130 c.Putln("return b")
131 c.Putln("}")
132 c.Putln("")
133 }
134
135 func (u *Union) WriteListSize(c *Context) {
136 c.Putln("// Union list size %s", u.SrcName())
137 c.Putln("// %sListSize computes the size (bytes) of a list of %s values.",
138 u.SrcName())
139 c.Putln("func %sListSize(list []%s) int {", u.SrcName(), u.SrcName())
140 c.Putln("size := 0")
141 c.Putln("for _, item := range list {")
142 c.Putln("size += %s", u.Size().Reduce("item."))
143 c.Putln("}")
144 c.Putln("return size")
145 c.Putln("}")
146 c.Putln("")
147 }
148
View as plain text