gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

encode.go (41222B)


      1 // Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
      2 // Use of this source code is governed by a MIT license found in the LICENSE file.
      3 
      4 package codec
      5 
      6 import (
      7 	"encoding"
      8 	"errors"
      9 	"io"
     10 	"reflect"
     11 	"sort"
     12 	"strconv"
     13 	"time"
     14 )
     15 
     16 // defEncByteBufSize is the default size of []byte used
     17 // for bufio buffer or []byte (when nil passed)
     18 const defEncByteBufSize = 1 << 10 // 4:16, 6:64, 8:256, 10:1024
     19 
     20 var errEncoderNotInitialized = errors.New("Encoder not initialized")
     21 
     22 // encDriver abstracts the actual codec (binc vs msgpack, etc)
     23 type encDriver interface {
     24 	EncodeNil()
     25 	EncodeInt(i int64)
     26 	EncodeUint(i uint64)
     27 	EncodeBool(b bool)
     28 	EncodeFloat32(f float32)
     29 	EncodeFloat64(f float64)
     30 	EncodeRawExt(re *RawExt)
     31 	EncodeExt(v interface{}, basetype reflect.Type, xtag uint64, ext Ext)
     32 	// EncodeString using cUTF8, honor'ing StringToRaw flag
     33 	EncodeString(v string)
     34 	EncodeStringBytesRaw(v []byte)
     35 	EncodeTime(time.Time)
     36 	WriteArrayStart(length int)
     37 	WriteArrayEnd()
     38 	WriteMapStart(length int)
     39 	WriteMapEnd()
     40 
     41 	// reset will reset current encoding runtime state, and cached information from the handle
     42 	reset()
     43 
     44 	encoder() *Encoder
     45 
     46 	driverStateManager
     47 }
     48 
     49 type encDriverContainerTracker interface {
     50 	WriteArrayElem()
     51 	WriteMapElemKey()
     52 	WriteMapElemValue()
     53 }
     54 
     55 type encDriverNoState struct{}
     56 
     57 func (encDriverNoState) captureState() interface{}  { return nil }
     58 func (encDriverNoState) reset()                     {}
     59 func (encDriverNoState) resetState()                {}
     60 func (encDriverNoState) restoreState(v interface{}) {}
     61 
     62 type encDriverNoopContainerWriter struct{}
     63 
     64 func (encDriverNoopContainerWriter) WriteArrayStart(length int) {}
     65 func (encDriverNoopContainerWriter) WriteArrayEnd()             {}
     66 func (encDriverNoopContainerWriter) WriteMapStart(length int)   {}
     67 func (encDriverNoopContainerWriter) WriteMapEnd()               {}
     68 
     69 // encStructFieldObj[Slice] is used for sorting when there are missing fields and canonical flag is set
     70 type encStructFieldObj struct {
     71 	key   string
     72 	rv    reflect.Value
     73 	intf  interface{}
     74 	ascii bool
     75 	isRv  bool
     76 }
     77 
     78 type encStructFieldObjSlice []encStructFieldObj
     79 
     80 func (p encStructFieldObjSlice) Len() int      { return len(p) }
     81 func (p encStructFieldObjSlice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }
     82 func (p encStructFieldObjSlice) Less(i, j int) bool {
     83 	return p[uint(i)].key < p[uint(j)].key
     84 }
     85 
     86 // EncodeOptions captures configuration options during encode.
     87 type EncodeOptions struct {
     88 	// WriterBufferSize is the size of the buffer used when writing.
     89 	//
     90 	// if > 0, we use a smart buffer internally for performance purposes.
     91 	WriterBufferSize int
     92 
     93 	// ChanRecvTimeout is the timeout used when selecting from a chan.
     94 	//
     95 	// Configuring this controls how we receive from a chan during the encoding process.
     96 	//   - If ==0, we only consume the elements currently available in the chan.
     97 	//   - if  <0, we consume until the chan is closed.
     98 	//   - If  >0, we consume until this timeout.
     99 	ChanRecvTimeout time.Duration
    100 
    101 	// StructToArray specifies to encode a struct as an array, and not as a map
    102 	StructToArray bool
    103 
    104 	// Canonical representation means that encoding a value will always result in the same
    105 	// sequence of bytes.
    106 	//
    107 	// This only affects maps, as the iteration order for maps is random.
    108 	//
    109 	// The implementation MAY use the natural sort order for the map keys if possible:
    110 	//
    111 	//     - If there is a natural sort order (ie for number, bool, string or []byte keys),
    112 	//       then the map keys are first sorted in natural order and then written
    113 	//       with corresponding map values to the strema.
    114 	//     - If there is no natural sort order, then the map keys will first be
    115 	//       encoded into []byte, and then sorted,
    116 	//       before writing the sorted keys and the corresponding map values to the stream.
    117 	//
    118 	Canonical bool
    119 
    120 	// CheckCircularRef controls whether we check for circular references
    121 	// and error fast during an encode.
    122 	//
    123 	// If enabled, an error is received if a pointer to a struct
    124 	// references itself either directly or through one of its fields (iteratively).
    125 	//
    126 	// This is opt-in, as there may be a performance hit to checking circular references.
    127 	CheckCircularRef bool
    128 
    129 	// RecursiveEmptyCheck controls how we determine whether a value is empty.
    130 	//
    131 	// If true, we descend into interfaces and pointers to reursively check if value is empty.
    132 	//
    133 	// We *might* check struct fields one by one to see if empty
    134 	// (if we cannot directly check if a struct value is equal to its zero value).
    135 	// If so, we honor IsZero, Comparable, IsCodecEmpty(), etc.
    136 	// Note: This *may* make OmitEmpty more expensive due to the large number of reflect calls.
    137 	//
    138 	// If false, we check if the value is equal to its zero value (newly allocated state).
    139 	RecursiveEmptyCheck bool
    140 
    141 	// Raw controls whether we encode Raw values.
    142 	// This is a "dangerous" option and must be explicitly set.
    143 	// If set, we blindly encode Raw values as-is, without checking
    144 	// if they are a correct representation of a value in that format.
    145 	// If unset, we error out.
    146 	Raw bool
    147 
    148 	// StringToRaw controls how strings are encoded.
    149 	//
    150 	// As a go string is just an (immutable) sequence of bytes,
    151 	// it can be encoded either as raw bytes or as a UTF string.
    152 	//
    153 	// By default, strings are encoded as UTF-8.
    154 	// but can be treated as []byte during an encode.
    155 	//
    156 	// Note that things which we know (by definition) to be UTF-8
    157 	// are ALWAYS encoded as UTF-8 strings.
    158 	// These include encoding.TextMarshaler, time.Format calls, struct field names, etc.
    159 	StringToRaw bool
    160 
    161 	// OptimumSize controls whether we optimize for the smallest size.
    162 	//
    163 	// Some formats will use this flag to determine whether to encode
    164 	// in the smallest size possible, even if it takes slightly longer.
    165 	//
    166 	// For example, some formats that support half-floats might check if it is possible
    167 	// to store a float64 as a half float. Doing this check has a small performance cost,
    168 	// but the benefit is that the encoded message will be smaller.
    169 	OptimumSize bool
    170 
    171 	// NoAddressableReadonly controls whether we try to force a non-addressable value
    172 	// to be addressable so we can call a pointer method on it e.g. for types
    173 	// that support Selfer, json.Marshaler, etc.
    174 	//
    175 	// Use it in the very rare occurrence that your types modify a pointer value when calling
    176 	// an encode callback function e.g. JsonMarshal, TextMarshal, BinaryMarshal or CodecEncodeSelf.
    177 	NoAddressableReadonly bool
    178 }
    179 
    180 // ---------------------------------------------
    181 
    182 func (e *Encoder) rawExt(f *codecFnInfo, rv reflect.Value) {
    183 	e.e.EncodeRawExt(rv2i(rv).(*RawExt))
    184 }
    185 
    186 func (e *Encoder) ext(f *codecFnInfo, rv reflect.Value) {
    187 	e.e.EncodeExt(rv2i(rv), f.ti.rt, f.xfTag, f.xfFn)
    188 }
    189 
    190 func (e *Encoder) selferMarshal(f *codecFnInfo, rv reflect.Value) {
    191 	rv2i(rv).(Selfer).CodecEncodeSelf(e)
    192 }
    193 
    194 func (e *Encoder) binaryMarshal(f *codecFnInfo, rv reflect.Value) {
    195 	bs, fnerr := rv2i(rv).(encoding.BinaryMarshaler).MarshalBinary()
    196 	e.marshalRaw(bs, fnerr)
    197 }
    198 
    199 func (e *Encoder) textMarshal(f *codecFnInfo, rv reflect.Value) {
    200 	bs, fnerr := rv2i(rv).(encoding.TextMarshaler).MarshalText()
    201 	e.marshalUtf8(bs, fnerr)
    202 }
    203 
    204 func (e *Encoder) jsonMarshal(f *codecFnInfo, rv reflect.Value) {
    205 	bs, fnerr := rv2i(rv).(jsonMarshaler).MarshalJSON()
    206 	e.marshalAsis(bs, fnerr)
    207 }
    208 
    209 func (e *Encoder) raw(f *codecFnInfo, rv reflect.Value) {
    210 	e.rawBytes(rv2i(rv).(Raw))
    211 }
    212 
    213 func (e *Encoder) encodeComplex64(v complex64) {
    214 	if imag(v) != 0 {
    215 		e.errorf("cannot encode complex number: %v, with imaginary values: %v", v, imag(v))
    216 	}
    217 	e.e.EncodeFloat32(real(v))
    218 }
    219 
    220 func (e *Encoder) encodeComplex128(v complex128) {
    221 	if imag(v) != 0 {
    222 		e.errorf("cannot encode complex number: %v, with imaginary values: %v", v, imag(v))
    223 	}
    224 	e.e.EncodeFloat64(real(v))
    225 }
    226 
    227 func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
    228 	e.e.EncodeBool(rvGetBool(rv))
    229 }
    230 
    231 func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
    232 	e.e.EncodeTime(rvGetTime(rv))
    233 }
    234 
    235 func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
    236 	e.e.EncodeString(rvGetString(rv))
    237 }
    238 
    239 func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
    240 	e.e.EncodeFloat32(rvGetFloat32(rv))
    241 }
    242 
    243 func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
    244 	e.e.EncodeFloat64(rvGetFloat64(rv))
    245 }
    246 
    247 func (e *Encoder) kComplex64(f *codecFnInfo, rv reflect.Value) {
    248 	e.encodeComplex64(rvGetComplex64(rv))
    249 }
    250 
    251 func (e *Encoder) kComplex128(f *codecFnInfo, rv reflect.Value) {
    252 	e.encodeComplex128(rvGetComplex128(rv))
    253 }
    254 
    255 func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
    256 	e.e.EncodeInt(int64(rvGetInt(rv)))
    257 }
    258 
    259 func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
    260 	e.e.EncodeInt(int64(rvGetInt8(rv)))
    261 }
    262 
    263 func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
    264 	e.e.EncodeInt(int64(rvGetInt16(rv)))
    265 }
    266 
    267 func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
    268 	e.e.EncodeInt(int64(rvGetInt32(rv)))
    269 }
    270 
    271 func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
    272 	e.e.EncodeInt(int64(rvGetInt64(rv)))
    273 }
    274 
    275 func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
    276 	e.e.EncodeUint(uint64(rvGetUint(rv)))
    277 }
    278 
    279 func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
    280 	e.e.EncodeUint(uint64(rvGetUint8(rv)))
    281 }
    282 
    283 func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
    284 	e.e.EncodeUint(uint64(rvGetUint16(rv)))
    285 }
    286 
    287 func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
    288 	e.e.EncodeUint(uint64(rvGetUint32(rv)))
    289 }
    290 
    291 func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
    292 	e.e.EncodeUint(uint64(rvGetUint64(rv)))
    293 }
    294 
    295 func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
    296 	e.e.EncodeUint(uint64(rvGetUintptr(rv)))
    297 }
    298 
    299 func (e *Encoder) kErr(f *codecFnInfo, rv reflect.Value) {
    300 	e.errorf("unsupported kind %s, for %#v", rv.Kind(), rv)
    301 }
    302 
    303 func chanToSlice(rv reflect.Value, rtslice reflect.Type, timeout time.Duration) (rvcs reflect.Value) {
    304 	rvcs = rvZeroK(rtslice, reflect.Slice)
    305 	if timeout < 0 { // consume until close
    306 		for {
    307 			recv, recvOk := rv.Recv()
    308 			if !recvOk {
    309 				break
    310 			}
    311 			rvcs = reflect.Append(rvcs, recv)
    312 		}
    313 	} else {
    314 		cases := make([]reflect.SelectCase, 2)
    315 		cases[0] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: rv}
    316 		if timeout == 0 {
    317 			cases[1] = reflect.SelectCase{Dir: reflect.SelectDefault}
    318 		} else {
    319 			tt := time.NewTimer(timeout)
    320 			cases[1] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(tt.C)}
    321 		}
    322 		for {
    323 			chosen, recv, recvOk := reflect.Select(cases)
    324 			if chosen == 1 || !recvOk {
    325 				break
    326 			}
    327 			rvcs = reflect.Append(rvcs, recv)
    328 		}
    329 	}
    330 	return
    331 }
    332 
    333 func (e *Encoder) kSeqFn(rtelem reflect.Type) (fn *codecFn) {
    334 	for rtelem.Kind() == reflect.Ptr {
    335 		rtelem = rtelem.Elem()
    336 	}
    337 	// if kind is reflect.Interface, do not pre-determine the encoding type,
    338 	// because preEncodeValue may break it down to a concrete type and kInterface will bomb.
    339 	if rtelem.Kind() != reflect.Interface {
    340 		fn = e.h.fn(rtelem)
    341 	}
    342 	return
    343 }
    344 
    345 func (e *Encoder) kSliceWMbs(rv reflect.Value, ti *typeInfo) {
    346 	var l = rvLenSlice(rv)
    347 	if l == 0 {
    348 		e.mapStart(0)
    349 	} else {
    350 		e.haltOnMbsOddLen(l)
    351 		e.mapStart(l >> 1) // e.mapStart(l / 2)
    352 		fn := e.kSeqFn(ti.elem)
    353 		for j := 0; j < l; j++ {
    354 			if j&1 == 0 { // j%2 == 0 {
    355 				e.mapElemKey()
    356 			} else {
    357 				e.mapElemValue()
    358 			}
    359 			e.encodeValue(rvSliceIndex(rv, j, ti), fn)
    360 		}
    361 	}
    362 	e.mapEnd()
    363 }
    364 
    365 func (e *Encoder) kSliceW(rv reflect.Value, ti *typeInfo) {
    366 	var l = rvLenSlice(rv)
    367 	e.arrayStart(l)
    368 	if l > 0 {
    369 		fn := e.kSeqFn(ti.elem)
    370 		for j := 0; j < l; j++ {
    371 			e.arrayElem()
    372 			e.encodeValue(rvSliceIndex(rv, j, ti), fn)
    373 		}
    374 	}
    375 	e.arrayEnd()
    376 }
    377 
    378 func (e *Encoder) kArrayWMbs(rv reflect.Value, ti *typeInfo) {
    379 	var l = rv.Len()
    380 	if l == 0 {
    381 		e.mapStart(0)
    382 	} else {
    383 		e.haltOnMbsOddLen(l)
    384 		e.mapStart(l >> 1) // e.mapStart(l / 2)
    385 		fn := e.kSeqFn(ti.elem)
    386 		for j := 0; j < l; j++ {
    387 			if j&1 == 0 { // j%2 == 0 {
    388 				e.mapElemKey()
    389 			} else {
    390 				e.mapElemValue()
    391 			}
    392 			e.encodeValue(rv.Index(j), fn)
    393 		}
    394 	}
    395 	e.mapEnd()
    396 }
    397 
    398 func (e *Encoder) kArrayW(rv reflect.Value, ti *typeInfo) {
    399 	var l = rv.Len()
    400 	e.arrayStart(l)
    401 	if l > 0 {
    402 		fn := e.kSeqFn(ti.elem)
    403 		for j := 0; j < l; j++ {
    404 			e.arrayElem()
    405 			e.encodeValue(rv.Index(j), fn)
    406 		}
    407 	}
    408 	e.arrayEnd()
    409 }
    410 
    411 func (e *Encoder) kChan(f *codecFnInfo, rv reflect.Value) {
    412 	if f.ti.chandir&uint8(reflect.RecvDir) == 0 {
    413 		e.errorf("send-only channel cannot be encoded")
    414 	}
    415 	if !f.ti.mbs && uint8TypId == rt2id(f.ti.elem) {
    416 		e.kSliceBytesChan(rv)
    417 		return
    418 	}
    419 	rtslice := reflect.SliceOf(f.ti.elem)
    420 	rv = chanToSlice(rv, rtslice, e.h.ChanRecvTimeout)
    421 	ti := e.h.getTypeInfo(rt2id(rtslice), rtslice)
    422 	if f.ti.mbs {
    423 		e.kSliceWMbs(rv, ti)
    424 	} else {
    425 		e.kSliceW(rv, ti)
    426 	}
    427 }
    428 
    429 func (e *Encoder) kSlice(f *codecFnInfo, rv reflect.Value) {
    430 	if f.ti.mbs {
    431 		e.kSliceWMbs(rv, f.ti)
    432 	} else if f.ti.rtid == uint8SliceTypId || uint8TypId == rt2id(f.ti.elem) {
    433 		e.e.EncodeStringBytesRaw(rvGetBytes(rv))
    434 	} else {
    435 		e.kSliceW(rv, f.ti)
    436 	}
    437 }
    438 
    439 func (e *Encoder) kArray(f *codecFnInfo, rv reflect.Value) {
    440 	if f.ti.mbs {
    441 		e.kArrayWMbs(rv, f.ti)
    442 	} else if handleBytesWithinKArray && uint8TypId == rt2id(f.ti.elem) {
    443 		e.e.EncodeStringBytesRaw(rvGetArrayBytes(rv, []byte{}))
    444 	} else {
    445 		e.kArrayW(rv, f.ti)
    446 	}
    447 }
    448 
    449 func (e *Encoder) kSliceBytesChan(rv reflect.Value) {
    450 	// do not use range, so that the number of elements encoded
    451 	// does not change, and encoding does not hang waiting on someone to close chan.
    452 
    453 	bs0 := e.blist.peek(32, true)
    454 	bs := bs0
    455 
    456 	irv := rv2i(rv)
    457 	ch, ok := irv.(<-chan byte)
    458 	if !ok {
    459 		ch = irv.(chan byte)
    460 	}
    461 
    462 L1:
    463 	switch timeout := e.h.ChanRecvTimeout; {
    464 	case timeout == 0: // only consume available
    465 		for {
    466 			select {
    467 			case b := <-ch:
    468 				bs = append(bs, b)
    469 			default:
    470 				break L1
    471 			}
    472 		}
    473 	case timeout > 0: // consume until timeout
    474 		tt := time.NewTimer(timeout)
    475 		for {
    476 			select {
    477 			case b := <-ch:
    478 				bs = append(bs, b)
    479 			case <-tt.C:
    480 				// close(tt.C)
    481 				break L1
    482 			}
    483 		}
    484 	default: // consume until close
    485 		for b := range ch {
    486 			bs = append(bs, b)
    487 		}
    488 	}
    489 
    490 	e.e.EncodeStringBytesRaw(bs)
    491 	e.blist.put(bs)
    492 	if !byteSliceSameData(bs0, bs) {
    493 		e.blist.put(bs0)
    494 	}
    495 }
    496 
    497 func (e *Encoder) kStructSfi(f *codecFnInfo) []*structFieldInfo {
    498 	if e.h.Canonical {
    499 		return f.ti.sfi.sorted()
    500 	}
    501 	return f.ti.sfi.source()
    502 }
    503 
    504 func (e *Encoder) kStructNoOmitempty(f *codecFnInfo, rv reflect.Value) {
    505 	var tisfi []*structFieldInfo
    506 	if f.ti.toArray || e.h.StructToArray { // toArray
    507 		tisfi = f.ti.sfi.source()
    508 		e.arrayStart(len(tisfi))
    509 		for _, si := range tisfi {
    510 			e.arrayElem()
    511 			e.encodeValue(si.path.field(rv), nil)
    512 		}
    513 		e.arrayEnd()
    514 	} else {
    515 		tisfi = e.kStructSfi(f)
    516 		e.mapStart(len(tisfi))
    517 		keytyp := f.ti.keyType
    518 		for _, si := range tisfi {
    519 			e.mapElemKey()
    520 			e.kStructFieldKey(keytyp, si.path.encNameAsciiAlphaNum, si.encName)
    521 			e.mapElemValue()
    522 			e.encodeValue(si.path.field(rv), nil)
    523 		}
    524 		e.mapEnd()
    525 	}
    526 }
    527 
    528 func (e *Encoder) kStructFieldKey(keyType valueType, encNameAsciiAlphaNum bool, encName string) {
    529 	encStructFieldKey(encName, e.e, e.w(), keyType, encNameAsciiAlphaNum, e.js)
    530 }
    531 
    532 func (e *Encoder) kStruct(f *codecFnInfo, rv reflect.Value) {
    533 	var newlen int
    534 	ti := f.ti
    535 	toMap := !(ti.toArray || e.h.StructToArray)
    536 	var mf map[string]interface{}
    537 	if ti.flagMissingFielder {
    538 		mf = rv2i(rv).(MissingFielder).CodecMissingFields()
    539 		toMap = true
    540 		newlen += len(mf)
    541 	} else if ti.flagMissingFielderPtr {
    542 		rv2 := e.addrRV(rv, ti.rt, ti.ptr)
    543 		mf = rv2i(rv2).(MissingFielder).CodecMissingFields()
    544 		toMap = true
    545 		newlen += len(mf)
    546 	}
    547 	tisfi := ti.sfi.source()
    548 	newlen += len(tisfi)
    549 
    550 	var fkvs = e.slist.get(newlen)[:newlen]
    551 
    552 	recur := e.h.RecursiveEmptyCheck
    553 
    554 	var kv sfiRv
    555 	var j int
    556 	if toMap {
    557 		newlen = 0
    558 		for _, si := range e.kStructSfi(f) {
    559 			kv.r = si.path.field(rv)
    560 			if si.path.omitEmpty && isEmptyValue(kv.r, e.h.TypeInfos, recur) {
    561 				continue
    562 			}
    563 			kv.v = si
    564 			fkvs[newlen] = kv
    565 			newlen++
    566 		}
    567 
    568 		var mf2s []stringIntf
    569 		if len(mf) > 0 {
    570 			mf2s = make([]stringIntf, 0, len(mf))
    571 			for k, v := range mf {
    572 				if k == "" {
    573 					continue
    574 				}
    575 				if ti.infoFieldOmitempty && isEmptyValue(reflect.ValueOf(v), e.h.TypeInfos, recur) {
    576 					continue
    577 				}
    578 				mf2s = append(mf2s, stringIntf{k, v})
    579 			}
    580 		}
    581 
    582 		e.mapStart(newlen + len(mf2s))
    583 
    584 		// When there are missing fields, and Canonical flag is set,
    585 		// we cannot have the missing fields and struct fields sorted independently.
    586 		// We have to capture them together and sort as a unit.
    587 
    588 		if len(mf2s) > 0 && e.h.Canonical {
    589 			mf2w := make([]encStructFieldObj, newlen+len(mf2s))
    590 			for j = 0; j < newlen; j++ {
    591 				kv = fkvs[j]
    592 				mf2w[j] = encStructFieldObj{kv.v.encName, kv.r, nil, kv.v.path.encNameAsciiAlphaNum, true}
    593 			}
    594 			for _, v := range mf2s {
    595 				mf2w[j] = encStructFieldObj{v.v, reflect.Value{}, v.i, false, false}
    596 				j++
    597 			}
    598 			sort.Sort((encStructFieldObjSlice)(mf2w))
    599 			for _, v := range mf2w {
    600 				e.mapElemKey()
    601 				e.kStructFieldKey(ti.keyType, v.ascii, v.key)
    602 				e.mapElemValue()
    603 				if v.isRv {
    604 					e.encodeValue(v.rv, nil)
    605 				} else {
    606 					e.encode(v.intf)
    607 				}
    608 			}
    609 		} else {
    610 			keytyp := ti.keyType
    611 			for j = 0; j < newlen; j++ {
    612 				kv = fkvs[j]
    613 				e.mapElemKey()
    614 				e.kStructFieldKey(keytyp, kv.v.path.encNameAsciiAlphaNum, kv.v.encName)
    615 				e.mapElemValue()
    616 				e.encodeValue(kv.r, nil)
    617 			}
    618 			for _, v := range mf2s {
    619 				e.mapElemKey()
    620 				e.kStructFieldKey(keytyp, false, v.v)
    621 				e.mapElemValue()
    622 				e.encode(v.i)
    623 			}
    624 		}
    625 
    626 		e.mapEnd()
    627 	} else {
    628 		newlen = len(tisfi)
    629 		for i, si := range tisfi { // use unsorted array (to match sequence in struct)
    630 			kv.r = si.path.field(rv)
    631 			// use the zero value.
    632 			// if a reference or struct, set to nil (so you do not output too much)
    633 			if si.path.omitEmpty && isEmptyValue(kv.r, e.h.TypeInfos, recur) {
    634 				switch kv.r.Kind() {
    635 				case reflect.Struct, reflect.Interface, reflect.Ptr, reflect.Array, reflect.Map, reflect.Slice:
    636 					kv.r = reflect.Value{} //encode as nil
    637 				}
    638 			}
    639 			fkvs[i] = kv
    640 		}
    641 		// encode it all
    642 		e.arrayStart(newlen)
    643 		for j = 0; j < newlen; j++ {
    644 			e.arrayElem()
    645 			e.encodeValue(fkvs[j].r, nil)
    646 		}
    647 		e.arrayEnd()
    648 	}
    649 
    650 	// do not use defer. Instead, use explicit pool return at end of function.
    651 	// defer has a cost we are trying to avoid.
    652 	// If there is a panic and these slices are not returned, it is ok.
    653 	e.slist.put(fkvs)
    654 }
    655 
    656 func (e *Encoder) kMap(f *codecFnInfo, rv reflect.Value) {
    657 	l := rvLenMap(rv)
    658 	e.mapStart(l)
    659 	if l == 0 {
    660 		e.mapEnd()
    661 		return
    662 	}
    663 
    664 	// determine the underlying key and val encFn's for the map.
    665 	// This eliminates some work which is done for each loop iteration i.e.
    666 	// rv.Type(), ref.ValueOf(rt).Pointer(), then check map/list for fn.
    667 	//
    668 	// However, if kind is reflect.Interface, do not pre-determine the
    669 	// encoding type, because preEncodeValue may break it down to
    670 	// a concrete type and kInterface will bomb.
    671 
    672 	var keyFn, valFn *codecFn
    673 
    674 	ktypeKind := reflect.Kind(f.ti.keykind)
    675 	vtypeKind := reflect.Kind(f.ti.elemkind)
    676 
    677 	rtval := f.ti.elem
    678 	rtvalkind := vtypeKind
    679 	for rtvalkind == reflect.Ptr {
    680 		rtval = rtval.Elem()
    681 		rtvalkind = rtval.Kind()
    682 	}
    683 	if rtvalkind != reflect.Interface {
    684 		valFn = e.h.fn(rtval)
    685 	}
    686 
    687 	var rvv = mapAddrLoopvarRV(f.ti.elem, vtypeKind)
    688 
    689 	rtkey := f.ti.key
    690 	var keyTypeIsString = stringTypId == rt2id(rtkey) // rtkeyid
    691 	if keyTypeIsString {
    692 		keyFn = e.h.fn(rtkey)
    693 	} else {
    694 		for rtkey.Kind() == reflect.Ptr {
    695 			rtkey = rtkey.Elem()
    696 		}
    697 		if rtkey.Kind() != reflect.Interface {
    698 			keyFn = e.h.fn(rtkey)
    699 		}
    700 	}
    701 
    702 	if e.h.Canonical {
    703 		e.kMapCanonical(f.ti, rv, rvv, keyFn, valFn)
    704 		e.mapEnd()
    705 		return
    706 	}
    707 
    708 	var rvk = mapAddrLoopvarRV(f.ti.key, ktypeKind)
    709 
    710 	var it mapIter
    711 	mapRange(&it, rv, rvk, rvv, true)
    712 
    713 	for it.Next() {
    714 		e.mapElemKey()
    715 		if keyTypeIsString {
    716 			e.e.EncodeString(it.Key().String())
    717 		} else {
    718 			e.encodeValue(it.Key(), keyFn)
    719 		}
    720 		e.mapElemValue()
    721 		e.encodeValue(it.Value(), valFn)
    722 	}
    723 	it.Done()
    724 
    725 	e.mapEnd()
    726 }
    727 
    728 func (e *Encoder) kMapCanonical(ti *typeInfo, rv, rvv reflect.Value, keyFn, valFn *codecFn) {
    729 	// The base kind of the type of the map key is sufficient for ordering.
    730 	// We only do out of band if that kind is not ordered (number or string), bool or time.Time.
    731 	// If the key is a predeclared type, directly call methods on encDriver e.g. EncodeString
    732 	// but if not, call encodeValue, in case it has an extension registered or otherwise.
    733 	rtkey := ti.key
    734 	rtkeydecl := rtkey.PkgPath() == "" && rtkey.Name() != "" // key type is predeclared
    735 
    736 	mks := rv.MapKeys()
    737 	rtkeyKind := rtkey.Kind()
    738 	kfast := mapKeyFastKindFor(rtkeyKind)
    739 	visindirect := mapStoresElemIndirect(uintptr(ti.elemsize))
    740 	visref := refBitset.isset(ti.elemkind)
    741 
    742 	switch rtkeyKind {
    743 	case reflect.Bool:
    744 		// though bool keys make no sense in a map, it *could* happen.
    745 		// in that case, we MUST support it in reflection mode,
    746 		// as that is the fallback for even codecgen and others.
    747 
    748 		// sort the keys so that false comes before true
    749 		// ie if 2 keys in order (true, false), then swap them
    750 		if len(mks) == 2 && mks[0].Bool() {
    751 			mks[0], mks[1] = mks[1], mks[0]
    752 		}
    753 		for i := range mks {
    754 			e.mapElemKey()
    755 			if rtkeydecl {
    756 				e.e.EncodeBool(mks[i].Bool())
    757 			} else {
    758 				e.encodeValueNonNil(mks[i], keyFn)
    759 			}
    760 			e.mapElemValue()
    761 			e.encodeValue(mapGet(rv, mks[i], rvv, kfast, visindirect, visref), valFn)
    762 		}
    763 	case reflect.String:
    764 		mksv := make([]stringRv, len(mks))
    765 		for i, k := range mks {
    766 			v := &mksv[i]
    767 			v.r = k
    768 			v.v = k.String()
    769 		}
    770 		sort.Sort(stringRvSlice(mksv))
    771 		for i := range mksv {
    772 			e.mapElemKey()
    773 			if rtkeydecl {
    774 				e.e.EncodeString(mksv[i].v)
    775 			} else {
    776 				e.encodeValueNonNil(mksv[i].r, keyFn)
    777 			}
    778 			e.mapElemValue()
    779 			e.encodeValue(mapGet(rv, mksv[i].r, rvv, kfast, visindirect, visref), valFn)
    780 		}
    781 	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr:
    782 		mksv := make([]uint64Rv, len(mks))
    783 		for i, k := range mks {
    784 			v := &mksv[i]
    785 			v.r = k
    786 			v.v = k.Uint()
    787 		}
    788 		sort.Sort(uint64RvSlice(mksv))
    789 		for i := range mksv {
    790 			e.mapElemKey()
    791 			if rtkeydecl {
    792 				e.e.EncodeUint(mksv[i].v)
    793 			} else {
    794 				e.encodeValueNonNil(mksv[i].r, keyFn)
    795 			}
    796 			e.mapElemValue()
    797 			e.encodeValue(mapGet(rv, mksv[i].r, rvv, kfast, visindirect, visref), valFn)
    798 		}
    799 	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
    800 		mksv := make([]int64Rv, len(mks))
    801 		for i, k := range mks {
    802 			v := &mksv[i]
    803 			v.r = k
    804 			v.v = k.Int()
    805 		}
    806 		sort.Sort(int64RvSlice(mksv))
    807 		for i := range mksv {
    808 			e.mapElemKey()
    809 			if rtkeydecl {
    810 				e.e.EncodeInt(mksv[i].v)
    811 			} else {
    812 				e.encodeValueNonNil(mksv[i].r, keyFn)
    813 			}
    814 			e.mapElemValue()
    815 			e.encodeValue(mapGet(rv, mksv[i].r, rvv, kfast, visindirect, visref), valFn)
    816 		}
    817 	case reflect.Float32:
    818 		mksv := make([]float64Rv, len(mks))
    819 		for i, k := range mks {
    820 			v := &mksv[i]
    821 			v.r = k
    822 			v.v = k.Float()
    823 		}
    824 		sort.Sort(float64RvSlice(mksv))
    825 		for i := range mksv {
    826 			e.mapElemKey()
    827 			if rtkeydecl {
    828 				e.e.EncodeFloat32(float32(mksv[i].v))
    829 			} else {
    830 				e.encodeValueNonNil(mksv[i].r, keyFn)
    831 			}
    832 			e.mapElemValue()
    833 			e.encodeValue(mapGet(rv, mksv[i].r, rvv, kfast, visindirect, visref), valFn)
    834 		}
    835 	case reflect.Float64:
    836 		mksv := make([]float64Rv, len(mks))
    837 		for i, k := range mks {
    838 			v := &mksv[i]
    839 			v.r = k
    840 			v.v = k.Float()
    841 		}
    842 		sort.Sort(float64RvSlice(mksv))
    843 		for i := range mksv {
    844 			e.mapElemKey()
    845 			if rtkeydecl {
    846 				e.e.EncodeFloat64(mksv[i].v)
    847 			} else {
    848 				e.encodeValueNonNil(mksv[i].r, keyFn)
    849 			}
    850 			e.mapElemValue()
    851 			e.encodeValue(mapGet(rv, mksv[i].r, rvv, kfast, visindirect, visref), valFn)
    852 		}
    853 	default:
    854 		if rtkey == timeTyp {
    855 			mksv := make([]timeRv, len(mks))
    856 			for i, k := range mks {
    857 				v := &mksv[i]
    858 				v.r = k
    859 				v.v = rv2i(k).(time.Time)
    860 			}
    861 			sort.Sort(timeRvSlice(mksv))
    862 			for i := range mksv {
    863 				e.mapElemKey()
    864 				e.e.EncodeTime(mksv[i].v)
    865 				e.mapElemValue()
    866 				e.encodeValue(mapGet(rv, mksv[i].r, rvv, kfast, visindirect, visref), valFn)
    867 			}
    868 			break
    869 		}
    870 
    871 		// out-of-band
    872 		// first encode each key to a []byte first, then sort them, then record
    873 		bs0 := e.blist.get(len(mks) * 16)
    874 		mksv := bs0
    875 		mksbv := make([]bytesRv, len(mks))
    876 
    877 		func() {
    878 			// replicate sideEncode logic
    879 			defer func(wb bytesEncAppender, bytes bool, c containerState, state interface{}) {
    880 				e.wb = wb
    881 				e.bytes = bytes
    882 				e.c = c
    883 				e.e.restoreState(state)
    884 			}(e.wb, e.bytes, e.c, e.e.captureState())
    885 
    886 			// e2 := NewEncoderBytes(&mksv, e.hh)
    887 			e.wb = bytesEncAppender{mksv[:0], &mksv}
    888 			e.bytes = true
    889 			e.c = 0
    890 			e.e.resetState()
    891 
    892 			for i, k := range mks {
    893 				v := &mksbv[i]
    894 				l := len(mksv)
    895 
    896 				e.c = containerMapKey
    897 				e.encodeValue(k, nil)
    898 				e.atEndOfEncode()
    899 				e.w().end()
    900 
    901 				v.r = k
    902 				v.v = mksv[l:]
    903 			}
    904 		}()
    905 
    906 		sort.Sort(bytesRvSlice(mksbv))
    907 		for j := range mksbv {
    908 			e.mapElemKey()
    909 			e.encWr.writeb(mksbv[j].v)
    910 			e.mapElemValue()
    911 			e.encodeValue(mapGet(rv, mksbv[j].r, rvv, kfast, visindirect, visref), valFn)
    912 		}
    913 		e.blist.put(mksv)
    914 		if !byteSliceSameData(bs0, mksv) {
    915 			e.blist.put(bs0)
    916 		}
    917 	}
    918 }
    919 
    920 // Encoder writes an object to an output stream in a supported format.
    921 //
    922 // Encoder is NOT safe for concurrent use i.e. a Encoder cannot be used
    923 // concurrently in multiple goroutines.
    924 //
    925 // However, as Encoder could be allocation heavy to initialize, a Reset method is provided
    926 // so its state can be reused to decode new input streams repeatedly.
    927 // This is the idiomatic way to use.
    928 type Encoder struct {
    929 	panicHdl
    930 
    931 	e encDriver
    932 
    933 	h *BasicHandle
    934 
    935 	// hopefully, reduce derefencing cost by laying the encWriter inside the Encoder
    936 	encWr
    937 
    938 	// ---- cpu cache line boundary
    939 	hh Handle
    940 
    941 	blist bytesFreelist
    942 	err   error
    943 
    944 	// ---- cpu cache line boundary
    945 
    946 	// ---- writable fields during execution --- *try* to keep in sep cache line
    947 
    948 	// ci holds interfaces during an encoding (if CheckCircularRef=true)
    949 	//
    950 	// We considered using a []uintptr (slice of pointer addresses) retrievable via rv.UnsafeAddr.
    951 	// However, it is possible for the same pointer to point to 2 different types e.g.
    952 	//    type T struct { tHelper }
    953 	//    Here, for var v T; &v and &v.tHelper are the same pointer.
    954 	// Consequently, we need a tuple of type and pointer, which interface{} natively provides.
    955 	ci []interface{} // []uintptr
    956 
    957 	perType encPerType
    958 
    959 	slist sfiRvFreelist
    960 }
    961 
    962 // NewEncoder returns an Encoder for encoding into an io.Writer.
    963 //
    964 // For efficiency, Users are encouraged to configure WriterBufferSize on the handle
    965 // OR pass in a memory buffered writer (eg bufio.Writer, bytes.Buffer).
    966 func NewEncoder(w io.Writer, h Handle) *Encoder {
    967 	e := h.newEncDriver().encoder()
    968 	if w != nil {
    969 		e.Reset(w)
    970 	}
    971 	return e
    972 }
    973 
    974 // NewEncoderBytes returns an encoder for encoding directly and efficiently
    975 // into a byte slice, using zero-copying to temporary slices.
    976 //
    977 // It will potentially replace the output byte slice pointed to.
    978 // After encoding, the out parameter contains the encoded contents.
    979 func NewEncoderBytes(out *[]byte, h Handle) *Encoder {
    980 	e := h.newEncDriver().encoder()
    981 	if out != nil {
    982 		e.ResetBytes(out)
    983 	}
    984 	return e
    985 }
    986 
    987 func (e *Encoder) init(h Handle) {
    988 	initHandle(h)
    989 	e.err = errEncoderNotInitialized
    990 	e.bytes = true
    991 	e.hh = h
    992 	e.h = h.getBasicHandle()
    993 	e.be = e.hh.isBinary()
    994 }
    995 
    996 func (e *Encoder) w() *encWr {
    997 	return &e.encWr
    998 }
    999 
   1000 func (e *Encoder) resetCommon() {
   1001 	e.e.reset()
   1002 	if e.ci != nil {
   1003 		e.ci = e.ci[:0]
   1004 	}
   1005 	e.c = 0
   1006 	e.calls = 0
   1007 	e.seq = 0
   1008 	e.err = nil
   1009 }
   1010 
   1011 // Reset resets the Encoder with a new output stream.
   1012 //
   1013 // This accommodates using the state of the Encoder,
   1014 // where it has "cached" information about sub-engines.
   1015 func (e *Encoder) Reset(w io.Writer) {
   1016 	e.bytes = false
   1017 	if e.wf == nil {
   1018 		e.wf = new(bufioEncWriter)
   1019 	}
   1020 	e.wf.reset(w, e.h.WriterBufferSize, &e.blist)
   1021 	e.resetCommon()
   1022 }
   1023 
   1024 // ResetBytes resets the Encoder with a new destination output []byte.
   1025 func (e *Encoder) ResetBytes(out *[]byte) {
   1026 	e.bytes = true
   1027 	e.wb.reset(encInBytes(out), out)
   1028 	e.resetCommon()
   1029 }
   1030 
   1031 // Encode writes an object into a stream.
   1032 //
   1033 // Encoding can be configured via the struct tag for the fields.
   1034 // The key (in the struct tags) that we look at is configurable.
   1035 //
   1036 // By default, we look up the "codec" key in the struct field's tags,
   1037 // and fall bak to the "json" key if "codec" is absent.
   1038 // That key in struct field's tag value is the key name,
   1039 // followed by an optional comma and options.
   1040 //
   1041 // To set an option on all fields (e.g. omitempty on all fields), you
   1042 // can create a field called _struct, and set flags on it. The options
   1043 // which can be set on _struct are:
   1044 //   - omitempty: so all fields are omitted if empty
   1045 //   - toarray: so struct is encoded as an array
   1046 //   - int: so struct key names are encoded as signed integers (instead of strings)
   1047 //   - uint: so struct key names are encoded as unsigned integers (instead of strings)
   1048 //   - float: so struct key names are encoded as floats (instead of strings)
   1049 //
   1050 // More details on these below.
   1051 //
   1052 // Struct values "usually" encode as maps. Each exported struct field is encoded unless:
   1053 //   - the field's tag is "-", OR
   1054 //   - the field is empty (empty or the zero value) and its tag specifies the "omitempty" option.
   1055 //
   1056 // When encoding as a map, the first string in the tag (before the comma)
   1057 // is the map key string to use when encoding.
   1058 // ...
   1059 // This key is typically encoded as a string.
   1060 // However, there are instances where the encoded stream has mapping keys encoded as numbers.
   1061 // For example, some cbor streams have keys as integer codes in the stream, but they should map
   1062 // to fields in a structured object. Consequently, a struct is the natural representation in code.
   1063 // For these, configure the struct to encode/decode the keys as numbers (instead of string).
   1064 // This is done with the int,uint or float option on the _struct field (see above).
   1065 //
   1066 // However, struct values may encode as arrays. This happens when:
   1067 //   - StructToArray Encode option is set, OR
   1068 //   - the tag on the _struct field sets the "toarray" option
   1069 //
   1070 // Note that omitempty is ignored when encoding struct values as arrays,
   1071 // as an entry must be encoded for each field, to maintain its position.
   1072 //
   1073 // Values with types that implement MapBySlice are encoded as stream maps.
   1074 //
   1075 // The empty values (for omitempty option) are false, 0, any nil pointer
   1076 // or interface value, and any array, slice, map, or string of length zero.
   1077 //
   1078 // Anonymous fields are encoded inline except:
   1079 //   - the struct tag specifies a replacement name (first value)
   1080 //   - the field is of an interface type
   1081 //
   1082 // Examples:
   1083 //
   1084 //	// NOTE: 'json:' can be used as struct tag key, in place 'codec:' below.
   1085 //	type MyStruct struct {
   1086 //	    _struct bool    `codec:",omitempty"`   //set omitempty for every field
   1087 //	    Field1 string   `codec:"-"`            //skip this field
   1088 //	    Field2 int      `codec:"myName"`       //Use key "myName" in encode stream
   1089 //	    Field3 int32    `codec:",omitempty"`   //use key "Field3". Omit if empty.
   1090 //	    Field4 bool     `codec:"f4,omitempty"` //use key "f4". Omit if empty.
   1091 //	    io.Reader                              //use key "Reader".
   1092 //	    MyStruct        `codec:"my1"           //use key "my1".
   1093 //	    MyStruct                               //inline it
   1094 //	    ...
   1095 //	}
   1096 //
   1097 //	type MyStruct struct {
   1098 //	    _struct bool    `codec:",toarray"`     //encode struct as an array
   1099 //	}
   1100 //
   1101 //	type MyStruct struct {
   1102 //	    _struct bool    `codec:",uint"`        //encode struct with "unsigned integer" keys
   1103 //	    Field1 string   `codec:"1"`            //encode Field1 key using: EncodeInt(1)
   1104 //	    Field2 string   `codec:"2"`            //encode Field2 key using: EncodeInt(2)
   1105 //	}
   1106 //
   1107 // The mode of encoding is based on the type of the value. When a value is seen:
   1108 //   - If a Selfer, call its CodecEncodeSelf method
   1109 //   - If an extension is registered for it, call that extension function
   1110 //   - If implements encoding.(Binary|Text|JSON)Marshaler, call Marshal(Binary|Text|JSON) method
   1111 //   - Else encode it based on its reflect.Kind
   1112 //
   1113 // Note that struct field names and keys in map[string]XXX will be treated as symbols.
   1114 // Some formats support symbols (e.g. binc) and will properly encode the string
   1115 // only once in the stream, and use a tag to refer to it thereafter.
   1116 func (e *Encoder) Encode(v interface{}) (err error) {
   1117 	// tried to use closure, as runtime optimizes defer with no params.
   1118 	// This seemed to be causing weird issues (like circular reference found, unexpected panic, etc).
   1119 	// Also, see https://github.com/golang/go/issues/14939#issuecomment-417836139
   1120 	if !debugging {
   1121 		defer func() {
   1122 			// if error occurred during encoding, return that error;
   1123 			// else if error occurred on end'ing (i.e. during flush), return that error.
   1124 			if x := recover(); x != nil {
   1125 				panicValToErr(e, x, &e.err)
   1126 				err = e.err
   1127 			}
   1128 		}()
   1129 	}
   1130 
   1131 	e.MustEncode(v)
   1132 	return
   1133 }
   1134 
   1135 // MustEncode is like Encode, but panics if unable to Encode.
   1136 //
   1137 // Note: This provides insight to the code location that triggered the error.
   1138 func (e *Encoder) MustEncode(v interface{}) {
   1139 	halt.onerror(e.err)
   1140 	if e.hh == nil {
   1141 		halt.onerror(errNoFormatHandle)
   1142 	}
   1143 
   1144 	e.calls++
   1145 	e.encode(v)
   1146 	e.calls--
   1147 	if e.calls == 0 {
   1148 		e.atEndOfEncode()
   1149 		e.w().end()
   1150 	}
   1151 }
   1152 
   1153 // Release releases shared (pooled) resources.
   1154 //
   1155 // It is important to call Release() when done with an Encoder, so those resources
   1156 // are released instantly for use by subsequently created Encoders.
   1157 //
   1158 // Deprecated: Release is a no-op as pooled resources are not used with an Encoder.
   1159 // This method is kept for compatibility reasons only.
   1160 func (e *Encoder) Release() {
   1161 }
   1162 
   1163 func (e *Encoder) encode(iv interface{}) {
   1164 	// MARKER: a switch with only concrete types can be optimized.
   1165 	// consequently, we deal with nil and interfaces outside the switch.
   1166 
   1167 	if iv == nil {
   1168 		e.e.EncodeNil()
   1169 		return
   1170 	}
   1171 
   1172 	rv, ok := isNil(iv)
   1173 	if ok {
   1174 		e.e.EncodeNil()
   1175 		return
   1176 	}
   1177 
   1178 	switch v := iv.(type) {
   1179 	// case nil:
   1180 	// case Selfer:
   1181 	case Raw:
   1182 		e.rawBytes(v)
   1183 	case reflect.Value:
   1184 		e.encodeValue(v, nil)
   1185 
   1186 	case string:
   1187 		e.e.EncodeString(v)
   1188 	case bool:
   1189 		e.e.EncodeBool(v)
   1190 	case int:
   1191 		e.e.EncodeInt(int64(v))
   1192 	case int8:
   1193 		e.e.EncodeInt(int64(v))
   1194 	case int16:
   1195 		e.e.EncodeInt(int64(v))
   1196 	case int32:
   1197 		e.e.EncodeInt(int64(v))
   1198 	case int64:
   1199 		e.e.EncodeInt(v)
   1200 	case uint:
   1201 		e.e.EncodeUint(uint64(v))
   1202 	case uint8:
   1203 		e.e.EncodeUint(uint64(v))
   1204 	case uint16:
   1205 		e.e.EncodeUint(uint64(v))
   1206 	case uint32:
   1207 		e.e.EncodeUint(uint64(v))
   1208 	case uint64:
   1209 		e.e.EncodeUint(v)
   1210 	case uintptr:
   1211 		e.e.EncodeUint(uint64(v))
   1212 	case float32:
   1213 		e.e.EncodeFloat32(v)
   1214 	case float64:
   1215 		e.e.EncodeFloat64(v)
   1216 	case complex64:
   1217 		e.encodeComplex64(v)
   1218 	case complex128:
   1219 		e.encodeComplex128(v)
   1220 	case time.Time:
   1221 		e.e.EncodeTime(v)
   1222 	case []byte:
   1223 		e.e.EncodeStringBytesRaw(v)
   1224 	case *Raw:
   1225 		e.rawBytes(*v)
   1226 	case *string:
   1227 		e.e.EncodeString(*v)
   1228 	case *bool:
   1229 		e.e.EncodeBool(*v)
   1230 	case *int:
   1231 		e.e.EncodeInt(int64(*v))
   1232 	case *int8:
   1233 		e.e.EncodeInt(int64(*v))
   1234 	case *int16:
   1235 		e.e.EncodeInt(int64(*v))
   1236 	case *int32:
   1237 		e.e.EncodeInt(int64(*v))
   1238 	case *int64:
   1239 		e.e.EncodeInt(*v)
   1240 	case *uint:
   1241 		e.e.EncodeUint(uint64(*v))
   1242 	case *uint8:
   1243 		e.e.EncodeUint(uint64(*v))
   1244 	case *uint16:
   1245 		e.e.EncodeUint(uint64(*v))
   1246 	case *uint32:
   1247 		e.e.EncodeUint(uint64(*v))
   1248 	case *uint64:
   1249 		e.e.EncodeUint(*v)
   1250 	case *uintptr:
   1251 		e.e.EncodeUint(uint64(*v))
   1252 	case *float32:
   1253 		e.e.EncodeFloat32(*v)
   1254 	case *float64:
   1255 		e.e.EncodeFloat64(*v)
   1256 	case *complex64:
   1257 		e.encodeComplex64(*v)
   1258 	case *complex128:
   1259 		e.encodeComplex128(*v)
   1260 	case *time.Time:
   1261 		e.e.EncodeTime(*v)
   1262 	case *[]byte:
   1263 		if *v == nil {
   1264 			e.e.EncodeNil()
   1265 		} else {
   1266 			e.e.EncodeStringBytesRaw(*v)
   1267 		}
   1268 	default:
   1269 		// we can't check non-predefined types, as they might be a Selfer or extension.
   1270 		if skipFastpathTypeSwitchInDirectCall || !fastpathEncodeTypeSwitch(iv, e) {
   1271 			e.encodeValue(rv, nil)
   1272 		}
   1273 	}
   1274 }
   1275 
   1276 // encodeValue will encode a value.
   1277 //
   1278 // Note that encodeValue will handle nil in the stream early, so that the
   1279 // subsequent calls i.e. kXXX methods, etc do not have to handle it themselves.
   1280 func (e *Encoder) encodeValue(rv reflect.Value, fn *codecFn) {
   1281 	// if a valid fn is passed, it MUST BE for the dereferenced type of rv
   1282 
   1283 	// MARKER: We check if value is nil here, so that the kXXX method do not have to.
   1284 
   1285 	var sptr interface{}
   1286 	var rvp reflect.Value
   1287 	var rvpValid bool
   1288 TOP:
   1289 	switch rv.Kind() {
   1290 	case reflect.Ptr:
   1291 		if rvIsNil(rv) {
   1292 			e.e.EncodeNil()
   1293 			return
   1294 		}
   1295 		rvpValid = true
   1296 		rvp = rv
   1297 		rv = rv.Elem()
   1298 		goto TOP
   1299 	case reflect.Interface:
   1300 		if rvIsNil(rv) {
   1301 			e.e.EncodeNil()
   1302 			return
   1303 		}
   1304 		rvpValid = false
   1305 		rvp = reflect.Value{}
   1306 		rv = rv.Elem()
   1307 		goto TOP
   1308 	case reflect.Struct:
   1309 		if rvpValid && e.h.CheckCircularRef {
   1310 			sptr = rv2i(rvp)
   1311 			for _, vv := range e.ci {
   1312 				if eq4i(sptr, vv) { // error if sptr already seen
   1313 					e.errorf("circular reference found: %p, %T", sptr, sptr)
   1314 				}
   1315 			}
   1316 			e.ci = append(e.ci, sptr)
   1317 		}
   1318 	case reflect.Slice, reflect.Map, reflect.Chan:
   1319 		if rvIsNil(rv) {
   1320 			e.e.EncodeNil()
   1321 			return
   1322 		}
   1323 	case reflect.Invalid, reflect.Func:
   1324 		e.e.EncodeNil()
   1325 		return
   1326 	}
   1327 
   1328 	if fn == nil {
   1329 		fn = e.h.fn(rv.Type())
   1330 	}
   1331 
   1332 	if !fn.i.addrE { // typically, addrE = false, so check it first
   1333 		// keep rv same
   1334 	} else if rvpValid {
   1335 		rv = rvp
   1336 	} else {
   1337 		rv = e.addrRV(rv, fn.i.ti.rt, fn.i.ti.ptr)
   1338 	}
   1339 	fn.fe(e, &fn.i, rv)
   1340 
   1341 	if sptr != nil { // remove sptr
   1342 		e.ci = e.ci[:len(e.ci)-1]
   1343 	}
   1344 }
   1345 
   1346 // encodeValueNonNil can encode a number, bool, or string
   1347 // OR non-nil values of kind map, slice and chan.
   1348 func (e *Encoder) encodeValueNonNil(rv reflect.Value, fn *codecFn) {
   1349 	if fn == nil {
   1350 		fn = e.h.fn(rv.Type())
   1351 	}
   1352 
   1353 	if fn.i.addrE { // typically, addrE = false, so check it first
   1354 		rv = e.addrRV(rv, fn.i.ti.rt, fn.i.ti.ptr)
   1355 	}
   1356 	fn.fe(e, &fn.i, rv)
   1357 }
   1358 
   1359 // addrRV returns a addressable value which may be readonly
   1360 func (e *Encoder) addrRV(rv reflect.Value, typ, ptrType reflect.Type) (rva reflect.Value) {
   1361 	if rv.CanAddr() {
   1362 		return rvAddr(rv, ptrType)
   1363 	}
   1364 	if e.h.NoAddressableReadonly {
   1365 		rva = reflect.New(typ)
   1366 		rvSetDirect(rva.Elem(), rv)
   1367 		return
   1368 	}
   1369 	return rvAddr(e.perType.AddressableRO(rv), ptrType)
   1370 }
   1371 
   1372 func (e *Encoder) marshalUtf8(bs []byte, fnerr error) {
   1373 	e.onerror(fnerr)
   1374 	if bs == nil {
   1375 		e.e.EncodeNil()
   1376 	} else {
   1377 		e.e.EncodeString(stringView(bs))
   1378 	}
   1379 }
   1380 
   1381 func (e *Encoder) marshalAsis(bs []byte, fnerr error) {
   1382 	e.onerror(fnerr)
   1383 	if bs == nil {
   1384 		e.e.EncodeNil()
   1385 	} else {
   1386 		e.encWr.writeb(bs) // e.asis(bs)
   1387 	}
   1388 }
   1389 
   1390 func (e *Encoder) marshalRaw(bs []byte, fnerr error) {
   1391 	e.onerror(fnerr)
   1392 	if bs == nil {
   1393 		e.e.EncodeNil()
   1394 	} else {
   1395 		e.e.EncodeStringBytesRaw(bs)
   1396 	}
   1397 }
   1398 
   1399 func (e *Encoder) rawBytes(vv Raw) {
   1400 	v := []byte(vv)
   1401 	if !e.h.Raw {
   1402 		e.errorf("Raw values cannot be encoded: %v", v)
   1403 	}
   1404 	e.encWr.writeb(v)
   1405 }
   1406 
   1407 func (e *Encoder) wrapErr(v error, err *error) {
   1408 	*err = wrapCodecErr(v, e.hh.Name(), 0, true)
   1409 }
   1410 
   1411 // ---- container tracker methods
   1412 // Note: We update the .c after calling the callback.
   1413 // This way, the callback can know what the last status was.
   1414 
   1415 func (e *Encoder) mapStart(length int) {
   1416 	e.e.WriteMapStart(length)
   1417 	e.c = containerMapStart
   1418 }
   1419 
   1420 func (e *Encoder) mapElemKey() {
   1421 	if e.js {
   1422 		e.jsondriver().WriteMapElemKey()
   1423 	}
   1424 	e.c = containerMapKey
   1425 }
   1426 
   1427 func (e *Encoder) mapElemValue() {
   1428 	if e.js {
   1429 		e.jsondriver().WriteMapElemValue()
   1430 	}
   1431 	e.c = containerMapValue
   1432 }
   1433 
   1434 func (e *Encoder) mapEnd() {
   1435 	e.e.WriteMapEnd()
   1436 	e.c = 0
   1437 }
   1438 
   1439 func (e *Encoder) arrayStart(length int) {
   1440 	e.e.WriteArrayStart(length)
   1441 	e.c = containerArrayStart
   1442 }
   1443 
   1444 func (e *Encoder) arrayElem() {
   1445 	if e.js {
   1446 		e.jsondriver().WriteArrayElem()
   1447 	}
   1448 	e.c = containerArrayElem
   1449 }
   1450 
   1451 func (e *Encoder) arrayEnd() {
   1452 	e.e.WriteArrayEnd()
   1453 	e.c = 0
   1454 }
   1455 
   1456 // ----------
   1457 
   1458 func (e *Encoder) haltOnMbsOddLen(length int) {
   1459 	if length&1 != 0 { // similar to &1==1 or %2 == 1
   1460 		e.errorf("mapBySlice requires even slice length, but got %v", length)
   1461 	}
   1462 }
   1463 
   1464 func (e *Encoder) atEndOfEncode() {
   1465 	// e.e.atEndOfEncode()
   1466 	if e.js {
   1467 		e.jsondriver().atEndOfEncode()
   1468 	}
   1469 }
   1470 
   1471 func (e *Encoder) sideEncode(v interface{}, basetype reflect.Type, bs *[]byte) {
   1472 	// rv := baseRV(v)
   1473 	// e2 := NewEncoderBytes(bs, e.hh)
   1474 	// e2.encodeValue(rv, e2.h.fnNoExt(basetype))
   1475 	// e2.atEndOfEncode()
   1476 	// e2.w().end()
   1477 
   1478 	defer func(wb bytesEncAppender, bytes bool, c containerState, state interface{}) {
   1479 		e.wb = wb
   1480 		e.bytes = bytes
   1481 		e.c = c
   1482 		e.e.restoreState(state)
   1483 	}(e.wb, e.bytes, e.c, e.e.captureState())
   1484 
   1485 	e.wb = bytesEncAppender{encInBytes(bs)[:0], bs}
   1486 	e.bytes = true
   1487 	e.c = 0
   1488 	e.e.resetState()
   1489 
   1490 	// must call using fnNoExt
   1491 	rv := baseRV(v)
   1492 	e.encodeValue(rv, e.h.fnNoExt(basetype))
   1493 	e.atEndOfEncode()
   1494 	e.w().end()
   1495 }
   1496 
   1497 func encInBytes(out *[]byte) (in []byte) {
   1498 	in = *out
   1499 	if in == nil {
   1500 		in = make([]byte, defEncByteBufSize)
   1501 	}
   1502 	return
   1503 }
   1504 
   1505 func encStructFieldKey(encName string, ee encDriver, w *encWr,
   1506 	keyType valueType, encNameAsciiAlphaNum bool, js bool) {
   1507 	// use if-else-if, not switch (which compiles to binary-search)
   1508 	// since keyType is typically valueTypeString, branch prediction is pretty good.
   1509 
   1510 	if keyType == valueTypeString {
   1511 		if js && encNameAsciiAlphaNum { // keyType == valueTypeString
   1512 			w.writeqstr(encName)
   1513 		} else { // keyType == valueTypeString
   1514 			ee.EncodeString(encName)
   1515 		}
   1516 	} else if keyType == valueTypeInt {
   1517 		ee.EncodeInt(must.Int(strconv.ParseInt(encName, 10, 64)))
   1518 	} else if keyType == valueTypeUint {
   1519 		ee.EncodeUint(must.Uint(strconv.ParseUint(encName, 10, 64)))
   1520 	} else if keyType == valueTypeFloat {
   1521 		ee.EncodeFloat64(must.Float(strconv.ParseFloat(encName, 64)))
   1522 	} else {
   1523 		halt.errorf("invalid struct key type: %v", keyType)
   1524 	}
   1525 }