...

Source file src/pkg/encoding/gob/encode.go

     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