github.com/BurntSushi/xgb@v0.0.0-20210121224620-deaf085860bc/xgbgen/go_list.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strings"
     7  )
     8  
     9  // List fields
    10  func (f *ListField) Define(c *Context) {
    11  	c.Putln("%s %s // size: %s",
    12  		f.SrcName(), f.SrcType(), f.Size())
    13  }
    14  
    15  func (f *ListField) Read(c *Context, prefix string) {
    16  	switch t := f.Type.(type) {
    17  	case *Resource:
    18  		length := f.LengthExpr.Reduce(prefix)
    19  		c.Putln("%s%s = make([]%s, %s)",
    20  			prefix, f.SrcName(), t.SrcName(), length)
    21  		c.Putln("for i := 0; i < int(%s); i++ {", length)
    22  		ReadSimpleSingleField(c, fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t)
    23  		c.Putln("}")
    24  	case *Base:
    25  		length := f.LengthExpr.Reduce(prefix)
    26  		if strings.ToLower(t.XmlName()) == "char" {
    27  			c.Putln("{")
    28  			c.Putln("byteString := make([]%s, %s)", t.SrcName(), length)
    29  			c.Putln("copy(byteString[:%s], buf[b:])", length)
    30  			c.Putln("%s%s = string(byteString)", prefix, f.SrcName())
    31  			// This is apparently a special case. The "Str" type itself
    32  			// doesn't specify any padding. I suppose it's up to the
    33  			// request/reply spec that uses it to get the padding right?
    34  			c.Putln("b += int(%s)", length)
    35  			c.Putln("}")
    36  		} else if t.SrcName() == "byte" {
    37  			c.Putln("%s%s = make([]%s, %s)",
    38  				prefix, f.SrcName(), t.SrcName(), length)
    39  			c.Putln("copy(%s%s[:%s], buf[b:])", prefix, f.SrcName(), length)
    40  			c.Putln("b += int(%s)", length)
    41  		} else {
    42  			c.Putln("%s%s = make([]%s, %s)",
    43  				prefix, f.SrcName(), t.SrcName(), length)
    44  			c.Putln("for i := 0; i < int(%s); i++ {", length)
    45  			ReadSimpleSingleField(c,
    46  				fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t)
    47  			c.Putln("}")
    48  		}
    49  	case *TypeDef:
    50  		length := f.LengthExpr.Reduce(prefix)
    51  		c.Putln("%s%s = make([]%s, %s)",
    52  			prefix, f.SrcName(), t.SrcName(), length)
    53  		c.Putln("for i := 0; i < int(%s); i++ {", length)
    54  		ReadSimpleSingleField(c, fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t)
    55  		c.Putln("}")
    56  	case *Union:
    57  		c.Putln("%s%s = make([]%s, %s)",
    58  			prefix, f.SrcName(), t.SrcName(), f.LengthExpr.Reduce(prefix))
    59  		c.Putln("b += %sReadList(buf[b:], %s%s)",
    60  			t.SrcName(), prefix, f.SrcName())
    61  	case *Struct:
    62  		c.Putln("%s%s = make([]%s, %s)",
    63  			prefix, f.SrcName(), t.SrcName(), f.LengthExpr.Reduce(prefix))
    64  		c.Putln("b += %sReadList(buf[b:], %s%s)",
    65  			t.SrcName(), prefix, f.SrcName())
    66  	default:
    67  		log.Panicf("Cannot read list field '%s' with %T type.",
    68  			f.XmlName(), f.Type)
    69  	}
    70  }
    71  
    72  func (f *ListField) Write(c *Context, prefix string) {
    73  	switch t := f.Type.(type) {
    74  	case *Resource:
    75  		length := f.Length().Reduce(prefix)
    76  		c.Putln("for i := 0; i < int(%s); i++ {", length)
    77  		WriteSimpleSingleField(c,
    78  			fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t)
    79  		c.Putln("}")
    80  	case *Base:
    81  		length := f.Length().Reduce(prefix)
    82  		if t.SrcName() == "byte" {
    83  			c.Putln("copy(buf[b:], %s%s[:%s])", prefix, f.SrcName(), length)
    84  			c.Putln("b += int(%s)", length)
    85  		} else {
    86  			c.Putln("for i := 0; i < int(%s); i++ {", length)
    87  			WriteSimpleSingleField(c,
    88  				fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t)
    89  			c.Putln("}")
    90  		}
    91  	case *TypeDef:
    92  		length := f.Length().Reduce(prefix)
    93  		c.Putln("for i := 0; i < int(%s); i++ {", length)
    94  		WriteSimpleSingleField(c,
    95  			fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t)
    96  		c.Putln("}")
    97  	case *Union:
    98  		c.Putln("b += %sListBytes(buf[b:], %s%s)",
    99  			t.SrcName(), prefix, f.SrcName())
   100  	case *Struct:
   101  		c.Putln("b += %sListBytes(buf[b:], %s%s)",
   102  			t.SrcName(), prefix, f.SrcName())
   103  	default:
   104  		log.Panicf("Cannot write list field '%s' with %T type.",
   105  			f.XmlName(), f.Type)
   106  	}
   107  }