OSDN Git Service

feat(warder): add warder backbone (#181)
[bytom/vapor.git] / vendor / github.com / ugorji / go / codec / encode.go
1 // Copyright (c) 2012-2018 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         "bufio"
8         "encoding"
9         "errors"
10         "fmt"
11         "io"
12         "reflect"
13         "sort"
14         "strconv"
15         "sync"
16         "time"
17 )
18
19 const defEncByteBufSize = 1 << 6 // 4:16, 6:64, 8:256, 10:1024
20
21 var errEncoderNotInitialized = errors.New("Encoder not initialized")
22
23 // encWriter abstracts writing to a byte array or to an io.Writer.
24 type encWriter interface {
25         writeb([]byte)
26         writestr(string)
27         writen1(byte)
28         writen2(byte, byte)
29         atEndOfEncode()
30 }
31
32 // encDriver abstracts the actual codec (binc vs msgpack, etc)
33 type encDriver interface {
34         EncodeNil()
35         EncodeInt(i int64)
36         EncodeUint(i uint64)
37         EncodeBool(b bool)
38         EncodeFloat32(f float32)
39         EncodeFloat64(f float64)
40         // encodeExtPreamble(xtag byte, length int)
41         EncodeRawExt(re *RawExt, e *Encoder)
42         EncodeExt(v interface{}, xtag uint64, ext Ext, e *Encoder)
43         EncodeString(c charEncoding, v string)
44         // EncodeSymbol(v string)
45         EncodeStringBytes(c charEncoding, v []byte)
46         EncodeTime(time.Time)
47         //encBignum(f *big.Int)
48         //encStringRunes(c charEncoding, v []rune)
49         WriteArrayStart(length int)
50         WriteArrayElem()
51         WriteArrayEnd()
52         WriteMapStart(length int)
53         WriteMapElemKey()
54         WriteMapElemValue()
55         WriteMapEnd()
56
57         reset()
58         atEndOfEncode()
59 }
60
61 type ioEncStringWriter interface {
62         WriteString(s string) (n int, err error)
63 }
64
65 type encDriverAsis interface {
66         EncodeAsis(v []byte)
67 }
68
69 type encodeError struct {
70         codecError
71 }
72
73 func (e encodeError) Error() string {
74         return fmt.Sprintf("%s encode error: %v", e.name, e.err)
75 }
76
77 type encDriverNoopContainerWriter struct{}
78
79 func (encDriverNoopContainerWriter) WriteArrayStart(length int) {}
80 func (encDriverNoopContainerWriter) WriteArrayElem()            {}
81 func (encDriverNoopContainerWriter) WriteArrayEnd()             {}
82 func (encDriverNoopContainerWriter) WriteMapStart(length int)   {}
83 func (encDriverNoopContainerWriter) WriteMapElemKey()           {}
84 func (encDriverNoopContainerWriter) WriteMapElemValue()         {}
85 func (encDriverNoopContainerWriter) WriteMapEnd()               {}
86 func (encDriverNoopContainerWriter) atEndOfEncode()             {}
87
88 type encDriverTrackContainerWriter struct {
89         c containerState
90 }
91
92 func (e *encDriverTrackContainerWriter) WriteArrayStart(length int) { e.c = containerArrayStart }
93 func (e *encDriverTrackContainerWriter) WriteArrayElem()            { e.c = containerArrayElem }
94 func (e *encDriverTrackContainerWriter) WriteArrayEnd()             { e.c = containerArrayEnd }
95 func (e *encDriverTrackContainerWriter) WriteMapStart(length int)   { e.c = containerMapStart }
96 func (e *encDriverTrackContainerWriter) WriteMapElemKey()           { e.c = containerMapKey }
97 func (e *encDriverTrackContainerWriter) WriteMapElemValue()         { e.c = containerMapValue }
98 func (e *encDriverTrackContainerWriter) WriteMapEnd()               { e.c = containerMapEnd }
99 func (e *encDriverTrackContainerWriter) atEndOfEncode()             {}
100
101 // type ioEncWriterWriter interface {
102 //      WriteByte(c byte) error
103 //      WriteString(s string) (n int, err error)
104 //      Write(p []byte) (n int, err error)
105 // }
106
107 // EncodeOptions captures configuration options during encode.
108 type EncodeOptions struct {
109         // WriterBufferSize is the size of the buffer used when writing.
110         //
111         // if > 0, we use a smart buffer internally for performance purposes.
112         WriterBufferSize int
113
114         // ChanRecvTimeout is the timeout used when selecting from a chan.
115         //
116         // Configuring this controls how we receive from a chan during the encoding process.
117         //   - If ==0, we only consume the elements currently available in the chan.
118         //   - if  <0, we consume until the chan is closed.
119         //   - If  >0, we consume until this timeout.
120         ChanRecvTimeout time.Duration
121
122         // StructToArray specifies to encode a struct as an array, and not as a map
123         StructToArray bool
124
125         // Canonical representation means that encoding a value will always result in the same
126         // sequence of bytes.
127         //
128         // This only affects maps, as the iteration order for maps is random.
129         //
130         // The implementation MAY use the natural sort order for the map keys if possible:
131         //
132         //     - If there is a natural sort order (ie for number, bool, string or []byte keys),
133         //       then the map keys are first sorted in natural order and then written
134         //       with corresponding map values to the strema.
135         //     - If there is no natural sort order, then the map keys will first be
136         //       encoded into []byte, and then sorted,
137         //       before writing the sorted keys and the corresponding map values to the stream.
138         //
139         Canonical bool
140
141         // CheckCircularRef controls whether we check for circular references
142         // and error fast during an encode.
143         //
144         // If enabled, an error is received if a pointer to a struct
145         // references itself either directly or through one of its fields (iteratively).
146         //
147         // This is opt-in, as there may be a performance hit to checking circular references.
148         CheckCircularRef bool
149
150         // RecursiveEmptyCheck controls whether we descend into interfaces, structs and pointers
151         // when checking if a value is empty.
152         //
153         // Note that this may make OmitEmpty more expensive, as it incurs a lot more reflect calls.
154         RecursiveEmptyCheck bool
155
156         // Raw controls whether we encode Raw values.
157         // This is a "dangerous" option and must be explicitly set.
158         // If set, we blindly encode Raw values as-is, without checking
159         // if they are a correct representation of a value in that format.
160         // If unset, we error out.
161         Raw bool
162
163         // // AsSymbols defines what should be encoded as symbols.
164         // //
165         // // Encoding as symbols can reduce the encoded size significantly.
166         // //
167         // // However, during decoding, each string to be encoded as a symbol must
168         // // be checked to see if it has been seen before. Consequently, encoding time
169         // // will increase if using symbols, because string comparisons has a clear cost.
170         // //
171         // // Sample values:
172         // //   AsSymbolNone
173         // //   AsSymbolAll
174         // //   AsSymbolMapStringKeys
175         // //   AsSymbolMapStringKeysFlag | AsSymbolStructFieldNameFlag
176         // AsSymbols AsSymbolFlag
177 }
178
179 // ---------------------------------------------
180
181 // ioEncWriter implements encWriter and can write to an io.Writer implementation
182 type ioEncWriter struct {
183         w  io.Writer
184         ww io.Writer
185         bw io.ByteWriter
186         sw ioEncStringWriter
187         fw ioFlusher
188         b  [8]byte
189 }
190
191 func (z *ioEncWriter) WriteByte(b byte) (err error) {
192         z.b[0] = b
193         _, err = z.w.Write(z.b[:1])
194         return
195 }
196
197 func (z *ioEncWriter) WriteString(s string) (n int, err error) {
198         return z.w.Write(bytesView(s))
199 }
200
201 func (z *ioEncWriter) writeb(bs []byte) {
202         if _, err := z.ww.Write(bs); err != nil {
203                 panic(err)
204         }
205 }
206
207 func (z *ioEncWriter) writestr(s string) {
208         if _, err := z.sw.WriteString(s); err != nil {
209                 panic(err)
210         }
211 }
212
213 func (z *ioEncWriter) writen1(b byte) {
214         if err := z.bw.WriteByte(b); err != nil {
215                 panic(err)
216         }
217 }
218
219 func (z *ioEncWriter) writen2(b1, b2 byte) {
220         var err error
221         if err = z.bw.WriteByte(b1); err == nil {
222                 if err = z.bw.WriteByte(b2); err == nil {
223                         return
224                 }
225         }
226         panic(err)
227 }
228
229 // func (z *ioEncWriter) writen5(b1, b2, b3, b4, b5 byte) {
230 //      z.b[0], z.b[1], z.b[2], z.b[3], z.b[4] = b1, b2, b3, b4, b5
231 //      if _, err := z.ww.Write(z.b[:5]); err != nil {
232 //              panic(err)
233 //      }
234 // }
235
236 func (z *ioEncWriter) atEndOfEncode() {
237         if z.fw != nil {
238                 if err := z.fw.Flush(); err != nil {
239                         panic(err)
240                 }
241         }
242 }
243
244 // ---------------------------------------------
245
246 // bytesEncAppender implements encWriter and can write to an byte slice.
247 type bytesEncAppender struct {
248         b   []byte
249         out *[]byte
250 }
251
252 func (z *bytesEncAppender) writeb(s []byte) {
253         z.b = append(z.b, s...)
254 }
255 func (z *bytesEncAppender) writestr(s string) {
256         z.b = append(z.b, s...)
257 }
258 func (z *bytesEncAppender) writen1(b1 byte) {
259         z.b = append(z.b, b1)
260 }
261 func (z *bytesEncAppender) writen2(b1, b2 byte) {
262         z.b = append(z.b, b1, b2)
263 }
264 func (z *bytesEncAppender) atEndOfEncode() {
265         *(z.out) = z.b
266 }
267 func (z *bytesEncAppender) reset(in []byte, out *[]byte) {
268         z.b = in[:0]
269         z.out = out
270 }
271
272 // ---------------------------------------------
273
274 func (e *Encoder) rawExt(f *codecFnInfo, rv reflect.Value) {
275         e.e.EncodeRawExt(rv2i(rv).(*RawExt), e)
276 }
277
278 func (e *Encoder) ext(f *codecFnInfo, rv reflect.Value) {
279         e.e.EncodeExt(rv2i(rv), f.xfTag, f.xfFn, e)
280 }
281
282 func (e *Encoder) selferMarshal(f *codecFnInfo, rv reflect.Value) {
283         rv2i(rv).(Selfer).CodecEncodeSelf(e)
284 }
285
286 func (e *Encoder) binaryMarshal(f *codecFnInfo, rv reflect.Value) {
287         bs, fnerr := rv2i(rv).(encoding.BinaryMarshaler).MarshalBinary()
288         e.marshal(bs, fnerr, false, cRAW)
289 }
290
291 func (e *Encoder) textMarshal(f *codecFnInfo, rv reflect.Value) {
292         bs, fnerr := rv2i(rv).(encoding.TextMarshaler).MarshalText()
293         e.marshal(bs, fnerr, false, cUTF8)
294 }
295
296 func (e *Encoder) jsonMarshal(f *codecFnInfo, rv reflect.Value) {
297         bs, fnerr := rv2i(rv).(jsonMarshaler).MarshalJSON()
298         e.marshal(bs, fnerr, true, cUTF8)
299 }
300
301 func (e *Encoder) raw(f *codecFnInfo, rv reflect.Value) {
302         e.rawBytes(rv2i(rv).(Raw))
303 }
304
305 func (e *Encoder) kInvalid(f *codecFnInfo, rv reflect.Value) {
306         e.e.EncodeNil()
307 }
308
309 func (e *Encoder) kErr(f *codecFnInfo, rv reflect.Value) {
310         e.errorf("unsupported kind %s, for %#v", rv.Kind(), rv)
311 }
312
313 func (e *Encoder) kSlice(f *codecFnInfo, rv reflect.Value) {
314         ti := f.ti
315         ee := e.e
316         // array may be non-addressable, so we have to manage with care
317         //   (don't call rv.Bytes, rv.Slice, etc).
318         // E.g. type struct S{B [2]byte};
319         //   Encode(S{}) will bomb on "panic: slice of unaddressable array".
320         if f.seq != seqTypeArray {
321                 if rv.IsNil() {
322                         ee.EncodeNil()
323                         return
324                 }
325                 // If in this method, then there was no extension function defined.
326                 // So it's okay to treat as []byte.
327                 if ti.rtid == uint8SliceTypId {
328                         ee.EncodeStringBytes(cRAW, rv.Bytes())
329                         return
330                 }
331         }
332         if f.seq == seqTypeChan && ti.chandir&uint8(reflect.RecvDir) == 0 {
333                 e.errorf("send-only channel cannot be encoded")
334         }
335         elemsep := e.esep
336         rtelem := ti.elem
337         rtelemIsByte := uint8TypId == rt2id(rtelem) // NOT rtelem.Kind() == reflect.Uint8
338         var l int
339         // if a slice, array or chan of bytes, treat specially
340         if rtelemIsByte {
341                 switch f.seq {
342                 case seqTypeSlice:
343                         ee.EncodeStringBytes(cRAW, rv.Bytes())
344                 case seqTypeArray:
345                         l = rv.Len()
346                         if rv.CanAddr() {
347                                 ee.EncodeStringBytes(cRAW, rv.Slice(0, l).Bytes())
348                         } else {
349                                 var bs []byte
350                                 if l <= cap(e.b) {
351                                         bs = e.b[:l]
352                                 } else {
353                                         bs = make([]byte, l)
354                                 }
355                                 reflect.Copy(reflect.ValueOf(bs), rv)
356                                 ee.EncodeStringBytes(cRAW, bs)
357                         }
358                 case seqTypeChan:
359                         // do not use range, so that the number of elements encoded
360                         // does not change, and encoding does not hang waiting on someone to close chan.
361                         // for b := range rv2i(rv).(<-chan byte) { bs = append(bs, b) }
362                         // ch := rv2i(rv).(<-chan byte) // fix error - that this is a chan byte, not a <-chan byte.
363
364                         if rv.IsNil() {
365                                 ee.EncodeNil()
366                                 break
367                         }
368                         bs := e.b[:0]
369                         irv := rv2i(rv)
370                         ch, ok := irv.(<-chan byte)
371                         if !ok {
372                                 ch = irv.(chan byte)
373                         }
374
375                 L1:
376                         switch timeout := e.h.ChanRecvTimeout; {
377                         case timeout == 0: // only consume available
378                                 for {
379                                         select {
380                                         case b := <-ch:
381                                                 bs = append(bs, b)
382                                         default:
383                                                 break L1
384                                         }
385                                 }
386                         case timeout > 0: // consume until timeout
387                                 tt := time.NewTimer(timeout)
388                                 for {
389                                         select {
390                                         case b := <-ch:
391                                                 bs = append(bs, b)
392                                         case <-tt.C:
393                                                 // close(tt.C)
394                                                 break L1
395                                         }
396                                 }
397                         default: // consume until close
398                                 for b := range ch {
399                                         bs = append(bs, b)
400                                 }
401                         }
402
403                         ee.EncodeStringBytes(cRAW, bs)
404                 }
405                 return
406         }
407
408         // if chan, consume chan into a slice, and work off that slice.
409         var rvcs reflect.Value
410         if f.seq == seqTypeChan {
411                 rvcs = reflect.Zero(reflect.SliceOf(rtelem))
412                 timeout := e.h.ChanRecvTimeout
413                 if timeout < 0 { // consume until close
414                         for {
415                                 recv, recvOk := rv.Recv()
416                                 if !recvOk {
417                                         break
418                                 }
419                                 rvcs = reflect.Append(rvcs, recv)
420                         }
421                 } else {
422                         cases := make([]reflect.SelectCase, 2)
423                         cases[0] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: rv}
424                         if timeout == 0 {
425                                 cases[1] = reflect.SelectCase{Dir: reflect.SelectDefault}
426                         } else {
427                                 tt := time.NewTimer(timeout)
428                                 cases[1] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(tt.C)}
429                         }
430                         for {
431                                 chosen, recv, recvOk := reflect.Select(cases)
432                                 if chosen == 1 || !recvOk {
433                                         break
434                                 }
435                                 rvcs = reflect.Append(rvcs, recv)
436                         }
437                 }
438                 rv = rvcs // TODO: ensure this doesn't mess up anywhere that rv of kind chan is expected
439         }
440
441         l = rv.Len()
442         if ti.mbs {
443                 if l%2 == 1 {
444                         e.errorf("mapBySlice requires even slice length, but got %v", l)
445                         return
446                 }
447                 ee.WriteMapStart(l / 2)
448         } else {
449                 ee.WriteArrayStart(l)
450         }
451
452         if l > 0 {
453                 var fn *codecFn
454                 for rtelem.Kind() == reflect.Ptr {
455                         rtelem = rtelem.Elem()
456                 }
457                 // if kind is reflect.Interface, do not pre-determine the
458                 // encoding type, because preEncodeValue may break it down to
459                 // a concrete type and kInterface will bomb.
460                 if rtelem.Kind() != reflect.Interface {
461                         fn = e.cfer().get(rtelem, true, true)
462                 }
463                 for j := 0; j < l; j++ {
464                         if elemsep {
465                                 if ti.mbs {
466                                         if j%2 == 0 {
467                                                 ee.WriteMapElemKey()
468                                         } else {
469                                                 ee.WriteMapElemValue()
470                                         }
471                                 } else {
472                                         ee.WriteArrayElem()
473                                 }
474                         }
475                         e.encodeValue(rv.Index(j), fn, true)
476                 }
477         }
478
479         if ti.mbs {
480                 ee.WriteMapEnd()
481         } else {
482                 ee.WriteArrayEnd()
483         }
484 }
485
486 func (e *Encoder) kStructNoOmitempty(f *codecFnInfo, rv reflect.Value) {
487         fti := f.ti
488         elemsep := e.esep
489         tisfi := fti.sfiSrc
490         toMap := !(fti.toArray || e.h.StructToArray)
491         if toMap {
492                 tisfi = fti.sfiSort
493         }
494         ee := e.e
495
496         sfn := structFieldNode{v: rv, update: false}
497         if toMap {
498                 ee.WriteMapStart(len(tisfi))
499                 if elemsep {
500                         for _, si := range tisfi {
501                                 ee.WriteMapElemKey()
502                                 // ee.EncodeString(cUTF8, si.encName)
503                                 e.kStructFieldKey(fti.keyType, si)
504                                 ee.WriteMapElemValue()
505                                 e.encodeValue(sfn.field(si), nil, true)
506                         }
507                 } else {
508                         for _, si := range tisfi {
509                                 // ee.EncodeString(cUTF8, si.encName)
510                                 e.kStructFieldKey(fti.keyType, si)
511                                 e.encodeValue(sfn.field(si), nil, true)
512                         }
513                 }
514                 ee.WriteMapEnd()
515         } else {
516                 ee.WriteArrayStart(len(tisfi))
517                 if elemsep {
518                         for _, si := range tisfi {
519                                 ee.WriteArrayElem()
520                                 e.encodeValue(sfn.field(si), nil, true)
521                         }
522                 } else {
523                         for _, si := range tisfi {
524                                 e.encodeValue(sfn.field(si), nil, true)
525                         }
526                 }
527                 ee.WriteArrayEnd()
528         }
529 }
530
531 func (e *Encoder) kStructFieldKey(keyType valueType, s *structFieldInfo) {
532         var m must
533         // use if-else-if, not switch (which compiles to binary-search)
534         // since keyType is typically valueTypeString, branch prediction is pretty good.
535         if keyType == valueTypeString {
536                 if e.js && s.encNameAsciiAlphaNum { // keyType == valueTypeString
537                         e.w.writen1('"')
538                         e.w.writestr(s.encName)
539                         e.w.writen1('"')
540                 } else { // keyType == valueTypeString
541                         e.e.EncodeString(cUTF8, s.encName)
542                 }
543         } else if keyType == valueTypeInt {
544                 e.e.EncodeInt(m.Int(strconv.ParseInt(s.encName, 10, 64)))
545         } else if keyType == valueTypeUint {
546                 e.e.EncodeUint(m.Uint(strconv.ParseUint(s.encName, 10, 64)))
547         } else if keyType == valueTypeFloat {
548                 e.e.EncodeFloat64(m.Float(strconv.ParseFloat(s.encName, 64)))
549         }
550 }
551
552 func (e *Encoder) kStructFieldKeyName(keyType valueType, encName string) {
553         var m must
554         // use if-else-if, not switch (which compiles to binary-search)
555         // since keyType is typically valueTypeString, branch prediction is pretty good.
556         if keyType == valueTypeString {
557                 e.e.EncodeString(cUTF8, encName)
558         } else if keyType == valueTypeInt {
559                 e.e.EncodeInt(m.Int(strconv.ParseInt(encName, 10, 64)))
560         } else if keyType == valueTypeUint {
561                 e.e.EncodeUint(m.Uint(strconv.ParseUint(encName, 10, 64)))
562         } else if keyType == valueTypeFloat {
563                 e.e.EncodeFloat64(m.Float(strconv.ParseFloat(encName, 64)))
564         }
565 }
566
567 func (e *Encoder) kStruct(f *codecFnInfo, rv reflect.Value) {
568         fti := f.ti
569         elemsep := e.esep
570         tisfi := fti.sfiSrc
571         var newlen int
572         toMap := !(fti.toArray || e.h.StructToArray)
573         var mf map[string]interface{}
574         if f.ti.mf {
575                 mf = rv2i(rv).(MissingFielder).CodecMissingFields()
576                 toMap = true
577                 newlen += len(mf)
578         } else if f.ti.mfp {
579                 if rv.CanAddr() {
580                         mf = rv2i(rv.Addr()).(MissingFielder).CodecMissingFields()
581                 } else {
582                         // make a new addressable value of same one, and use it
583                         rv2 := reflect.New(rv.Type())
584                         rv2.Elem().Set(rv)
585                         mf = rv2i(rv2).(MissingFielder).CodecMissingFields()
586                 }
587                 toMap = true
588                 newlen += len(mf)
589         }
590         // if toMap, use the sorted array. If toArray, use unsorted array (to match sequence in struct)
591         if toMap {
592                 tisfi = fti.sfiSort
593         }
594         newlen += len(tisfi)
595         ee := e.e
596
597         // Use sync.Pool to reduce allocating slices unnecessarily.
598         // The cost of sync.Pool is less than the cost of new allocation.
599         //
600         // Each element of the array pools one of encStructPool(8|16|32|64).
601         // It allows the re-use of slices up to 64 in length.
602         // A performance cost of encoding structs was collecting
603         // which values were empty and should be omitted.
604         // We needed slices of reflect.Value and string to collect them.
605         // This shared pool reduces the amount of unnecessary creation we do.
606         // The cost is that of locking sometimes, but sync.Pool is efficient
607         // enough to reduce thread contention.
608
609         var spool *sync.Pool
610         var poolv interface{}
611         var fkvs []sfiRv
612         // fmt.Printf(">>>>>>>>>>>>>> encode.kStruct: newlen: %d\n", newlen)
613         if newlen <= 8 {
614                 spool, poolv = pool.sfiRv8()
615                 fkvs = poolv.(*[8]sfiRv)[:newlen]
616         } else if newlen <= 16 {
617                 spool, poolv = pool.sfiRv16()
618                 fkvs = poolv.(*[16]sfiRv)[:newlen]
619         } else if newlen <= 32 {
620                 spool, poolv = pool.sfiRv32()
621                 fkvs = poolv.(*[32]sfiRv)[:newlen]
622         } else if newlen <= 64 {
623                 spool, poolv = pool.sfiRv64()
624                 fkvs = poolv.(*[64]sfiRv)[:newlen]
625         } else if newlen <= 128 {
626                 spool, poolv = pool.sfiRv128()
627                 fkvs = poolv.(*[128]sfiRv)[:newlen]
628         } else {
629                 fkvs = make([]sfiRv, newlen)
630         }
631
632         newlen = 0
633         var kv sfiRv
634         recur := e.h.RecursiveEmptyCheck
635         sfn := structFieldNode{v: rv, update: false}
636         for _, si := range tisfi {
637                 // kv.r = si.field(rv, false)
638                 kv.r = sfn.field(si)
639                 if toMap {
640                         if si.omitEmpty() && isEmptyValue(kv.r, e.h.TypeInfos, recur, recur) {
641                                 continue
642                         }
643                         kv.v = si // si.encName
644                 } else {
645                         // use the zero value.
646                         // if a reference or struct, set to nil (so you do not output too much)
647                         if si.omitEmpty() && isEmptyValue(kv.r, e.h.TypeInfos, recur, recur) {
648                                 switch kv.r.Kind() {
649                                 case reflect.Struct, reflect.Interface, reflect.Ptr, reflect.Array, reflect.Map, reflect.Slice:
650                                         kv.r = reflect.Value{} //encode as nil
651                                 }
652                         }
653                 }
654                 fkvs[newlen] = kv
655                 newlen++
656         }
657
658         var mflen int
659         for k, v := range mf {
660                 if k == "" {
661                         delete(mf, k)
662                         continue
663                 }
664                 if fti.infoFieldOmitempty && isEmptyValue(reflect.ValueOf(v), e.h.TypeInfos, recur, recur) {
665                         delete(mf, k)
666                         continue
667                 }
668                 mflen++
669         }
670
671         if toMap {
672                 ee.WriteMapStart(newlen + mflen)
673                 if elemsep {
674                         for j := 0; j < newlen; j++ {
675                                 kv = fkvs[j]
676                                 ee.WriteMapElemKey()
677                                 // ee.EncodeString(cUTF8, kv.v)
678                                 e.kStructFieldKey(fti.keyType, kv.v)
679                                 ee.WriteMapElemValue()
680                                 e.encodeValue(kv.r, nil, true)
681                         }
682                 } else {
683                         for j := 0; j < newlen; j++ {
684                                 kv = fkvs[j]
685                                 // ee.EncodeString(cUTF8, kv.v)
686                                 e.kStructFieldKey(fti.keyType, kv.v)
687                                 e.encodeValue(kv.r, nil, true)
688                         }
689                 }
690                 // now, add the others
691                 for k, v := range mf {
692                         ee.WriteMapElemKey()
693                         e.kStructFieldKeyName(fti.keyType, k)
694                         ee.WriteMapElemValue()
695                         e.encode(v)
696                 }
697                 ee.WriteMapEnd()
698         } else {
699                 ee.WriteArrayStart(newlen)
700                 if elemsep {
701                         for j := 0; j < newlen; j++ {
702                                 ee.WriteArrayElem()
703                                 e.encodeValue(fkvs[j].r, nil, true)
704                         }
705                 } else {
706                         for j := 0; j < newlen; j++ {
707                                 e.encodeValue(fkvs[j].r, nil, true)
708                         }
709                 }
710                 ee.WriteArrayEnd()
711         }
712
713         // do not use defer. Instead, use explicit pool return at end of function.
714         // defer has a cost we are trying to avoid.
715         // If there is a panic and these slices are not returned, it is ok.
716         if spool != nil {
717                 spool.Put(poolv)
718         }
719 }
720
721 func (e *Encoder) kMap(f *codecFnInfo, rv reflect.Value) {
722         ee := e.e
723         if rv.IsNil() {
724                 ee.EncodeNil()
725                 return
726         }
727
728         l := rv.Len()
729         ee.WriteMapStart(l)
730         elemsep := e.esep
731         if l == 0 {
732                 ee.WriteMapEnd()
733                 return
734         }
735         // var asSymbols bool
736         // determine the underlying key and val encFn's for the map.
737         // This eliminates some work which is done for each loop iteration i.e.
738         // rv.Type(), ref.ValueOf(rt).Pointer(), then check map/list for fn.
739         //
740         // However, if kind is reflect.Interface, do not pre-determine the
741         // encoding type, because preEncodeValue may break it down to
742         // a concrete type and kInterface will bomb.
743         var keyFn, valFn *codecFn
744         ti := f.ti
745         rtkey0 := ti.key
746         rtkey := rtkey0
747         rtval0 := ti.elem
748         rtval := rtval0
749         // rtkeyid := rt2id(rtkey0)
750         for rtval.Kind() == reflect.Ptr {
751                 rtval = rtval.Elem()
752         }
753         if rtval.Kind() != reflect.Interface {
754                 valFn = e.cfer().get(rtval, true, true)
755         }
756         mks := rv.MapKeys()
757
758         if e.h.Canonical {
759                 e.kMapCanonical(rtkey, rv, mks, valFn)
760                 ee.WriteMapEnd()
761                 return
762         }
763
764         var keyTypeIsString = stringTypId == rt2id(rtkey0) // rtkeyid
765         if !keyTypeIsString {
766                 for rtkey.Kind() == reflect.Ptr {
767                         rtkey = rtkey.Elem()
768                 }
769                 if rtkey.Kind() != reflect.Interface {
770                         // rtkeyid = rt2id(rtkey)
771                         keyFn = e.cfer().get(rtkey, true, true)
772                 }
773         }
774
775         // for j, lmks := 0, len(mks); j < lmks; j++ {
776         for j := range mks {
777                 if elemsep {
778                         ee.WriteMapElemKey()
779                 }
780                 if keyTypeIsString {
781                         ee.EncodeString(cUTF8, mks[j].String())
782                 } else {
783                         e.encodeValue(mks[j], keyFn, true)
784                 }
785                 if elemsep {
786                         ee.WriteMapElemValue()
787                 }
788                 e.encodeValue(rv.MapIndex(mks[j]), valFn, true)
789
790         }
791         ee.WriteMapEnd()
792 }
793
794 func (e *Encoder) kMapCanonical(rtkey reflect.Type, rv reflect.Value, mks []reflect.Value, valFn *codecFn) {
795         ee := e.e
796         elemsep := e.esep
797         // we previously did out-of-band if an extension was registered.
798         // This is not necessary, as the natural kind is sufficient for ordering.
799
800         switch rtkey.Kind() {
801         case reflect.Bool:
802                 mksv := make([]boolRv, len(mks))
803                 for i, k := range mks {
804                         v := &mksv[i]
805                         v.r = k
806                         v.v = k.Bool()
807                 }
808                 sort.Sort(boolRvSlice(mksv))
809                 for i := range mksv {
810                         if elemsep {
811                                 ee.WriteMapElemKey()
812                         }
813                         ee.EncodeBool(mksv[i].v)
814                         if elemsep {
815                                 ee.WriteMapElemValue()
816                         }
817                         e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
818                 }
819         case reflect.String:
820                 mksv := make([]stringRv, len(mks))
821                 for i, k := range mks {
822                         v := &mksv[i]
823                         v.r = k
824                         v.v = k.String()
825                 }
826                 sort.Sort(stringRvSlice(mksv))
827                 for i := range mksv {
828                         if elemsep {
829                                 ee.WriteMapElemKey()
830                         }
831                         ee.EncodeString(cUTF8, mksv[i].v)
832                         if elemsep {
833                                 ee.WriteMapElemValue()
834                         }
835                         e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
836                 }
837         case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr:
838                 mksv := make([]uintRv, len(mks))
839                 for i, k := range mks {
840                         v := &mksv[i]
841                         v.r = k
842                         v.v = k.Uint()
843                 }
844                 sort.Sort(uintRvSlice(mksv))
845                 for i := range mksv {
846                         if elemsep {
847                                 ee.WriteMapElemKey()
848                         }
849                         ee.EncodeUint(mksv[i].v)
850                         if elemsep {
851                                 ee.WriteMapElemValue()
852                         }
853                         e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
854                 }
855         case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
856                 mksv := make([]intRv, len(mks))
857                 for i, k := range mks {
858                         v := &mksv[i]
859                         v.r = k
860                         v.v = k.Int()
861                 }
862                 sort.Sort(intRvSlice(mksv))
863                 for i := range mksv {
864                         if elemsep {
865                                 ee.WriteMapElemKey()
866                         }
867                         ee.EncodeInt(mksv[i].v)
868                         if elemsep {
869                                 ee.WriteMapElemValue()
870                         }
871                         e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
872                 }
873         case reflect.Float32:
874                 mksv := make([]floatRv, len(mks))
875                 for i, k := range mks {
876                         v := &mksv[i]
877                         v.r = k
878                         v.v = k.Float()
879                 }
880                 sort.Sort(floatRvSlice(mksv))
881                 for i := range mksv {
882                         if elemsep {
883                                 ee.WriteMapElemKey()
884                         }
885                         ee.EncodeFloat32(float32(mksv[i].v))
886                         if elemsep {
887                                 ee.WriteMapElemValue()
888                         }
889                         e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
890                 }
891         case reflect.Float64:
892                 mksv := make([]floatRv, len(mks))
893                 for i, k := range mks {
894                         v := &mksv[i]
895                         v.r = k
896                         v.v = k.Float()
897                 }
898                 sort.Sort(floatRvSlice(mksv))
899                 for i := range mksv {
900                         if elemsep {
901                                 ee.WriteMapElemKey()
902                         }
903                         ee.EncodeFloat64(mksv[i].v)
904                         if elemsep {
905                                 ee.WriteMapElemValue()
906                         }
907                         e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
908                 }
909         case reflect.Struct:
910                 if rv.Type() == timeTyp {
911                         mksv := make([]timeRv, len(mks))
912                         for i, k := range mks {
913                                 v := &mksv[i]
914                                 v.r = k
915                                 v.v = rv2i(k).(time.Time)
916                         }
917                         sort.Sort(timeRvSlice(mksv))
918                         for i := range mksv {
919                                 if elemsep {
920                                         ee.WriteMapElemKey()
921                                 }
922                                 ee.EncodeTime(mksv[i].v)
923                                 if elemsep {
924                                         ee.WriteMapElemValue()
925                                 }
926                                 e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
927                         }
928                         break
929                 }
930                 fallthrough
931         default:
932                 // out-of-band
933                 // first encode each key to a []byte first, then sort them, then record
934                 var mksv []byte = make([]byte, 0, len(mks)*16) // temporary byte slice for the encoding
935                 e2 := NewEncoderBytes(&mksv, e.hh)
936                 mksbv := make([]bytesRv, len(mks))
937                 for i, k := range mks {
938                         v := &mksbv[i]
939                         l := len(mksv)
940                         e2.MustEncode(k)
941                         v.r = k
942                         v.v = mksv[l:]
943                 }
944                 sort.Sort(bytesRvSlice(mksbv))
945                 for j := range mksbv {
946                         if elemsep {
947                                 ee.WriteMapElemKey()
948                         }
949                         e.asis(mksbv[j].v)
950                         if elemsep {
951                                 ee.WriteMapElemValue()
952                         }
953                         e.encodeValue(rv.MapIndex(mksbv[j].r), valFn, true)
954                 }
955         }
956 }
957
958 // // --------------------------------------------------
959
960 type encWriterSwitch struct {
961         wi   *ioEncWriter
962         wb   bytesEncAppender
963         wx   bool      // if bytes, wx=true
964         esep bool      // whether it has elem separators
965         isas bool      // whether e.as != nil
966         js   bool      // here, so that no need to piggy back on *codecFner for this
967         be   bool      // here, so that no need to piggy back on *codecFner for this
968         _    [3]byte   // padding
969         _    [2]uint64 // padding
970 }
971
972 /*
973
974 func (z *encWriterSwitch) writeb(s []byte) {
975         if z.wx {
976                 z.wb.writeb(s)
977         } else {
978                 z.wi.writeb(s)
979         }
980 }
981 func (z *encWriterSwitch) writestr(s string) {
982         if z.wx {
983                 z.wb.writestr(s)
984         } else {
985                 z.wi.writestr(s)
986         }
987 }
988 func (z *encWriterSwitch) writen1(b1 byte) {
989         if z.wx {
990                 z.wb.writen1(b1)
991         } else {
992                 z.wi.writen1(b1)
993         }
994 }
995 func (z *encWriterSwitch) writen2(b1, b2 byte) {
996         if z.wx {
997                 z.wb.writen2(b1, b2)
998         } else {
999                 z.wi.writen2(b1, b2)
1000         }
1001 }
1002 func (z *encWriterSwitch) atEndOfEncode() {
1003         if z.wx {
1004                 z.wb.atEndOfEncode()
1005         } else {
1006                 z.wi.atEndOfEncode()
1007         }
1008 }
1009
1010 */
1011
1012 // An Encoder writes an object to an output stream in the codec format.
1013 type Encoder struct {
1014         panicHdl
1015         // hopefully, reduce derefencing cost by laying the encWriter inside the Encoder
1016         e encDriver
1017         // NOTE: Encoder shouldn't call it's write methods,
1018         // as the handler MAY need to do some coordination.
1019         w encWriter
1020
1021         // bw *bufio.Writer
1022         as encDriverAsis
1023
1024         err error
1025
1026         // ---- cpu cache line boundary?
1027         encWriterSwitch
1028
1029         // ---- cpu cache line boundary?
1030         h *BasicHandle
1031         codecFnPooler
1032         ci set
1033
1034         // ---- writable fields during execution --- *try* to keep in sep cache line
1035
1036         // ---- cpu cache line boundary?
1037         // b [scratchByteArrayLen]byte
1038         // _ [cacheLineSize - scratchByteArrayLen]byte // padding
1039         b [cacheLineSize - 0]byte // used for encoding a chan or (non-addressable) array of bytes
1040 }
1041
1042 // NewEncoder returns an Encoder for encoding into an io.Writer.
1043 //
1044 // For efficiency, Users are encouraged to pass in a memory buffered writer
1045 // (eg bufio.Writer, bytes.Buffer).
1046 func NewEncoder(w io.Writer, h Handle) *Encoder {
1047         e := newEncoder(h)
1048         e.Reset(w)
1049         return e
1050 }
1051
1052 // NewEncoderBytes returns an encoder for encoding directly and efficiently
1053 // into a byte slice, using zero-copying to temporary slices.
1054 //
1055 // It will potentially replace the output byte slice pointed to.
1056 // After encoding, the out parameter contains the encoded contents.
1057 func NewEncoderBytes(out *[]byte, h Handle) *Encoder {
1058         e := newEncoder(h)
1059         e.ResetBytes(out)
1060         return e
1061 }
1062
1063 func newEncoder(h Handle) *Encoder {
1064         e := &Encoder{h: h.getBasicHandle(), err: errEncoderNotInitialized}
1065         e.hh = h
1066         e.esep = h.hasElemSeparators()
1067         return e
1068 }
1069
1070 func (e *Encoder) resetCommon() {
1071         // e.w = &e.encWriterSwitch
1072         if e.e == nil || e.hh.recreateEncDriver(e.e) {
1073                 e.e = e.hh.newEncDriver(e)
1074                 e.as, e.isas = e.e.(encDriverAsis)
1075                 // e.cr, _ = e.e.(containerStateRecv)
1076         }
1077         e.be = e.hh.isBinary()
1078         _, e.js = e.hh.(*JsonHandle)
1079         e.e.reset()
1080         e.err = nil
1081 }
1082
1083 // Reset resets the Encoder with a new output stream.
1084 //
1085 // This accommodates using the state of the Encoder,
1086 // where it has "cached" information about sub-engines.
1087 func (e *Encoder) Reset(w io.Writer) {
1088         if w == nil {
1089                 return
1090         }
1091         if e.wi == nil {
1092                 e.wi = new(ioEncWriter)
1093         }
1094         var ok bool
1095         e.wx = false
1096         e.wi.w = w
1097         if e.h.WriterBufferSize > 0 {
1098                 bw := bufio.NewWriterSize(w, e.h.WriterBufferSize)
1099                 e.wi.bw = bw
1100                 e.wi.sw = bw
1101                 e.wi.fw = bw
1102                 e.wi.ww = bw
1103         } else {
1104                 if e.wi.bw, ok = w.(io.ByteWriter); !ok {
1105                         e.wi.bw = e.wi
1106                 }
1107                 if e.wi.sw, ok = w.(ioEncStringWriter); !ok {
1108                         e.wi.sw = e.wi
1109                 }
1110                 e.wi.fw, _ = w.(ioFlusher)
1111                 e.wi.ww = w
1112         }
1113         e.w = e.wi
1114         e.resetCommon()
1115 }
1116
1117 // ResetBytes resets the Encoder with a new destination output []byte.
1118 func (e *Encoder) ResetBytes(out *[]byte) {
1119         if out == nil {
1120                 return
1121         }
1122         var in []byte
1123         if out != nil {
1124                 in = *out
1125         }
1126         if in == nil {
1127                 in = make([]byte, defEncByteBufSize)
1128         }
1129         e.wx = true
1130         e.wb.reset(in, out)
1131         e.w = &e.wb
1132         e.resetCommon()
1133 }
1134
1135 // Encode writes an object into a stream.
1136 //
1137 // Encoding can be configured via the struct tag for the fields.
1138 // The key (in the struct tags) that we look at is configurable.
1139 //
1140 // By default, we look up the "codec" key in the struct field's tags,
1141 // and fall bak to the "json" key if "codec" is absent.
1142 // That key in struct field's tag value is the key name,
1143 // followed by an optional comma and options.
1144 //
1145 // To set an option on all fields (e.g. omitempty on all fields), you
1146 // can create a field called _struct, and set flags on it. The options
1147 // which can be set on _struct are:
1148 //    - omitempty: so all fields are omitted if empty
1149 //    - toarray: so struct is encoded as an array
1150 //    - int: so struct key names are encoded as signed integers (instead of strings)
1151 //    - uint: so struct key names are encoded as unsigned integers (instead of strings)
1152 //    - float: so struct key names are encoded as floats (instead of strings)
1153 // More details on these below.
1154 //
1155 // Struct values "usually" encode as maps. Each exported struct field is encoded unless:
1156 //    - the field's tag is "-", OR
1157 //    - the field is empty (empty or the zero value) and its tag specifies the "omitempty" option.
1158 //
1159 // When encoding as a map, the first string in the tag (before the comma)
1160 // is the map key string to use when encoding.
1161 // ...
1162 // This key is typically encoded as a string.
1163 // However, there are instances where the encoded stream has mapping keys encoded as numbers.
1164 // For example, some cbor streams have keys as integer codes in the stream, but they should map
1165 // to fields in a structured object. Consequently, a struct is the natural representation in code.
1166 // For these, configure the struct to encode/decode the keys as numbers (instead of string).
1167 // This is done with the int,uint or float option on the _struct field (see above).
1168 //
1169 // However, struct values may encode as arrays. This happens when:
1170 //    - StructToArray Encode option is set, OR
1171 //    - the tag on the _struct field sets the "toarray" option
1172 // Note that omitempty is ignored when encoding struct values as arrays,
1173 // as an entry must be encoded for each field, to maintain its position.
1174 //
1175 // Values with types that implement MapBySlice are encoded as stream maps.
1176 //
1177 // The empty values (for omitempty option) are false, 0, any nil pointer
1178 // or interface value, and any array, slice, map, or string of length zero.
1179 //
1180 // Anonymous fields are encoded inline except:
1181 //    - the struct tag specifies a replacement name (first value)
1182 //    - the field is of an interface type
1183 //
1184 // Examples:
1185 //
1186 //      // NOTE: 'json:' can be used as struct tag key, in place 'codec:' below.
1187 //      type MyStruct struct {
1188 //          _struct bool    `codec:",omitempty"`   //set omitempty for every field
1189 //          Field1 string   `codec:"-"`            //skip this field
1190 //          Field2 int      `codec:"myName"`       //Use key "myName" in encode stream
1191 //          Field3 int32    `codec:",omitempty"`   //use key "Field3". Omit if empty.
1192 //          Field4 bool     `codec:"f4,omitempty"` //use key "f4". Omit if empty.
1193 //          io.Reader                              //use key "Reader".
1194 //          MyStruct        `codec:"my1"           //use key "my1".
1195 //          MyStruct                               //inline it
1196 //          ...
1197 //      }
1198 //
1199 //      type MyStruct struct {
1200 //          _struct bool    `codec:",toarray"`     //encode struct as an array
1201 //      }
1202 //
1203 //      type MyStruct struct {
1204 //          _struct bool    `codec:",uint"`        //encode struct with "unsigned integer" keys
1205 //          Field1 string   `codec:"1"`            //encode Field1 key using: EncodeInt(1)
1206 //          Field2 string   `codec:"2"`            //encode Field2 key using: EncodeInt(2)
1207 //      }
1208 //
1209 // The mode of encoding is based on the type of the value. When a value is seen:
1210 //   - If a Selfer, call its CodecEncodeSelf method
1211 //   - If an extension is registered for it, call that extension function
1212 //   - If implements encoding.(Binary|Text|JSON)Marshaler, call Marshal(Binary|Text|JSON) method
1213 //   - Else encode it based on its reflect.Kind
1214 //
1215 // Note that struct field names and keys in map[string]XXX will be treated as symbols.
1216 // Some formats support symbols (e.g. binc) and will properly encode the string
1217 // only once in the stream, and use a tag to refer to it thereafter.
1218 func (e *Encoder) Encode(v interface{}) (err error) {
1219         defer e.deferred(&err)
1220         e.MustEncode(v)
1221         return
1222 }
1223
1224 // MustEncode is like Encode, but panics if unable to Encode.
1225 // This provides insight to the code location that triggered the error.
1226 func (e *Encoder) MustEncode(v interface{}) {
1227         if e.err != nil {
1228                 panic(e.err)
1229         }
1230         e.encode(v)
1231         e.e.atEndOfEncode()
1232         e.w.atEndOfEncode()
1233         e.alwaysAtEnd()
1234 }
1235
1236 func (e *Encoder) deferred(err1 *error) {
1237         e.alwaysAtEnd()
1238         if recoverPanicToErr {
1239                 if x := recover(); x != nil {
1240                         panicValToErr(e, x, err1)
1241                         panicValToErr(e, x, &e.err)
1242                 }
1243         }
1244 }
1245
1246 // func (e *Encoder) alwaysAtEnd() {
1247 //      e.codecFnPooler.alwaysAtEnd()
1248 // }
1249
1250 func (e *Encoder) encode(iv interface{}) {
1251         if iv == nil || definitelyNil(iv) {
1252                 e.e.EncodeNil()
1253                 return
1254         }
1255         if v, ok := iv.(Selfer); ok {
1256                 v.CodecEncodeSelf(e)
1257                 return
1258         }
1259
1260         // a switch with only concrete types can be optimized.
1261         // consequently, we deal with nil and interfaces outside.
1262
1263         switch v := iv.(type) {
1264         case Raw:
1265                 e.rawBytes(v)
1266         case reflect.Value:
1267                 e.encodeValue(v, nil, true)
1268
1269         case string:
1270                 e.e.EncodeString(cUTF8, v)
1271         case bool:
1272                 e.e.EncodeBool(v)
1273         case int:
1274                 e.e.EncodeInt(int64(v))
1275         case int8:
1276                 e.e.EncodeInt(int64(v))
1277         case int16:
1278                 e.e.EncodeInt(int64(v))
1279         case int32:
1280                 e.e.EncodeInt(int64(v))
1281         case int64:
1282                 e.e.EncodeInt(v)
1283         case uint:
1284                 e.e.EncodeUint(uint64(v))
1285         case uint8:
1286                 e.e.EncodeUint(uint64(v))
1287         case uint16:
1288                 e.e.EncodeUint(uint64(v))
1289         case uint32:
1290                 e.e.EncodeUint(uint64(v))
1291         case uint64:
1292                 e.e.EncodeUint(v)
1293         case uintptr:
1294                 e.e.EncodeUint(uint64(v))
1295         case float32:
1296                 e.e.EncodeFloat32(v)
1297         case float64:
1298                 e.e.EncodeFloat64(v)
1299         case time.Time:
1300                 e.e.EncodeTime(v)
1301         case []uint8:
1302                 e.e.EncodeStringBytes(cRAW, v)
1303
1304         case *Raw:
1305                 e.rawBytes(*v)
1306
1307         case *string:
1308                 e.e.EncodeString(cUTF8, *v)
1309         case *bool:
1310                 e.e.EncodeBool(*v)
1311         case *int:
1312                 e.e.EncodeInt(int64(*v))
1313         case *int8:
1314                 e.e.EncodeInt(int64(*v))
1315         case *int16:
1316                 e.e.EncodeInt(int64(*v))
1317         case *int32:
1318                 e.e.EncodeInt(int64(*v))
1319         case *int64:
1320                 e.e.EncodeInt(*v)
1321         case *uint:
1322                 e.e.EncodeUint(uint64(*v))
1323         case *uint8:
1324                 e.e.EncodeUint(uint64(*v))
1325         case *uint16:
1326                 e.e.EncodeUint(uint64(*v))
1327         case *uint32:
1328                 e.e.EncodeUint(uint64(*v))
1329         case *uint64:
1330                 e.e.EncodeUint(*v)
1331         case *uintptr:
1332                 e.e.EncodeUint(uint64(*v))
1333         case *float32:
1334                 e.e.EncodeFloat32(*v)
1335         case *float64:
1336                 e.e.EncodeFloat64(*v)
1337         case *time.Time:
1338                 e.e.EncodeTime(*v)
1339
1340         case *[]uint8:
1341                 e.e.EncodeStringBytes(cRAW, *v)
1342
1343         default:
1344                 if !fastpathEncodeTypeSwitch(iv, e) {
1345                         // checkfastpath=true (not false), as underlying slice/map type may be fast-path
1346                         e.encodeValue(reflect.ValueOf(iv), nil, true)
1347                 }
1348         }
1349 }
1350
1351 func (e *Encoder) encodeValue(rv reflect.Value, fn *codecFn, checkFastpath bool) {
1352         // if a valid fn is passed, it MUST BE for the dereferenced type of rv
1353         var sptr uintptr
1354         var rvp reflect.Value
1355         var rvpValid bool
1356 TOP:
1357         switch rv.Kind() {
1358         case reflect.Ptr:
1359                 if rv.IsNil() {
1360                         e.e.EncodeNil()
1361                         return
1362                 }
1363                 rvpValid = true
1364                 rvp = rv
1365                 rv = rv.Elem()
1366                 if e.h.CheckCircularRef && rv.Kind() == reflect.Struct {
1367                         // TODO: Movable pointers will be an issue here. Future problem.
1368                         sptr = rv.UnsafeAddr()
1369                         break TOP
1370                 }
1371                 goto TOP
1372         case reflect.Interface:
1373                 if rv.IsNil() {
1374                         e.e.EncodeNil()
1375                         return
1376                 }
1377                 rv = rv.Elem()
1378                 goto TOP
1379         case reflect.Slice, reflect.Map:
1380                 if rv.IsNil() {
1381                         e.e.EncodeNil()
1382                         return
1383                 }
1384         case reflect.Invalid, reflect.Func:
1385                 e.e.EncodeNil()
1386                 return
1387         }
1388
1389         if sptr != 0 && (&e.ci).add(sptr) {
1390                 e.errorf("circular reference found: # %d", sptr)
1391         }
1392
1393         if fn == nil {
1394                 rt := rv.Type()
1395                 // always pass checkCodecSelfer=true, in case T or ****T is passed, where *T is a Selfer
1396                 fn = e.cfer().get(rt, checkFastpath, true)
1397         }
1398         if fn.i.addrE {
1399                 if rvpValid {
1400                         fn.fe(e, &fn.i, rvp)
1401                 } else if rv.CanAddr() {
1402                         fn.fe(e, &fn.i, rv.Addr())
1403                 } else {
1404                         rv2 := reflect.New(rv.Type())
1405                         rv2.Elem().Set(rv)
1406                         fn.fe(e, &fn.i, rv2)
1407                 }
1408         } else {
1409                 fn.fe(e, &fn.i, rv)
1410         }
1411         if sptr != 0 {
1412                 (&e.ci).remove(sptr)
1413         }
1414 }
1415
1416 func (e *Encoder) marshal(bs []byte, fnerr error, asis bool, c charEncoding) {
1417         if fnerr != nil {
1418                 panic(fnerr)
1419         }
1420         if bs == nil {
1421                 e.e.EncodeNil()
1422         } else if asis {
1423                 e.asis(bs)
1424         } else {
1425                 e.e.EncodeStringBytes(c, bs)
1426         }
1427 }
1428
1429 func (e *Encoder) asis(v []byte) {
1430         if e.isas {
1431                 e.as.EncodeAsis(v)
1432         } else {
1433                 e.w.writeb(v)
1434         }
1435 }
1436
1437 func (e *Encoder) rawBytes(vv Raw) {
1438         v := []byte(vv)
1439         if !e.h.Raw {
1440                 e.errorf("Raw values cannot be encoded: %v", v)
1441         }
1442         e.asis(v)
1443 }
1444
1445 func (e *Encoder) wrapErr(v interface{}, err *error) {
1446         *err = encodeError{codecError{name: e.hh.Name(), err: v}}
1447 }