1 package main
2
3 import (
4 "fmt"
5 "log"
6 "strings"
7 )
8
9
10
11
12
13
14
15 type Field interface {
16
17 Initialize(p *Protocol)
18
19
20 SrcName() string
21
22
23 XmlName() string
24
25
26 SrcType() string
27
28
29
30 Size() Size
31
32
33 Define(c *Context)
34
35
36
37
38 Read(c *Context, prefix string)
39
40
41
42
43 Write(c *Context, prefix string)
44 }
45
46 func (pad *PadField) Initialize(p *Protocol) {}
47
48
49
50
51 type PadField struct {
52 Bytes uint
53 Align uint16
54 }
55
56 func (p *PadField) SrcName() string {
57 panic("illegal to take source name of a pad field")
58 }
59
60 func (p *PadField) XmlName() string {
61 panic("illegal to take XML name of a pad field")
62 }
63
64 func (f *PadField) SrcType() string {
65 panic("it is illegal to call SrcType on a PadField field")
66 }
67
68 func (p *PadField) Size() Size {
69 if p.Align > 0 {
70 return newFixedSize(uint(p.Align), false)
71 } else {
72 return newFixedSize(p.Bytes, true)
73 }
74 }
75
76
77
78 type SingleField struct {
79 srcName string
80 xmlName string
81 Type Type
82 }
83
84 func (f *SingleField) Initialize(p *Protocol) {
85 f.srcName = SrcName(p, f.XmlName())
86 f.Type = f.Type.(*Translation).RealType(p)
87 }
88
89 func (f *SingleField) SrcName() string {
90 if f.srcName == "Bytes" {
91 return "Bytes_"
92 }
93 return f.srcName
94 }
95
96 func (f *SingleField) XmlName() string {
97 return f.xmlName
98 }
99
100 func (f *SingleField) SrcType() string {
101 return f.Type.SrcName()
102 }
103
104 func (f *SingleField) Size() Size {
105 return f.Type.Size()
106 }
107
108
109 type ListField struct {
110 srcName string
111 xmlName string
112 Type Type
113 LengthExpr Expression
114 }
115
116 func (f *ListField) SrcName() string {
117 return f.srcName
118 }
119
120 func (f *ListField) XmlName() string {
121 return f.xmlName
122 }
123
124 func (f *ListField) SrcType() string {
125 if strings.ToLower(f.Type.XmlName()) == "char" {
126 return fmt.Sprintf("string")
127 }
128 return fmt.Sprintf("[]%s", f.Type.SrcName())
129 }
130
131
132
133
134 func (f *ListField) Length() Size {
135 if f.LengthExpr == nil {
136 return newExpressionSize(&Function{
137 Name: "len",
138 Expr: &FieldRef{
139 Name: f.SrcName(),
140 },
141 }, true)
142 }
143 return newExpressionSize(f.LengthExpr, true)
144 }
145
146
147
148
149
150
151
152 func (f *ListField) Size() Size {
153 elsz := f.Type.Size()
154 simpleLen := &Padding{
155 Expr: newBinaryOp("*", f.Length().Expression, elsz.Expression),
156 }
157
158 switch field := f.Type.(type) {
159 case *Struct:
160 if field.HasList() {
161 sizeFun := &Function{
162 Name: fmt.Sprintf("%sListSize", f.Type.SrcName()),
163 Expr: &FieldRef{Name: f.SrcName()},
164 }
165 return newExpressionSize(sizeFun, elsz.exact)
166 } else {
167 return newExpressionSize(simpleLen, elsz.exact)
168 }
169 case *Union:
170 return newExpressionSize(simpleLen, elsz.exact)
171 case *Base:
172 return newExpressionSize(simpleLen, elsz.exact)
173 case *Resource:
174 return newExpressionSize(simpleLen, elsz.exact)
175 case *TypeDef:
176 return newExpressionSize(simpleLen, elsz.exact)
177 default:
178 log.Panicf("Cannot compute list size with type '%T'.", f.Type)
179 }
180 panic("unreachable")
181 }
182
183 func (f *ListField) Initialize(p *Protocol) {
184 f.srcName = SrcName(p, f.XmlName())
185 f.Type = f.Type.(*Translation).RealType(p)
186 if f.LengthExpr != nil {
187 f.LengthExpr.Initialize(p)
188 }
189 }
190
191
192
193 type LocalField struct {
194 *SingleField
195 }
196
197
198
199 type ExprField struct {
200 srcName string
201 xmlName string
202 Type Type
203 Expr Expression
204 }
205
206 func (f *ExprField) SrcName() string {
207 return f.srcName
208 }
209
210 func (f *ExprField) XmlName() string {
211 return f.xmlName
212 }
213
214 func (f *ExprField) SrcType() string {
215 return f.Type.SrcName()
216 }
217
218 func (f *ExprField) Size() Size {
219 return f.Type.Size()
220 }
221
222 func (f *ExprField) Initialize(p *Protocol) {
223 f.srcName = SrcName(p, f.XmlName())
224 f.Type = f.Type.(*Translation).RealType(p)
225 f.Expr.Initialize(p)
226 }
227
228
229
230
231 type ValueField struct {
232 Parent interface{}
233 MaskType Type
234 MaskName string
235 ListName string
236 }
237
238 func (f *ValueField) SrcName() string {
239 panic("it is illegal to call SrcName on a ValueField field")
240 }
241
242 func (f *ValueField) XmlName() string {
243 panic("it is illegal to call XmlName on a ValueField field")
244 }
245
246 func (f *ValueField) SrcType() string {
247 return f.MaskType.SrcName()
248 }
249
250
251
252
253
254 func (f *ValueField) Size() Size {
255 maskSize := f.MaskType.Size()
256 listSize := newExpressionSize(&Function{
257 Name: "xgb.Pad",
258 Expr: &BinaryOp{
259 Op: "*",
260 Expr1: &Value{v: 4},
261 Expr2: &PopCount{
262 Expr: &Function{
263 Name: "int",
264 Expr: &FieldRef{
265 Name: f.MaskName,
266 },
267 },
268 },
269 },
270 }, true)
271 return maskSize.Add(listSize)
272 }
273
274 func (f *ValueField) ListLength() Size {
275 return newExpressionSize(&PopCount{
276 Expr: &Function{
277 Name: "int",
278 Expr: &FieldRef{
279 Name: f.MaskName,
280 },
281 },
282 }, true)
283 }
284
285 func (f *ValueField) Initialize(p *Protocol) {
286 f.MaskType = f.MaskType.(*Translation).RealType(p)
287 f.MaskName = SrcName(p, f.MaskName)
288 f.ListName = SrcName(p, f.ListName)
289 }
290
291
292
293 type SwitchField struct {
294 Name string
295 Expr Expression
296 Bitcases []*Bitcase
297 }
298
299 func (f *SwitchField) SrcName() string {
300 panic("it is illegal to call SrcName on a SwitchField field")
301 }
302
303 func (f *SwitchField) XmlName() string {
304 panic("it is illegal to call XmlName on a SwitchField field")
305 }
306
307 func (f *SwitchField) SrcType() string {
308 panic("it is illegal to call SrcType on a SwitchField field")
309 }
310
311
312
313
314 func (f *SwitchField) Size() Size {
315 return newFixedSize(0, true)
316 }
317
318 func (f *SwitchField) Initialize(p *Protocol) {
319 f.Name = SrcName(p, f.Name)
320 f.Expr.Initialize(p)
321 for _, bitcase := range f.Bitcases {
322 bitcase.Expr.Initialize(p)
323 for _, field := range bitcase.Fields {
324 field.Initialize(p)
325 }
326 }
327 }
328
329
330
331 type Bitcase struct {
332 Fields []Field
333 Expr Expression
334 }
335
View as plain text