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  }