diff options
Diffstat (limited to 'nexgb/xgbgen/field.go')
-rw-r--r-- | nexgb/xgbgen/field.go | 60 |
1 files changed, 55 insertions, 5 deletions
diff --git a/nexgb/xgbgen/field.go b/nexgb/xgbgen/field.go index 5041f77..725f3de 100644 --- a/nexgb/xgbgen/field.go +++ b/nexgb/xgbgen/field.go @@ -6,20 +6,48 @@ import ( "strings" ) +// Field corresponds to any field described in an XML protocol description +// file. This includes struct fields, union fields, request fields, +// reply fields and so on. +// To make code generation easier, fields that have types are also stored. +// Note that not all fields support all methods defined in this interface. +// For instance, a padding field does not have a source name. type Field interface { + // Initialize sets up the source name of this field. Initialize(p *Protocol) + + // SrcName is the Go source name of this field. SrcName() string + + // XmlName is the name of this field from the XML file. XmlName() string + + // SrcType is the Go source type name of this field. SrcType() string + + // Size returns an expression that computes the size (in bytes) + // of this field. Size() Size + // Define writes the Go code to declare this field (in a struct definition). Define(c *Context) + + // Read writes the Go code to convert a byte slice to a Go value + // of this field. + // 'prefix' is the prefix of the name of the Go value. Read(c *Context, prefix string) + + // Write writes the Go code to convert a Go value to a byte slice of + // this field. + // 'prefix' is the prefix of the name of the Go value. Write(c *Context, prefix string) } func (pad *PadField) Initialize(p *Protocol) {} +// PadField represents any type of padding. It is omitted from +// definitions, but is used in Read/Write to increment the buffer index. +// It is also used in size calculation. type PadField struct { Bytes uint } @@ -40,6 +68,8 @@ func (p *PadField) Size() Size { return newFixedSize(p.Bytes) } +// SingleField represents most of the fields in an XML protocol description. +// It corresponds to any single value. type SingleField struct { srcName string xmlName string @@ -67,6 +97,7 @@ func (f *SingleField) Size() Size { return f.Type.Size() } +// ListField represents a list of values. type ListField struct { srcName string xmlName string @@ -89,6 +120,9 @@ func (f *ListField) SrcType() string { return fmt.Sprintf("[]%s", f.Type.SrcName()) } +// Length computes the *number* of values in a list. +// If this ListField does not have any length expression, we throw our hands +// up and simply compute the 'len' of the field name of this list. func (f *ListField) Length() Size { if f.LengthExpr == nil { return newExpressionSize(&Function{ @@ -101,6 +135,12 @@ func (f *ListField) Length() Size { return newExpressionSize(f.LengthExpr) } +// Size computes the *size* of a list (in bytes). +// It it typically a simple matter of multiplying the length of the list by +// the size of the type of the list. +// But if it's a list of struct where the struct has a list field, we use a +// special function written in go_struct.go to compute the size (since the +// size in this case can only be computed recursively). func (f *ListField) Size() Size { simpleLen := &Function{ Name: "pad", @@ -120,11 +160,6 @@ func (f *ListField) Size() Size { } case *Union: return newExpressionSize(simpleLen) - // sizeFun := &Function{ - // Name: fmt.Sprintf("%sListSize", f.Type.SrcName()), - // Expr: &FieldRef{Name: f.SrcName()}, - // } - // return newExpressionSize(sizeFun) case *Base: return newExpressionSize(simpleLen) case *Resource: @@ -145,10 +180,14 @@ func (f *ListField) Initialize(p *Protocol) { } } +// LocalField is exactly the same as a regular SingleField, except it isn't +// sent over the wire. (i.e., it's probably used to compute an ExprField). type LocalField struct { *SingleField } +// ExprField is a field that is not parameterized, but is computed from values +// of other fields. type ExprField struct { srcName string xmlName string @@ -178,6 +217,9 @@ func (f *ExprField) Initialize(p *Protocol) { f.Expr.Initialize(p) } +// ValueField represents two fields in one: a mask and a list of 4-byte +// integers. The mask specifies which kinds of values are in the list. +// (i.e., See ConfigureWindow, CreateWindow, ChangeWindowAttributes, etc.) type ValueField struct { Parent interface{} MaskType Type @@ -197,6 +239,10 @@ func (f *ValueField) SrcType() string { return f.MaskType.SrcName() } +// Size computes the size in bytes of the combination of the mask and list +// in this value field. +// The expression to compute this looks complicated, but it's really just +// the number of bits set in the mask multiplied 4 (and padded of course). func (f *ValueField) Size() Size { maskSize := f.MaskType.Size() listSize := newExpressionSize(&Function{ @@ -234,6 +280,8 @@ func (f *ValueField) Initialize(p *Protocol) { f.ListName = SrcName(p, f.ListName) } +// SwitchField represents a 'switch' element in the XML protocol description +// file. It is not currently used. (i.e., it is XKB voodoo.) type SwitchField struct { Name string Expr Expression @@ -270,6 +318,8 @@ func (f *SwitchField) Initialize(p *Protocol) { } } +// Bitcase represents a single bitcase inside a switch expression. +// It is not currently used. (i.e., it's XKB voodoo.) type Bitcase struct { Fields []Field Expr Expression |