inet.af/netstack@v0.0.0-20220214151720-7585b01ddccf/state/wire/wire.go (about)

     1  // Copyright 2020 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package wire contains a few basic types that can be composed to serialize
    16  // graph information for the state package. This package defines the wire
    17  // protocol.
    18  //
    19  // Note that these types are careful about how they implement the relevant
    20  // interfaces (either value receiver or pointer receiver), so that native-sized
    21  // types, such as integers and simple pointers, can fit inside the interface
    22  // object.
    23  //
    24  // This package also uses panic as control flow, so called should be careful to
    25  // wrap calls in appropriate handlers.
    26  //
    27  // Testing for this package is driven by the state test package.
    28  package wire
    29  
    30  import (
    31  	"fmt"
    32  	"io"
    33  	"math"
    34  
    35  	"inet.af/netstack/gohacks"
    36  )
    37  
    38  // Reader is the required reader interface.
    39  type Reader interface {
    40  	io.Reader
    41  	ReadByte() (byte, error)
    42  }
    43  
    44  // Writer is the required writer interface.
    45  type Writer interface {
    46  	io.Writer
    47  	WriteByte(byte) error
    48  }
    49  
    50  // readFull is a utility. The equivalent is not needed for Write, but the API
    51  // contract dictates that it must always complete all bytes given or return an
    52  // error.
    53  func readFull(r io.Reader, p []byte) {
    54  	for done := 0; done < len(p); {
    55  		n, err := r.Read(p[done:])
    56  		done += n
    57  		if n == 0 && err != nil {
    58  			panic(err)
    59  		}
    60  	}
    61  }
    62  
    63  // Object is a generic object.
    64  type Object interface {
    65  	// save saves the given object.
    66  	//
    67  	// Panic is used for error control flow.
    68  	save(Writer)
    69  
    70  	// load loads a new object of the given type.
    71  	//
    72  	// Panic is used for error control flow.
    73  	load(Reader) Object
    74  }
    75  
    76  // Bool is a boolean.
    77  type Bool bool
    78  
    79  // loadBool loads an object of type Bool.
    80  func loadBool(r Reader) Bool {
    81  	b := loadUint(r)
    82  	return Bool(b == 1)
    83  }
    84  
    85  // save implements Object.save.
    86  func (b Bool) save(w Writer) {
    87  	var v Uint
    88  	if b {
    89  		v = 1
    90  	} else {
    91  		v = 0
    92  	}
    93  	v.save(w)
    94  }
    95  
    96  // load implements Object.load.
    97  func (Bool) load(r Reader) Object { return loadBool(r) }
    98  
    99  // Int is a signed integer.
   100  //
   101  // This uses varint encoding.
   102  type Int int64
   103  
   104  // loadInt loads an object of type Int.
   105  func loadInt(r Reader) Int {
   106  	u := loadUint(r)
   107  	x := Int(u >> 1)
   108  	if u&1 != 0 {
   109  		x = ^x
   110  	}
   111  	return x
   112  }
   113  
   114  // save implements Object.save.
   115  func (i Int) save(w Writer) {
   116  	u := Uint(i) << 1
   117  	if i < 0 {
   118  		u = ^u
   119  	}
   120  	u.save(w)
   121  }
   122  
   123  // load implements Object.load.
   124  func (Int) load(r Reader) Object { return loadInt(r) }
   125  
   126  // Uint is an unsigned integer.
   127  type Uint uint64
   128  
   129  // loadUint loads an object of type Uint.
   130  func loadUint(r Reader) Uint {
   131  	var (
   132  		u Uint
   133  		s uint
   134  	)
   135  	for i := 0; i <= 9; i++ {
   136  		b, err := r.ReadByte()
   137  		if err != nil {
   138  			panic(err)
   139  		}
   140  		if b < 0x80 {
   141  			if i == 9 && b > 1 {
   142  				panic("overflow")
   143  			}
   144  			u |= Uint(b) << s
   145  			return u
   146  		}
   147  		u |= Uint(b&0x7f) << s
   148  		s += 7
   149  	}
   150  	panic("unreachable")
   151  }
   152  
   153  // save implements Object.save.
   154  func (u Uint) save(w Writer) {
   155  	for u >= 0x80 {
   156  		if err := w.WriteByte(byte(u) | 0x80); err != nil {
   157  			panic(err)
   158  		}
   159  		u >>= 7
   160  	}
   161  	if err := w.WriteByte(byte(u)); err != nil {
   162  		panic(err)
   163  	}
   164  }
   165  
   166  // load implements Object.load.
   167  func (Uint) load(r Reader) Object { return loadUint(r) }
   168  
   169  // Float32 is a 32-bit floating point number.
   170  type Float32 float32
   171  
   172  // loadFloat32 loads an object of type Float32.
   173  func loadFloat32(r Reader) Float32 {
   174  	n := loadUint(r)
   175  	return Float32(math.Float32frombits(uint32(n)))
   176  }
   177  
   178  // save implements Object.save.
   179  func (f Float32) save(w Writer) {
   180  	n := Uint(math.Float32bits(float32(f)))
   181  	n.save(w)
   182  }
   183  
   184  // load implements Object.load.
   185  func (Float32) load(r Reader) Object { return loadFloat32(r) }
   186  
   187  // Float64 is a 64-bit floating point number.
   188  type Float64 float64
   189  
   190  // loadFloat64 loads an object of type Float64.
   191  func loadFloat64(r Reader) Float64 {
   192  	n := loadUint(r)
   193  	return Float64(math.Float64frombits(uint64(n)))
   194  }
   195  
   196  // save implements Object.save.
   197  func (f Float64) save(w Writer) {
   198  	n := Uint(math.Float64bits(float64(f)))
   199  	n.save(w)
   200  }
   201  
   202  // load implements Object.load.
   203  func (Float64) load(r Reader) Object { return loadFloat64(r) }
   204  
   205  // Complex64 is a 64-bit complex number.
   206  type Complex64 complex128
   207  
   208  // loadComplex64 loads an object of type Complex64.
   209  func loadComplex64(r Reader) Complex64 {
   210  	re := loadFloat32(r)
   211  	im := loadFloat32(r)
   212  	return Complex64(complex(float32(re), float32(im)))
   213  }
   214  
   215  // save implements Object.save.
   216  func (c *Complex64) save(w Writer) {
   217  	re := Float32(real(*c))
   218  	im := Float32(imag(*c))
   219  	re.save(w)
   220  	im.save(w)
   221  }
   222  
   223  // load implements Object.load.
   224  func (*Complex64) load(r Reader) Object {
   225  	c := loadComplex64(r)
   226  	return &c
   227  }
   228  
   229  // Complex128 is a 128-bit complex number.
   230  type Complex128 complex128
   231  
   232  // loadComplex128 loads an object of type Complex128.
   233  func loadComplex128(r Reader) Complex128 {
   234  	re := loadFloat64(r)
   235  	im := loadFloat64(r)
   236  	return Complex128(complex(float64(re), float64(im)))
   237  }
   238  
   239  // save implements Object.save.
   240  func (c *Complex128) save(w Writer) {
   241  	re := Float64(real(*c))
   242  	im := Float64(imag(*c))
   243  	re.save(w)
   244  	im.save(w)
   245  }
   246  
   247  // load implements Object.load.
   248  func (*Complex128) load(r Reader) Object {
   249  	c := loadComplex128(r)
   250  	return &c
   251  }
   252  
   253  // String is a string.
   254  type String string
   255  
   256  // loadString loads an object of type String.
   257  func loadString(r Reader) String {
   258  	l := loadUint(r)
   259  	p := make([]byte, l)
   260  	readFull(r, p)
   261  	return String(gohacks.StringFromImmutableBytes(p))
   262  }
   263  
   264  // save implements Object.save.
   265  func (s *String) save(w Writer) {
   266  	l := Uint(len(*s))
   267  	l.save(w)
   268  	p := gohacks.ImmutableBytesFromString(string(*s))
   269  	_, err := w.Write(p) // Must write all bytes.
   270  	if err != nil {
   271  		panic(err)
   272  	}
   273  }
   274  
   275  // load implements Object.load.
   276  func (*String) load(r Reader) Object {
   277  	s := loadString(r)
   278  	return &s
   279  }
   280  
   281  // Dot is a kind of reference: one of Index and FieldName.
   282  type Dot interface {
   283  	isDot()
   284  }
   285  
   286  // Index is a reference resolution.
   287  type Index uint32
   288  
   289  func (Index) isDot() {}
   290  
   291  // FieldName is a reference resolution.
   292  type FieldName string
   293  
   294  func (*FieldName) isDot() {}
   295  
   296  // Ref is a reference to an object.
   297  type Ref struct {
   298  	// Root is the root object.
   299  	Root Uint
   300  
   301  	// Dots is the set of traversals required from the Root object above.
   302  	// Note that this will be stored in reverse order for efficiency.
   303  	Dots []Dot
   304  
   305  	// Type is the base type for the root object. This is non-nil iff Dots
   306  	// is non-zero length (that is, this is a complex reference). This is
   307  	// not *strictly* necessary, but can be used to simplify decoding.
   308  	Type TypeSpec
   309  }
   310  
   311  // loadRef loads an object of type Ref (abstract).
   312  func loadRef(r Reader) Ref {
   313  	ref := Ref{
   314  		Root: loadUint(r),
   315  	}
   316  	l := loadUint(r)
   317  	ref.Dots = make([]Dot, l)
   318  	for i := 0; i < int(l); i++ {
   319  		// Disambiguate between an Index (non-negative) and a field
   320  		// name (negative). This does some space and avoids a dedicate
   321  		// loadDot function. See Ref.save for the other side.
   322  		d := loadInt(r)
   323  		if d >= 0 {
   324  			ref.Dots[i] = Index(d)
   325  			continue
   326  		}
   327  		p := make([]byte, -d)
   328  		readFull(r, p)
   329  		fieldName := FieldName(gohacks.StringFromImmutableBytes(p))
   330  		ref.Dots[i] = &fieldName
   331  	}
   332  	if l != 0 {
   333  		// Only if dots is non-zero.
   334  		ref.Type = loadTypeSpec(r)
   335  	}
   336  	return ref
   337  }
   338  
   339  // save implements Object.save.
   340  func (r *Ref) save(w Writer) {
   341  	r.Root.save(w)
   342  	l := Uint(len(r.Dots))
   343  	l.save(w)
   344  	for _, d := range r.Dots {
   345  		// See LoadRef. We use non-negative numbers to encode Index
   346  		// objects and negative numbers to encode field lengths.
   347  		switch x := d.(type) {
   348  		case Index:
   349  			i := Int(x)
   350  			i.save(w)
   351  		case *FieldName:
   352  			d := Int(-len(*x))
   353  			d.save(w)
   354  			p := gohacks.ImmutableBytesFromString(string(*x))
   355  			if _, err := w.Write(p); err != nil {
   356  				panic(err)
   357  			}
   358  		default:
   359  			panic("unknown dot implementation")
   360  		}
   361  	}
   362  	if l != 0 {
   363  		// See above.
   364  		saveTypeSpec(w, r.Type)
   365  	}
   366  }
   367  
   368  // load implements Object.load.
   369  func (*Ref) load(r Reader) Object {
   370  	ref := loadRef(r)
   371  	return &ref
   372  }
   373  
   374  // Nil is a primitive zero value of any type.
   375  type Nil struct{}
   376  
   377  // loadNil loads an object of type Nil.
   378  func loadNil(r Reader) Nil {
   379  	return Nil{}
   380  }
   381  
   382  // save implements Object.save.
   383  func (Nil) save(w Writer) {}
   384  
   385  // load implements Object.load.
   386  func (Nil) load(r Reader) Object { return loadNil(r) }
   387  
   388  // Slice is a slice value.
   389  type Slice struct {
   390  	Length   Uint
   391  	Capacity Uint
   392  	Ref      Ref
   393  }
   394  
   395  // loadSlice loads an object of type Slice.
   396  func loadSlice(r Reader) Slice {
   397  	return Slice{
   398  		Length:   loadUint(r),
   399  		Capacity: loadUint(r),
   400  		Ref:      loadRef(r),
   401  	}
   402  }
   403  
   404  // save implements Object.save.
   405  func (s *Slice) save(w Writer) {
   406  	s.Length.save(w)
   407  	s.Capacity.save(w)
   408  	s.Ref.save(w)
   409  }
   410  
   411  // load implements Object.load.
   412  func (*Slice) load(r Reader) Object {
   413  	s := loadSlice(r)
   414  	return &s
   415  }
   416  
   417  // Array is an array value.
   418  type Array struct {
   419  	Contents []Object
   420  }
   421  
   422  // loadArray loads an object of type Array.
   423  func loadArray(r Reader) Array {
   424  	l := loadUint(r)
   425  	if l == 0 {
   426  		// Note that there isn't a single object available to encode
   427  		// the type of, so we need this additional branch.
   428  		return Array{}
   429  	}
   430  	// All the objects here have the same type, so use dynamic dispatch
   431  	// only once. All other objects will automatically take the same type
   432  	// as the first object.
   433  	contents := make([]Object, l)
   434  	v := Load(r)
   435  	contents[0] = v
   436  	for i := 1; i < int(l); i++ {
   437  		contents[i] = v.load(r)
   438  	}
   439  	return Array{
   440  		Contents: contents,
   441  	}
   442  }
   443  
   444  // save implements Object.save.
   445  func (a *Array) save(w Writer) {
   446  	l := Uint(len(a.Contents))
   447  	l.save(w)
   448  	if l == 0 {
   449  		// See LoadArray.
   450  		return
   451  	}
   452  	// See above.
   453  	Save(w, a.Contents[0])
   454  	for i := 1; i < int(l); i++ {
   455  		a.Contents[i].save(w)
   456  	}
   457  }
   458  
   459  // load implements Object.load.
   460  func (*Array) load(r Reader) Object {
   461  	a := loadArray(r)
   462  	return &a
   463  }
   464  
   465  // Map is a map value.
   466  type Map struct {
   467  	Keys   []Object
   468  	Values []Object
   469  }
   470  
   471  // loadMap loads an object of type Map.
   472  func loadMap(r Reader) Map {
   473  	l := loadUint(r)
   474  	if l == 0 {
   475  		// See LoadArray.
   476  		return Map{}
   477  	}
   478  	// See type dispatch notes in Array.
   479  	keys := make([]Object, l)
   480  	values := make([]Object, l)
   481  	k := Load(r)
   482  	v := Load(r)
   483  	keys[0] = k
   484  	values[0] = v
   485  	for i := 1; i < int(l); i++ {
   486  		keys[i] = k.load(r)
   487  		values[i] = v.load(r)
   488  	}
   489  	return Map{
   490  		Keys:   keys,
   491  		Values: values,
   492  	}
   493  }
   494  
   495  // save implements Object.save.
   496  func (m *Map) save(w Writer) {
   497  	l := Uint(len(m.Keys))
   498  	if int(l) != len(m.Values) {
   499  		panic(fmt.Sprintf("mismatched keys (%d) Aand values (%d)", len(m.Keys), len(m.Values)))
   500  	}
   501  	l.save(w)
   502  	if l == 0 {
   503  		// See LoadArray.
   504  		return
   505  	}
   506  	// See above.
   507  	Save(w, m.Keys[0])
   508  	Save(w, m.Values[0])
   509  	for i := 1; i < int(l); i++ {
   510  		m.Keys[i].save(w)
   511  		m.Values[i].save(w)
   512  	}
   513  }
   514  
   515  // load implements Object.load.
   516  func (*Map) load(r Reader) Object {
   517  	m := loadMap(r)
   518  	return &m
   519  }
   520  
   521  // TypeSpec is a type dereference.
   522  type TypeSpec interface {
   523  	isTypeSpec()
   524  }
   525  
   526  // TypeID is a concrete type ID.
   527  type TypeID Uint
   528  
   529  func (TypeID) isTypeSpec() {}
   530  
   531  // TypeSpecPointer is a pointer type.
   532  type TypeSpecPointer struct {
   533  	Type TypeSpec
   534  }
   535  
   536  func (*TypeSpecPointer) isTypeSpec() {}
   537  
   538  // TypeSpecArray is an array type.
   539  type TypeSpecArray struct {
   540  	Count Uint
   541  	Type  TypeSpec
   542  }
   543  
   544  func (*TypeSpecArray) isTypeSpec() {}
   545  
   546  // TypeSpecSlice is a slice type.
   547  type TypeSpecSlice struct {
   548  	Type TypeSpec
   549  }
   550  
   551  func (*TypeSpecSlice) isTypeSpec() {}
   552  
   553  // TypeSpecMap is a map type.
   554  type TypeSpecMap struct {
   555  	Key   TypeSpec
   556  	Value TypeSpec
   557  }
   558  
   559  func (*TypeSpecMap) isTypeSpec() {}
   560  
   561  // TypeSpecNil is an empty type.
   562  type TypeSpecNil struct{}
   563  
   564  func (TypeSpecNil) isTypeSpec() {}
   565  
   566  // TypeSpec types.
   567  //
   568  // These use a distinct encoding on the wire, as they are used only in the
   569  // interface object. They are decoded through the dedicated loadTypeSpec and
   570  // saveTypeSpec functions.
   571  const (
   572  	typeSpecTypeID Uint = iota
   573  	typeSpecPointer
   574  	typeSpecArray
   575  	typeSpecSlice
   576  	typeSpecMap
   577  	typeSpecNil
   578  )
   579  
   580  // loadTypeSpec loads TypeSpec values.
   581  func loadTypeSpec(r Reader) TypeSpec {
   582  	switch hdr := loadUint(r); hdr {
   583  	case typeSpecTypeID:
   584  		return TypeID(loadUint(r))
   585  	case typeSpecPointer:
   586  		return &TypeSpecPointer{
   587  			Type: loadTypeSpec(r),
   588  		}
   589  	case typeSpecArray:
   590  		return &TypeSpecArray{
   591  			Count: loadUint(r),
   592  			Type:  loadTypeSpec(r),
   593  		}
   594  	case typeSpecSlice:
   595  		return &TypeSpecSlice{
   596  			Type: loadTypeSpec(r),
   597  		}
   598  	case typeSpecMap:
   599  		return &TypeSpecMap{
   600  			Key:   loadTypeSpec(r),
   601  			Value: loadTypeSpec(r),
   602  		}
   603  	case typeSpecNil:
   604  		return TypeSpecNil{}
   605  	default:
   606  		// This is not a valid stream?
   607  		panic(fmt.Errorf("unknown header: %d", hdr))
   608  	}
   609  }
   610  
   611  // saveTypeSpec saves TypeSpec values.
   612  func saveTypeSpec(w Writer, t TypeSpec) {
   613  	switch x := t.(type) {
   614  	case TypeID:
   615  		typeSpecTypeID.save(w)
   616  		Uint(x).save(w)
   617  	case *TypeSpecPointer:
   618  		typeSpecPointer.save(w)
   619  		saveTypeSpec(w, x.Type)
   620  	case *TypeSpecArray:
   621  		typeSpecArray.save(w)
   622  		x.Count.save(w)
   623  		saveTypeSpec(w, x.Type)
   624  	case *TypeSpecSlice:
   625  		typeSpecSlice.save(w)
   626  		saveTypeSpec(w, x.Type)
   627  	case *TypeSpecMap:
   628  		typeSpecMap.save(w)
   629  		saveTypeSpec(w, x.Key)
   630  		saveTypeSpec(w, x.Value)
   631  	case TypeSpecNil:
   632  		typeSpecNil.save(w)
   633  	default:
   634  		// This should not happen?
   635  		panic(fmt.Errorf("unknown type %T", t))
   636  	}
   637  }
   638  
   639  // Interface is an interface value.
   640  type Interface struct {
   641  	Type  TypeSpec
   642  	Value Object
   643  }
   644  
   645  // loadInterface loads an object of type Interface.
   646  func loadInterface(r Reader) Interface {
   647  	return Interface{
   648  		Type:  loadTypeSpec(r),
   649  		Value: Load(r),
   650  	}
   651  }
   652  
   653  // save implements Object.save.
   654  func (i *Interface) save(w Writer) {
   655  	saveTypeSpec(w, i.Type)
   656  	Save(w, i.Value)
   657  }
   658  
   659  // load implements Object.load.
   660  func (*Interface) load(r Reader) Object {
   661  	i := loadInterface(r)
   662  	return &i
   663  }
   664  
   665  // Type is type information.
   666  type Type struct {
   667  	Name   string
   668  	Fields []string
   669  }
   670  
   671  // loadType loads an object of type Type.
   672  func loadType(r Reader) Type {
   673  	name := string(loadString(r))
   674  	l := loadUint(r)
   675  	fields := make([]string, l)
   676  	for i := 0; i < int(l); i++ {
   677  		fields[i] = string(loadString(r))
   678  	}
   679  	return Type{
   680  		Name:   name,
   681  		Fields: fields,
   682  	}
   683  }
   684  
   685  // save implements Object.save.
   686  func (t *Type) save(w Writer) {
   687  	s := String(t.Name)
   688  	s.save(w)
   689  	l := Uint(len(t.Fields))
   690  	l.save(w)
   691  	for i := 0; i < int(l); i++ {
   692  		s := String(t.Fields[i])
   693  		s.save(w)
   694  	}
   695  }
   696  
   697  // load implements Object.load.
   698  func (*Type) load(r Reader) Object {
   699  	t := loadType(r)
   700  	return &t
   701  }
   702  
   703  // multipleObjects is a special type for serializing multiple objects.
   704  type multipleObjects []Object
   705  
   706  // loadMultipleObjects loads a series of objects.
   707  func loadMultipleObjects(r Reader) multipleObjects {
   708  	l := loadUint(r)
   709  	m := make(multipleObjects, l)
   710  	for i := 0; i < int(l); i++ {
   711  		m[i] = Load(r)
   712  	}
   713  	return m
   714  }
   715  
   716  // save implements Object.save.
   717  func (m *multipleObjects) save(w Writer) {
   718  	l := Uint(len(*m))
   719  	l.save(w)
   720  	for i := 0; i < int(l); i++ {
   721  		Save(w, (*m)[i])
   722  	}
   723  }
   724  
   725  // load implements Object.load.
   726  func (*multipleObjects) load(r Reader) Object {
   727  	m := loadMultipleObjects(r)
   728  	return &m
   729  }
   730  
   731  // noObjects represents no objects.
   732  type noObjects struct{}
   733  
   734  // loadNoObjects loads a sentinel.
   735  func loadNoObjects(r Reader) noObjects { return noObjects{} }
   736  
   737  // save implements Object.save.
   738  func (noObjects) save(w Writer) {}
   739  
   740  // load implements Object.load.
   741  func (noObjects) load(r Reader) Object { return loadNoObjects(r) }
   742  
   743  // Struct is a basic composite value.
   744  type Struct struct {
   745  	TypeID TypeID
   746  	fields Object // Optionally noObjects or *multipleObjects.
   747  }
   748  
   749  // Field returns a pointer to the given field slot.
   750  //
   751  // This must be called after Alloc.
   752  func (s *Struct) Field(i int) *Object {
   753  	if fields, ok := s.fields.(*multipleObjects); ok {
   754  		return &((*fields)[i])
   755  	}
   756  	if _, ok := s.fields.(noObjects); ok {
   757  		// Alloc may be optionally called; can't call twice.
   758  		panic("Field called inappropriately, wrong Alloc?")
   759  	}
   760  	return &s.fields
   761  }
   762  
   763  // Alloc allocates the given number of fields.
   764  //
   765  // This must be called before Add and Save.
   766  //
   767  // Precondition: slots must be positive.
   768  func (s *Struct) Alloc(slots int) {
   769  	switch {
   770  	case slots == 0:
   771  		s.fields = noObjects{}
   772  	case slots == 1:
   773  		// Leave it alone.
   774  	case slots > 1:
   775  		fields := make(multipleObjects, slots)
   776  		s.fields = &fields
   777  	default:
   778  		// Violates precondition.
   779  		panic(fmt.Sprintf("Alloc called with negative slots %d?", slots))
   780  	}
   781  }
   782  
   783  // Fields returns the number of fields.
   784  func (s *Struct) Fields() int {
   785  	switch x := s.fields.(type) {
   786  	case *multipleObjects:
   787  		return len(*x)
   788  	case noObjects:
   789  		return 0
   790  	default:
   791  		return 1
   792  	}
   793  }
   794  
   795  // loadStruct loads an object of type Struct.
   796  func loadStruct(r Reader) Struct {
   797  	return Struct{
   798  		TypeID: TypeID(loadUint(r)),
   799  		fields: Load(r),
   800  	}
   801  }
   802  
   803  // save implements Object.save.
   804  //
   805  // Precondition: Alloc must have been called, and the fields all filled in
   806  // appropriately. See Alloc and Add for more details.
   807  func (s *Struct) save(w Writer) {
   808  	Uint(s.TypeID).save(w)
   809  	Save(w, s.fields)
   810  }
   811  
   812  // load implements Object.load.
   813  func (*Struct) load(r Reader) Object {
   814  	s := loadStruct(r)
   815  	return &s
   816  }
   817  
   818  // Object types.
   819  //
   820  // N.B. Be careful about changing the order or introducing new elements in the
   821  // middle here. This is part of the wire format and shouldn't change.
   822  const (
   823  	typeBool Uint = iota
   824  	typeInt
   825  	typeUint
   826  	typeFloat32
   827  	typeFloat64
   828  	typeNil
   829  	typeRef
   830  	typeString
   831  	typeSlice
   832  	typeArray
   833  	typeMap
   834  	typeStruct
   835  	typeNoObjects
   836  	typeMultipleObjects
   837  	typeInterface
   838  	typeComplex64
   839  	typeComplex128
   840  	typeType
   841  )
   842  
   843  // Save saves the given object.
   844  //
   845  // +checkescape all
   846  //
   847  // N.B. This function will panic on error.
   848  func Save(w Writer, obj Object) {
   849  	switch x := obj.(type) {
   850  	case Bool:
   851  		typeBool.save(w)
   852  		x.save(w)
   853  	case Int:
   854  		typeInt.save(w)
   855  		x.save(w)
   856  	case Uint:
   857  		typeUint.save(w)
   858  		x.save(w)
   859  	case Float32:
   860  		typeFloat32.save(w)
   861  		x.save(w)
   862  	case Float64:
   863  		typeFloat64.save(w)
   864  		x.save(w)
   865  	case Nil:
   866  		typeNil.save(w)
   867  		x.save(w)
   868  	case *Ref:
   869  		typeRef.save(w)
   870  		x.save(w)
   871  	case *String:
   872  		typeString.save(w)
   873  		x.save(w)
   874  	case *Slice:
   875  		typeSlice.save(w)
   876  		x.save(w)
   877  	case *Array:
   878  		typeArray.save(w)
   879  		x.save(w)
   880  	case *Map:
   881  		typeMap.save(w)
   882  		x.save(w)
   883  	case *Struct:
   884  		typeStruct.save(w)
   885  		x.save(w)
   886  	case noObjects:
   887  		typeNoObjects.save(w)
   888  		x.save(w)
   889  	case *multipleObjects:
   890  		typeMultipleObjects.save(w)
   891  		x.save(w)
   892  	case *Interface:
   893  		typeInterface.save(w)
   894  		x.save(w)
   895  	case *Type:
   896  		typeType.save(w)
   897  		x.save(w)
   898  	case *Complex64:
   899  		typeComplex64.save(w)
   900  		x.save(w)
   901  	case *Complex128:
   902  		typeComplex128.save(w)
   903  		x.save(w)
   904  	default:
   905  		panic(fmt.Errorf("unknown type: %#v", obj))
   906  	}
   907  }
   908  
   909  // Load loads a new object.
   910  //
   911  // +checkescape all
   912  //
   913  // N.B. This function will panic on error.
   914  func Load(r Reader) Object {
   915  	switch hdr := loadUint(r); hdr {
   916  	case typeBool:
   917  		return loadBool(r)
   918  	case typeInt:
   919  		return loadInt(r)
   920  	case typeUint:
   921  		return loadUint(r)
   922  	case typeFloat32:
   923  		return loadFloat32(r)
   924  	case typeFloat64:
   925  		return loadFloat64(r)
   926  	case typeNil:
   927  		return loadNil(r)
   928  	case typeRef:
   929  		return ((*Ref)(nil)).load(r) // Escapes.
   930  	case typeString:
   931  		return ((*String)(nil)).load(r) // Escapes.
   932  	case typeSlice:
   933  		return ((*Slice)(nil)).load(r) // Escapes.
   934  	case typeArray:
   935  		return ((*Array)(nil)).load(r) // Escapes.
   936  	case typeMap:
   937  		return ((*Map)(nil)).load(r) // Escapes.
   938  	case typeStruct:
   939  		return ((*Struct)(nil)).load(r) // Escapes.
   940  	case typeNoObjects: // Special for struct.
   941  		return loadNoObjects(r)
   942  	case typeMultipleObjects: // Special for struct.
   943  		return ((*multipleObjects)(nil)).load(r) // Escapes.
   944  	case typeInterface:
   945  		return ((*Interface)(nil)).load(r) // Escapes.
   946  	case typeComplex64:
   947  		return ((*Complex64)(nil)).load(r) // Escapes.
   948  	case typeComplex128:
   949  		return ((*Complex128)(nil)).load(r) // Escapes.
   950  	case typeType:
   951  		return ((*Type)(nil)).load(r) // Escapes.
   952  	default:
   953  		// This is not a valid stream?
   954  		panic(fmt.Errorf("unknown header: %d", hdr))
   955  	}
   956  }
   957  
   958  // LoadUint loads a single unsigned integer.
   959  //
   960  // N.B. This function will panic on error.
   961  func LoadUint(r Reader) uint64 {
   962  	return uint64(loadUint(r))
   963  }
   964  
   965  // SaveUint saves a single unsigned integer.
   966  //
   967  // N.B. This function will panic on error.
   968  func SaveUint(w Writer, v uint64) {
   969  	Uint(v).save(w)
   970  }