...

Source file src/encoding/gob/encode.go

Documentation: encoding/gob

		 1  // Copyright 2009 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  //go:generate go run encgen.go -output enc_helpers.go
		 6  
		 7  package gob
		 8  
		 9  import (
		10  	"encoding"
		11  	"encoding/binary"
		12  	"math"
		13  	"math/bits"
		14  	"reflect"
		15  	"sync"
		16  )
		17  
		18  const uint64Size = 8
		19  
		20  type encHelper func(state *encoderState, v reflect.Value) bool
		21  
		22  // encoderState is the global execution state of an instance of the encoder.
		23  // Field numbers are delta encoded and always increase. The field
		24  // number is initialized to -1 so 0 comes out as delta(1). A delta of
		25  // 0 terminates the structure.
		26  type encoderState struct {
		27  	enc			*Encoder
		28  	b				*encBuffer
		29  	sendZero bool								 // encoding an array element or map key/value pair; send zero values
		30  	fieldnum int									// the last field number written.
		31  	buf			[1 + uint64Size]byte // buffer used by the encoder; here to avoid allocation.
		32  	next		 *encoderState				// for free list
		33  }
		34  
		35  // encBuffer is an extremely simple, fast implementation of a write-only byte buffer.
		36  // It never returns a non-nil error, but Write returns an error value so it matches io.Writer.
		37  type encBuffer struct {
		38  	data		[]byte
		39  	scratch [64]byte
		40  }
		41  
		42  var encBufferPool = sync.Pool{
		43  	New: func() interface{} {
		44  		e := new(encBuffer)
		45  		e.data = e.scratch[0:0]
		46  		return e
		47  	},
		48  }
		49  
		50  func (e *encBuffer) writeByte(c byte) {
		51  	e.data = append(e.data, c)
		52  }
		53  
		54  func (e *encBuffer) Write(p []byte) (int, error) {
		55  	e.data = append(e.data, p...)
		56  	return len(p), nil
		57  }
		58  
		59  func (e *encBuffer) WriteString(s string) {
		60  	e.data = append(e.data, s...)
		61  }
		62  
		63  func (e *encBuffer) Len() int {
		64  	return len(e.data)
		65  }
		66  
		67  func (e *encBuffer) Bytes() []byte {
		68  	return e.data
		69  }
		70  
		71  func (e *encBuffer) Reset() {
		72  	if len(e.data) >= tooBig {
		73  		e.data = e.scratch[0:0]
		74  	} else {
		75  		e.data = e.data[0:0]
		76  	}
		77  }
		78  
		79  func (enc *Encoder) newEncoderState(b *encBuffer) *encoderState {
		80  	e := enc.freeList
		81  	if e == nil {
		82  		e = new(encoderState)
		83  		e.enc = enc
		84  	} else {
		85  		enc.freeList = e.next
		86  	}
		87  	e.sendZero = false
		88  	e.fieldnum = 0
		89  	e.b = b
		90  	if len(b.data) == 0 {
		91  		b.data = b.scratch[0:0]
		92  	}
		93  	return e
		94  }
		95  
		96  func (enc *Encoder) freeEncoderState(e *encoderState) {
		97  	e.next = enc.freeList
		98  	enc.freeList = e
		99  }
	 100  
	 101  // Unsigned integers have a two-state encoding. If the number is less
	 102  // than 128 (0 through 0x7F), its value is written directly.
	 103  // Otherwise the value is written in big-endian byte order preceded
	 104  // by the byte length, negated.
	 105  
	 106  // encodeUint writes an encoded unsigned integer to state.b.
	 107  func (state *encoderState) encodeUint(x uint64) {
	 108  	if x <= 0x7F {
	 109  		state.b.writeByte(uint8(x))
	 110  		return
	 111  	}
	 112  
	 113  	binary.BigEndian.PutUint64(state.buf[1:], x)
	 114  	bc := bits.LeadingZeros64(x) >> 3			// 8 - bytelen(x)
	 115  	state.buf[bc] = uint8(bc - uint64Size) // and then we subtract 8 to get -bytelen(x)
	 116  
	 117  	state.b.Write(state.buf[bc : uint64Size+1])
	 118  }
	 119  
	 120  // encodeInt writes an encoded signed integer to state.w.
	 121  // The low bit of the encoding says whether to bit complement the (other bits of the)
	 122  // uint to recover the int.
	 123  func (state *encoderState) encodeInt(i int64) {
	 124  	var x uint64
	 125  	if i < 0 {
	 126  		x = uint64(^i<<1) | 1
	 127  	} else {
	 128  		x = uint64(i << 1)
	 129  	}
	 130  	state.encodeUint(x)
	 131  }
	 132  
	 133  // encOp is the signature of an encoding operator for a given type.
	 134  type encOp func(i *encInstr, state *encoderState, v reflect.Value)
	 135  
	 136  // The 'instructions' of the encoding machine
	 137  type encInstr struct {
	 138  	op		encOp
	 139  	field int	 // field number in input
	 140  	index []int // struct index
	 141  	indir int	 // how many pointer indirections to reach the value in the struct
	 142  }
	 143  
	 144  // update emits a field number and updates the state to record its value for delta encoding.
	 145  // If the instruction pointer is nil, it does nothing
	 146  func (state *encoderState) update(instr *encInstr) {
	 147  	if instr != nil {
	 148  		state.encodeUint(uint64(instr.field - state.fieldnum))
	 149  		state.fieldnum = instr.field
	 150  	}
	 151  }
	 152  
	 153  // Each encoder for a composite is responsible for handling any
	 154  // indirections associated with the elements of the data structure.
	 155  // If any pointer so reached is nil, no bytes are written. If the
	 156  // data item is zero, no bytes are written. Single values - ints,
	 157  // strings etc. - are indirected before calling their encoders.
	 158  // Otherwise, the output (for a scalar) is the field number, as an
	 159  // encoded integer, followed by the field data in its appropriate
	 160  // format.
	 161  
	 162  // encIndirect dereferences pv indir times and returns the result.
	 163  func encIndirect(pv reflect.Value, indir int) reflect.Value {
	 164  	for ; indir > 0; indir-- {
	 165  		if pv.IsNil() {
	 166  			break
	 167  		}
	 168  		pv = pv.Elem()
	 169  	}
	 170  	return pv
	 171  }
	 172  
	 173  // encBool encodes the bool referenced by v as an unsigned 0 or 1.
	 174  func encBool(i *encInstr, state *encoderState, v reflect.Value) {
	 175  	b := v.Bool()
	 176  	if b || state.sendZero {
	 177  		state.update(i)
	 178  		if b {
	 179  			state.encodeUint(1)
	 180  		} else {
	 181  			state.encodeUint(0)
	 182  		}
	 183  	}
	 184  }
	 185  
	 186  // encInt encodes the signed integer (int int8 int16 int32 int64) referenced by v.
	 187  func encInt(i *encInstr, state *encoderState, v reflect.Value) {
	 188  	value := v.Int()
	 189  	if value != 0 || state.sendZero {
	 190  		state.update(i)
	 191  		state.encodeInt(value)
	 192  	}
	 193  }
	 194  
	 195  // encUint encodes the unsigned integer (uint uint8 uint16 uint32 uint64 uintptr) referenced by v.
	 196  func encUint(i *encInstr, state *encoderState, v reflect.Value) {
	 197  	value := v.Uint()
	 198  	if value != 0 || state.sendZero {
	 199  		state.update(i)
	 200  		state.encodeUint(value)
	 201  	}
	 202  }
	 203  
	 204  // floatBits returns a uint64 holding the bits of a floating-point number.
	 205  // Floating-point numbers are transmitted as uint64s holding the bits
	 206  // of the underlying representation. They are sent byte-reversed, with
	 207  // the exponent end coming out first, so integer floating point numbers
	 208  // (for example) transmit more compactly. This routine does the
	 209  // swizzling.
	 210  func floatBits(f float64) uint64 {
	 211  	u := math.Float64bits(f)
	 212  	return bits.ReverseBytes64(u)
	 213  }
	 214  
	 215  // encFloat encodes the floating point value (float32 float64) referenced by v.
	 216  func encFloat(i *encInstr, state *encoderState, v reflect.Value) {
	 217  	f := v.Float()
	 218  	if f != 0 || state.sendZero {
	 219  		bits := floatBits(f)
	 220  		state.update(i)
	 221  		state.encodeUint(bits)
	 222  	}
	 223  }
	 224  
	 225  // encComplex encodes the complex value (complex64 complex128) referenced by v.
	 226  // Complex numbers are just a pair of floating-point numbers, real part first.
	 227  func encComplex(i *encInstr, state *encoderState, v reflect.Value) {
	 228  	c := v.Complex()
	 229  	if c != 0+0i || state.sendZero {
	 230  		rpart := floatBits(real(c))
	 231  		ipart := floatBits(imag(c))
	 232  		state.update(i)
	 233  		state.encodeUint(rpart)
	 234  		state.encodeUint(ipart)
	 235  	}
	 236  }
	 237  
	 238  // encUint8Array encodes the byte array referenced by v.
	 239  // Byte arrays are encoded as an unsigned count followed by the raw bytes.
	 240  func encUint8Array(i *encInstr, state *encoderState, v reflect.Value) {
	 241  	b := v.Bytes()
	 242  	if len(b) > 0 || state.sendZero {
	 243  		state.update(i)
	 244  		state.encodeUint(uint64(len(b)))
	 245  		state.b.Write(b)
	 246  	}
	 247  }
	 248  
	 249  // encString encodes the string referenced by v.
	 250  // Strings are encoded as an unsigned count followed by the raw bytes.
	 251  func encString(i *encInstr, state *encoderState, v reflect.Value) {
	 252  	s := v.String()
	 253  	if len(s) > 0 || state.sendZero {
	 254  		state.update(i)
	 255  		state.encodeUint(uint64(len(s)))
	 256  		state.b.WriteString(s)
	 257  	}
	 258  }
	 259  
	 260  // encStructTerminator encodes the end of an encoded struct
	 261  // as delta field number of 0.
	 262  func encStructTerminator(i *encInstr, state *encoderState, v reflect.Value) {
	 263  	state.encodeUint(0)
	 264  }
	 265  
	 266  // Execution engine
	 267  
	 268  // encEngine an array of instructions indexed by field number of the encoding
	 269  // data, typically a struct. It is executed top to bottom, walking the struct.
	 270  type encEngine struct {
	 271  	instr []encInstr
	 272  }
	 273  
	 274  const singletonField = 0
	 275  
	 276  // valid reports whether the value is valid and a non-nil pointer.
	 277  // (Slices, maps, and chans take care of themselves.)
	 278  func valid(v reflect.Value) bool {
	 279  	switch v.Kind() {
	 280  	case reflect.Invalid:
	 281  		return false
	 282  	case reflect.Ptr:
	 283  		return !v.IsNil()
	 284  	}
	 285  	return true
	 286  }
	 287  
	 288  // encodeSingle encodes a single top-level non-struct value.
	 289  func (enc *Encoder) encodeSingle(b *encBuffer, engine *encEngine, value reflect.Value) {
	 290  	state := enc.newEncoderState(b)
	 291  	defer enc.freeEncoderState(state)
	 292  	state.fieldnum = singletonField
	 293  	// There is no surrounding struct to frame the transmission, so we must
	 294  	// generate data even if the item is zero. To do this, set sendZero.
	 295  	state.sendZero = true
	 296  	instr := &engine.instr[singletonField]
	 297  	if instr.indir > 0 {
	 298  		value = encIndirect(value, instr.indir)
	 299  	}
	 300  	if valid(value) {
	 301  		instr.op(instr, state, value)
	 302  	}
	 303  }
	 304  
	 305  // encodeStruct encodes a single struct value.
	 306  func (enc *Encoder) encodeStruct(b *encBuffer, engine *encEngine, value reflect.Value) {
	 307  	if !valid(value) {
	 308  		return
	 309  	}
	 310  	state := enc.newEncoderState(b)
	 311  	defer enc.freeEncoderState(state)
	 312  	state.fieldnum = -1
	 313  	for i := 0; i < len(engine.instr); i++ {
	 314  		instr := &engine.instr[i]
	 315  		if i >= value.NumField() {
	 316  			// encStructTerminator
	 317  			instr.op(instr, state, reflect.Value{})
	 318  			break
	 319  		}
	 320  		field := value.FieldByIndex(instr.index)
	 321  		if instr.indir > 0 {
	 322  			field = encIndirect(field, instr.indir)
	 323  			// TODO: Is field guaranteed valid? If so we could avoid this check.
	 324  			if !valid(field) {
	 325  				continue
	 326  			}
	 327  		}
	 328  		instr.op(instr, state, field)
	 329  	}
	 330  }
	 331  
	 332  // encodeArray encodes an array.
	 333  func (enc *Encoder) encodeArray(b *encBuffer, value reflect.Value, op encOp, elemIndir int, length int, helper encHelper) {
	 334  	state := enc.newEncoderState(b)
	 335  	defer enc.freeEncoderState(state)
	 336  	state.fieldnum = -1
	 337  	state.sendZero = true
	 338  	state.encodeUint(uint64(length))
	 339  	if helper != nil && helper(state, value) {
	 340  		return
	 341  	}
	 342  	for i := 0; i < length; i++ {
	 343  		elem := value.Index(i)
	 344  		if elemIndir > 0 {
	 345  			elem = encIndirect(elem, elemIndir)
	 346  			// TODO: Is elem guaranteed valid? If so we could avoid this check.
	 347  			if !valid(elem) {
	 348  				errorf("encodeArray: nil element")
	 349  			}
	 350  		}
	 351  		op(nil, state, elem)
	 352  	}
	 353  }
	 354  
	 355  // encodeReflectValue is a helper for maps. It encodes the value v.
	 356  func encodeReflectValue(state *encoderState, v reflect.Value, op encOp, indir int) {
	 357  	for i := 0; i < indir && v.IsValid(); i++ {
	 358  		v = reflect.Indirect(v)
	 359  	}
	 360  	if !v.IsValid() {
	 361  		errorf("encodeReflectValue: nil element")
	 362  	}
	 363  	op(nil, state, v)
	 364  }
	 365  
	 366  // encodeMap encodes a map as unsigned count followed by key:value pairs.
	 367  func (enc *Encoder) encodeMap(b *encBuffer, mv reflect.Value, keyOp, elemOp encOp, keyIndir, elemIndir int) {
	 368  	state := enc.newEncoderState(b)
	 369  	state.fieldnum = -1
	 370  	state.sendZero = true
	 371  	keys := mv.MapKeys()
	 372  	state.encodeUint(uint64(len(keys)))
	 373  	for _, key := range keys {
	 374  		encodeReflectValue(state, key, keyOp, keyIndir)
	 375  		encodeReflectValue(state, mv.MapIndex(key), elemOp, elemIndir)
	 376  	}
	 377  	enc.freeEncoderState(state)
	 378  }
	 379  
	 380  // encodeInterface encodes the interface value iv.
	 381  // To send an interface, we send a string identifying the concrete type, followed
	 382  // by the type identifier (which might require defining that type right now), followed
	 383  // by the concrete value. A nil value gets sent as the empty string for the name,
	 384  // followed by no value.
	 385  func (enc *Encoder) encodeInterface(b *encBuffer, iv reflect.Value) {
	 386  	// Gobs can encode nil interface values but not typed interface
	 387  	// values holding nil pointers, since nil pointers point to no value.
	 388  	elem := iv.Elem()
	 389  	if elem.Kind() == reflect.Ptr && elem.IsNil() {
	 390  		errorf("gob: cannot encode nil pointer of type %s inside interface", iv.Elem().Type())
	 391  	}
	 392  	state := enc.newEncoderState(b)
	 393  	state.fieldnum = -1
	 394  	state.sendZero = true
	 395  	if iv.IsNil() {
	 396  		state.encodeUint(0)
	 397  		return
	 398  	}
	 399  
	 400  	ut := userType(iv.Elem().Type())
	 401  	namei, ok := concreteTypeToName.Load(ut.base)
	 402  	if !ok {
	 403  		errorf("type not registered for interface: %s", ut.base)
	 404  	}
	 405  	name := namei.(string)
	 406  
	 407  	// Send the name.
	 408  	state.encodeUint(uint64(len(name)))
	 409  	state.b.WriteString(name)
	 410  	// Define the type id if necessary.
	 411  	enc.sendTypeDescriptor(enc.writer(), state, ut)
	 412  	// Send the type id.
	 413  	enc.sendTypeId(state, ut)
	 414  	// Encode the value into a new buffer. Any nested type definitions
	 415  	// should be written to b, before the encoded value.
	 416  	enc.pushWriter(b)
	 417  	data := encBufferPool.Get().(*encBuffer)
	 418  	data.Write(spaceForLength)
	 419  	enc.encode(data, elem, ut)
	 420  	if enc.err != nil {
	 421  		error_(enc.err)
	 422  	}
	 423  	enc.popWriter()
	 424  	enc.writeMessage(b, data)
	 425  	data.Reset()
	 426  	encBufferPool.Put(data)
	 427  	if enc.err != nil {
	 428  		error_(enc.err)
	 429  	}
	 430  	enc.freeEncoderState(state)
	 431  }
	 432  
	 433  // isZero reports whether the value is the zero of its type.
	 434  func isZero(val reflect.Value) bool {
	 435  	switch val.Kind() {
	 436  	case reflect.Array:
	 437  		for i := 0; i < val.Len(); i++ {
	 438  			if !isZero(val.Index(i)) {
	 439  				return false
	 440  			}
	 441  		}
	 442  		return true
	 443  	case reflect.Map, reflect.Slice, reflect.String:
	 444  		return val.Len() == 0
	 445  	case reflect.Bool:
	 446  		return !val.Bool()
	 447  	case reflect.Complex64, reflect.Complex128:
	 448  		return val.Complex() == 0
	 449  	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr:
	 450  		return val.IsNil()
	 451  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
	 452  		return val.Int() == 0
	 453  	case reflect.Float32, reflect.Float64:
	 454  		return val.Float() == 0
	 455  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
	 456  		return val.Uint() == 0
	 457  	case reflect.Struct:
	 458  		for i := 0; i < val.NumField(); i++ {
	 459  			if !isZero(val.Field(i)) {
	 460  				return false
	 461  			}
	 462  		}
	 463  		return true
	 464  	}
	 465  	panic("unknown type in isZero " + val.Type().String())
	 466  }
	 467  
	 468  // encGobEncoder encodes a value that implements the GobEncoder interface.
	 469  // The data is sent as a byte array.
	 470  func (enc *Encoder) encodeGobEncoder(b *encBuffer, ut *userTypeInfo, v reflect.Value) {
	 471  	// TODO: should we catch panics from the called method?
	 472  
	 473  	var data []byte
	 474  	var err error
	 475  	// We know it's one of these.
	 476  	switch ut.externalEnc {
	 477  	case xGob:
	 478  		data, err = v.Interface().(GobEncoder).GobEncode()
	 479  	case xBinary:
	 480  		data, err = v.Interface().(encoding.BinaryMarshaler).MarshalBinary()
	 481  	case xText:
	 482  		data, err = v.Interface().(encoding.TextMarshaler).MarshalText()
	 483  	}
	 484  	if err != nil {
	 485  		error_(err)
	 486  	}
	 487  	state := enc.newEncoderState(b)
	 488  	state.fieldnum = -1
	 489  	state.encodeUint(uint64(len(data)))
	 490  	state.b.Write(data)
	 491  	enc.freeEncoderState(state)
	 492  }
	 493  
	 494  var encOpTable = [...]encOp{
	 495  	reflect.Bool:			 encBool,
	 496  	reflect.Int:				encInt,
	 497  	reflect.Int8:			 encInt,
	 498  	reflect.Int16:			encInt,
	 499  	reflect.Int32:			encInt,
	 500  	reflect.Int64:			encInt,
	 501  	reflect.Uint:			 encUint,
	 502  	reflect.Uint8:			encUint,
	 503  	reflect.Uint16:		 encUint,
	 504  	reflect.Uint32:		 encUint,
	 505  	reflect.Uint64:		 encUint,
	 506  	reflect.Uintptr:		encUint,
	 507  	reflect.Float32:		encFloat,
	 508  	reflect.Float64:		encFloat,
	 509  	reflect.Complex64:	encComplex,
	 510  	reflect.Complex128: encComplex,
	 511  	reflect.String:		 encString,
	 512  }
	 513  
	 514  // encOpFor returns (a pointer to) the encoding op for the base type under rt and
	 515  // the indirection count to reach it.
	 516  func encOpFor(rt reflect.Type, inProgress map[reflect.Type]*encOp, building map[*typeInfo]bool) (*encOp, int) {
	 517  	ut := userType(rt)
	 518  	// If the type implements GobEncoder, we handle it without further processing.
	 519  	if ut.externalEnc != 0 {
	 520  		return gobEncodeOpFor(ut)
	 521  	}
	 522  	// If this type is already in progress, it's a recursive type (e.g. map[string]*T).
	 523  	// Return the pointer to the op we're already building.
	 524  	if opPtr := inProgress[rt]; opPtr != nil {
	 525  		return opPtr, ut.indir
	 526  	}
	 527  	typ := ut.base
	 528  	indir := ut.indir
	 529  	k := typ.Kind()
	 530  	var op encOp
	 531  	if int(k) < len(encOpTable) {
	 532  		op = encOpTable[k]
	 533  	}
	 534  	if op == nil {
	 535  		inProgress[rt] = &op
	 536  		// Special cases
	 537  		switch t := typ; t.Kind() {
	 538  		case reflect.Slice:
	 539  			if t.Elem().Kind() == reflect.Uint8 {
	 540  				op = encUint8Array
	 541  				break
	 542  			}
	 543  			// Slices have a header; we decode it to find the underlying array.
	 544  			elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
	 545  			helper := encSliceHelper[t.Elem().Kind()]
	 546  			op = func(i *encInstr, state *encoderState, slice reflect.Value) {
	 547  				if !state.sendZero && slice.Len() == 0 {
	 548  					return
	 549  				}
	 550  				state.update(i)
	 551  				state.enc.encodeArray(state.b, slice, *elemOp, elemIndir, slice.Len(), helper)
	 552  			}
	 553  		case reflect.Array:
	 554  			// True arrays have size in the type.
	 555  			elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
	 556  			helper := encArrayHelper[t.Elem().Kind()]
	 557  			op = func(i *encInstr, state *encoderState, array reflect.Value) {
	 558  				state.update(i)
	 559  				state.enc.encodeArray(state.b, array, *elemOp, elemIndir, array.Len(), helper)
	 560  			}
	 561  		case reflect.Map:
	 562  			keyOp, keyIndir := encOpFor(t.Key(), inProgress, building)
	 563  			elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
	 564  			op = func(i *encInstr, state *encoderState, mv reflect.Value) {
	 565  				// We send zero-length (but non-nil) maps because the
	 566  				// receiver might want to use the map.	(Maps don't use append.)
	 567  				if !state.sendZero && mv.IsNil() {
	 568  					return
	 569  				}
	 570  				state.update(i)
	 571  				state.enc.encodeMap(state.b, mv, *keyOp, *elemOp, keyIndir, elemIndir)
	 572  			}
	 573  		case reflect.Struct:
	 574  			// Generate a closure that calls out to the engine for the nested type.
	 575  			getEncEngine(userType(typ), building)
	 576  			info := mustGetTypeInfo(typ)
	 577  			op = func(i *encInstr, state *encoderState, sv reflect.Value) {
	 578  				state.update(i)
	 579  				// indirect through info to delay evaluation for recursive structs
	 580  				enc := info.encoder.Load().(*encEngine)
	 581  				state.enc.encodeStruct(state.b, enc, sv)
	 582  			}
	 583  		case reflect.Interface:
	 584  			op = func(i *encInstr, state *encoderState, iv reflect.Value) {
	 585  				if !state.sendZero && (!iv.IsValid() || iv.IsNil()) {
	 586  					return
	 587  				}
	 588  				state.update(i)
	 589  				state.enc.encodeInterface(state.b, iv)
	 590  			}
	 591  		}
	 592  	}
	 593  	if op == nil {
	 594  		errorf("can't happen: encode type %s", rt)
	 595  	}
	 596  	return &op, indir
	 597  }
	 598  
	 599  // gobEncodeOpFor returns the op for a type that is known to implement GobEncoder.
	 600  func gobEncodeOpFor(ut *userTypeInfo) (*encOp, int) {
	 601  	rt := ut.user
	 602  	if ut.encIndir == -1 {
	 603  		rt = reflect.PtrTo(rt)
	 604  	} else if ut.encIndir > 0 {
	 605  		for i := int8(0); i < ut.encIndir; i++ {
	 606  			rt = rt.Elem()
	 607  		}
	 608  	}
	 609  	var op encOp
	 610  	op = func(i *encInstr, state *encoderState, v reflect.Value) {
	 611  		if ut.encIndir == -1 {
	 612  			// Need to climb up one level to turn value into pointer.
	 613  			if !v.CanAddr() {
	 614  				errorf("unaddressable value of type %s", rt)
	 615  			}
	 616  			v = v.Addr()
	 617  		}
	 618  		if !state.sendZero && isZero(v) {
	 619  			return
	 620  		}
	 621  		state.update(i)
	 622  		state.enc.encodeGobEncoder(state.b, ut, v)
	 623  	}
	 624  	return &op, int(ut.encIndir) // encIndir: op will get called with p == address of receiver.
	 625  }
	 626  
	 627  // compileEnc returns the engine to compile the type.
	 628  func compileEnc(ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
	 629  	srt := ut.base
	 630  	engine := new(encEngine)
	 631  	seen := make(map[reflect.Type]*encOp)
	 632  	rt := ut.base
	 633  	if ut.externalEnc != 0 {
	 634  		rt = ut.user
	 635  	}
	 636  	if ut.externalEnc == 0 && srt.Kind() == reflect.Struct {
	 637  		for fieldNum, wireFieldNum := 0, 0; fieldNum < srt.NumField(); fieldNum++ {
	 638  			f := srt.Field(fieldNum)
	 639  			if !isSent(&f) {
	 640  				continue
	 641  			}
	 642  			op, indir := encOpFor(f.Type, seen, building)
	 643  			engine.instr = append(engine.instr, encInstr{*op, wireFieldNum, f.Index, indir})
	 644  			wireFieldNum++
	 645  		}
	 646  		if srt.NumField() > 0 && len(engine.instr) == 0 {
	 647  			errorf("type %s has no exported fields", rt)
	 648  		}
	 649  		engine.instr = append(engine.instr, encInstr{encStructTerminator, 0, nil, 0})
	 650  	} else {
	 651  		engine.instr = make([]encInstr, 1)
	 652  		op, indir := encOpFor(rt, seen, building)
	 653  		engine.instr[0] = encInstr{*op, singletonField, nil, indir}
	 654  	}
	 655  	return engine
	 656  }
	 657  
	 658  // getEncEngine returns the engine to compile the type.
	 659  func getEncEngine(ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
	 660  	info, err := getTypeInfo(ut)
	 661  	if err != nil {
	 662  		error_(err)
	 663  	}
	 664  	enc, ok := info.encoder.Load().(*encEngine)
	 665  	if !ok {
	 666  		enc = buildEncEngine(info, ut, building)
	 667  	}
	 668  	return enc
	 669  }
	 670  
	 671  func buildEncEngine(info *typeInfo, ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
	 672  	// Check for recursive types.
	 673  	if building != nil && building[info] {
	 674  		return nil
	 675  	}
	 676  	info.encInit.Lock()
	 677  	defer info.encInit.Unlock()
	 678  	enc, ok := info.encoder.Load().(*encEngine)
	 679  	if !ok {
	 680  		if building == nil {
	 681  			building = make(map[*typeInfo]bool)
	 682  		}
	 683  		building[info] = true
	 684  		enc = compileEnc(ut, building)
	 685  		info.encoder.Store(enc)
	 686  	}
	 687  	return enc
	 688  }
	 689  
	 690  func (enc *Encoder) encode(b *encBuffer, value reflect.Value, ut *userTypeInfo) {
	 691  	defer catchError(&enc.err)
	 692  	engine := getEncEngine(ut, nil)
	 693  	indir := ut.indir
	 694  	if ut.externalEnc != 0 {
	 695  		indir = int(ut.encIndir)
	 696  	}
	 697  	for i := 0; i < indir; i++ {
	 698  		value = reflect.Indirect(value)
	 699  	}
	 700  	if ut.externalEnc == 0 && value.Type().Kind() == reflect.Struct {
	 701  		enc.encodeStruct(b, engine, value)
	 702  	} else {
	 703  		enc.encodeSingle(b, engine, value)
	 704  	}
	 705  }
	 706  

View as plain text