github.com/BurntSushi/xgb@v0.0.0-20210121224620-deaf085860bc/xgbgen/go_struct.go (about) 1 package main 2 3 func (s *Struct) Define(c *Context) { 4 c.Putln("type %s struct {", s.SrcName()) 5 for _, field := range s.Fields { 6 field.Define(c) 7 } 8 c.Putln("}") 9 c.Putln("") 10 11 // Write function that reads bytes and produces this struct. 12 s.Read(c) 13 14 // Write function that reads bytes and produces a list of this struct. 15 s.ReadList(c) 16 17 // Write function that writes bytes given this struct. 18 s.Write(c) 19 20 // Write function that writes a list of this struct. 21 s.WriteList(c) 22 23 // Write function that computes the size of a list of these structs, 24 // IF there is a list field in this struct. 25 if s.HasList() { 26 s.WriteListSize(c) 27 } 28 } 29 30 // Read for a struct creates a function 'ReadStructName' that takes a source 31 // byte slice (i.e., the buffer) and a destination struct, and returns 32 // the number of bytes read off the buffer. 33 // 'ReadStructName' should only be used to read raw reply data from the wire. 34 func (s *Struct) Read(c *Context) { 35 c.Putln("// %sRead reads a byte slice into a %s value.", 36 s.SrcName(), s.SrcName()) 37 c.Putln("func %sRead(buf []byte, v *%s) int {", s.SrcName(), s.SrcName()) 38 39 c.Putln("b := 0") 40 c.Putln("") 41 for _, field := range s.Fields { 42 field.Read(c, "v.") 43 c.Putln("") 44 } 45 c.Putln("return b") 46 47 c.Putln("}") 48 c.Putln("") 49 } 50 51 // ReadList for a struct creates a function 'ReadStructNameList' that takes 52 // a source (i.e., the buffer) byte slice, and a destination slice and returns 53 // the number of bytes read from the byte slice. 54 func (s *Struct) ReadList(c *Context) { 55 c.Putln("// %sReadList reads a byte slice into a list of %s values.", 56 s.SrcName(), s.SrcName()) 57 c.Putln("func %sReadList(buf []byte, dest []%s) int {", 58 s.SrcName(), s.SrcName()) 59 c.Putln("b := 0") 60 c.Putln("for i := 0; i < len(dest); i++ {") 61 c.Putln("dest[i] = %s{}", s.SrcName()) 62 c.Putln("b += %sRead(buf[b:], &dest[i])", s.SrcName()) 63 c.Putln("}") 64 65 c.Putln("return xgb.Pad(b)") 66 67 c.Putln("}") 68 c.Putln("") 69 } 70 71 func (s *Struct) Write(c *Context) { 72 c.Putln("// Bytes writes a %s value to a byte slice.", s.SrcName()) 73 c.Putln("func (v %s) Bytes() []byte {", s.SrcName()) 74 c.Putln("buf := make([]byte, %s)", s.Size().Reduce("v.")) 75 c.Putln("b := 0") 76 c.Putln("") 77 for _, field := range s.Fields { 78 field.Write(c, "v.") 79 c.Putln("") 80 } 81 c.Putln("return buf[:b]") 82 c.Putln("}") 83 c.Putln("") 84 } 85 86 func (s *Struct) WriteList(c *Context) { 87 c.Putln("// %sListBytes writes a list of %s values to a byte slice.", 88 s.SrcName(), s.SrcName()) 89 c.Putln("func %sListBytes(buf []byte, list []%s) int {", 90 s.SrcName(), s.SrcName()) 91 c.Putln("b := 0") 92 c.Putln("var structBytes []byte") 93 c.Putln("for _, item := range list {") 94 c.Putln("structBytes = item.Bytes()") 95 c.Putln("copy(buf[b:], structBytes)") 96 c.Putln("b += len(structBytes)") 97 c.Putln("}") 98 c.Putln("return xgb.Pad(b)") 99 c.Putln("}") 100 c.Putln("") 101 } 102 103 func (s *Struct) WriteListSize(c *Context) { 104 c.Putln("// %sListSize computes the size (bytes) of a list of %s values.", 105 s.SrcName(), s.SrcName()) 106 c.Putln("func %sListSize(list []%s) int {", s.SrcName(), s.SrcName()) 107 c.Putln("size := 0") 108 if s.Size().Expression.Concrete() { 109 c.Putln("for _ = range list {") 110 } else { 111 c.Putln("for _, item := range list {") 112 } 113 c.Putln("size += %s", s.Size().Reduce("item.")) 114 c.Putln("}") 115 c.Putln("return size") 116 c.Putln("}") 117 c.Putln("") 118 }