1// Copyright (c) 2012, 2013 Ugorji Nwoke. All rights reserved.
2// Use of this source code is governed by a BSD-style license found in the LICENSE file.
3
4package codec
5
6import (
7	"io"
8	"reflect"
9)
10
11const (
12	// Some tagging information for error messages.
13	msgTagEnc         = "codec.encoder"
14	defEncByteBufSize = 1 << 6 // 4:16, 6:64, 8:256, 10:1024
15	// maxTimeSecs32 = math.MaxInt32 / 60 / 24 / 366
16)
17
18// AsSymbolFlag defines what should be encoded as symbols.
19type AsSymbolFlag uint8
20
21const (
22	// AsSymbolDefault is default.
23	// Currently, this means only encode struct field names as symbols.
24	// The default is subject to change.
25	AsSymbolDefault AsSymbolFlag = iota
26
27	// AsSymbolAll means encode anything which could be a symbol as a symbol.
28	AsSymbolAll = 0xfe
29
30	// AsSymbolNone means do not encode anything as a symbol.
31	AsSymbolNone = 1 << iota
32
33	// AsSymbolMapStringKeys means encode keys in map[string]XXX as symbols.
34	AsSymbolMapStringKeysFlag
35
36	// AsSymbolStructFieldName means encode struct field names as symbols.
37	AsSymbolStructFieldNameFlag
38)
39
40// encWriter abstracting writing to a byte array or to an io.Writer.
41type encWriter interface {
42	writeUint16(uint16)
43	writeUint32(uint32)
44	writeUint64(uint64)
45	writeb([]byte)
46	writestr(string)
47	writen1(byte)
48	writen2(byte, byte)
49	atEndOfEncode()
50}
51
52// encDriver abstracts the actual codec (binc vs msgpack, etc)
53type encDriver interface {
54	isBuiltinType(rt uintptr) bool
55	encodeBuiltin(rt uintptr, v interface{})
56	encodeNil()
57	encodeInt(i int64)
58	encodeUint(i uint64)
59	encodeBool(b bool)
60	encodeFloat32(f float32)
61	encodeFloat64(f float64)
62	encodeExtPreamble(xtag byte, length int)
63	encodeArrayPreamble(length int)
64	encodeMapPreamble(length int)
65	encodeString(c charEncoding, v string)
66	encodeSymbol(v string)
67	encodeStringBytes(c charEncoding, v []byte)
68	//TODO
69	//encBignum(f *big.Int)
70	//encStringRunes(c charEncoding, v []rune)
71}
72
73type ioEncWriterWriter interface {
74	WriteByte(c byte) error
75	WriteString(s string) (n int, err error)
76	Write(p []byte) (n int, err error)
77}
78
79type ioEncStringWriter interface {
80	WriteString(s string) (n int, err error)
81}
82
83type EncodeOptions struct {
84	// Encode a struct as an array, and not as a map.
85	StructToArray bool
86
87	// AsSymbols defines what should be encoded as symbols.
88	//
89	// Encoding as symbols can reduce the encoded size significantly.
90	//
91	// However, during decoding, each string to be encoded as a symbol must
92	// be checked to see if it has been seen before. Consequently, encoding time
93	// will increase if using symbols, because string comparisons has a clear cost.
94	//
95	// Sample values:
96	//   AsSymbolNone
97	//   AsSymbolAll
98	//   AsSymbolMapStringKeys
99	//   AsSymbolMapStringKeysFlag | AsSymbolStructFieldNameFlag
100	AsSymbols AsSymbolFlag
101}
102
103// ---------------------------------------------
104
105type simpleIoEncWriterWriter struct {
106	w  io.Writer
107	bw io.ByteWriter
108	sw ioEncStringWriter
109}
110
111func (o *simpleIoEncWriterWriter) WriteByte(c byte) (err error) {
112	if o.bw != nil {
113		return o.bw.WriteByte(c)
114	}
115	_, err = o.w.Write([]byte{c})
116	return
117}
118
119func (o *simpleIoEncWriterWriter) WriteString(s string) (n int, err error) {
120	if o.sw != nil {
121		return o.sw.WriteString(s)
122	}
123	return o.w.Write([]byte(s))
124}
125
126func (o *simpleIoEncWriterWriter) Write(p []byte) (n int, err error) {
127	return o.w.Write(p)
128}
129
130// ----------------------------------------
131
132// ioEncWriter implements encWriter and can write to an io.Writer implementation
133type ioEncWriter struct {
134	w ioEncWriterWriter
135	x [8]byte // temp byte array re-used internally for efficiency
136}
137
138func (z *ioEncWriter) writeUint16(v uint16) {
139	bigen.PutUint16(z.x[:2], v)
140	z.writeb(z.x[:2])
141}
142
143func (z *ioEncWriter) writeUint32(v uint32) {
144	bigen.PutUint32(z.x[:4], v)
145	z.writeb(z.x[:4])
146}
147
148func (z *ioEncWriter) writeUint64(v uint64) {
149	bigen.PutUint64(z.x[:8], v)
150	z.writeb(z.x[:8])
151}
152
153func (z *ioEncWriter) writeb(bs []byte) {
154	if len(bs) == 0 {
155		return
156	}
157	n, err := z.w.Write(bs)
158	if err != nil {
159		panic(err)
160	}
161	if n != len(bs) {
162		encErr("write: Incorrect num bytes written. Expecting: %v, Wrote: %v", len(bs), n)
163	}
164}
165
166func (z *ioEncWriter) writestr(s string) {
167	n, err := z.w.WriteString(s)
168	if err != nil {
169		panic(err)
170	}
171	if n != len(s) {
172		encErr("write: Incorrect num bytes written. Expecting: %v, Wrote: %v", len(s), n)
173	}
174}
175
176func (z *ioEncWriter) writen1(b byte) {
177	if err := z.w.WriteByte(b); err != nil {
178		panic(err)
179	}
180}
181
182func (z *ioEncWriter) writen2(b1 byte, b2 byte) {
183	z.writen1(b1)
184	z.writen1(b2)
185}
186
187func (z *ioEncWriter) atEndOfEncode() {}
188
189// ----------------------------------------
190
191// bytesEncWriter implements encWriter and can write to an byte slice.
192// It is used by Marshal function.
193type bytesEncWriter struct {
194	b   []byte
195	c   int     // cursor
196	out *[]byte // write out on atEndOfEncode
197}
198
199func (z *bytesEncWriter) writeUint16(v uint16) {
200	c := z.grow(2)
201	z.b[c] = byte(v >> 8)
202	z.b[c+1] = byte(v)
203}
204
205func (z *bytesEncWriter) writeUint32(v uint32) {
206	c := z.grow(4)
207	z.b[c] = byte(v >> 24)
208	z.b[c+1] = byte(v >> 16)
209	z.b[c+2] = byte(v >> 8)
210	z.b[c+3] = byte(v)
211}
212
213func (z *bytesEncWriter) writeUint64(v uint64) {
214	c := z.grow(8)
215	z.b[c] = byte(v >> 56)
216	z.b[c+1] = byte(v >> 48)
217	z.b[c+2] = byte(v >> 40)
218	z.b[c+3] = byte(v >> 32)
219	z.b[c+4] = byte(v >> 24)
220	z.b[c+5] = byte(v >> 16)
221	z.b[c+6] = byte(v >> 8)
222	z.b[c+7] = byte(v)
223}
224
225func (z *bytesEncWriter) writeb(s []byte) {
226	if len(s) == 0 {
227		return
228	}
229	c := z.grow(len(s))
230	copy(z.b[c:], s)
231}
232
233func (z *bytesEncWriter) writestr(s string) {
234	c := z.grow(len(s))
235	copy(z.b[c:], s)
236}
237
238func (z *bytesEncWriter) writen1(b1 byte) {
239	c := z.grow(1)
240	z.b[c] = b1
241}
242
243func (z *bytesEncWriter) writen2(b1 byte, b2 byte) {
244	c := z.grow(2)
245	z.b[c] = b1
246	z.b[c+1] = b2
247}
248
249func (z *bytesEncWriter) atEndOfEncode() {
250	*(z.out) = z.b[:z.c]
251}
252
253func (z *bytesEncWriter) grow(n int) (oldcursor int) {
254	oldcursor = z.c
255	z.c = oldcursor + n
256	if z.c > cap(z.b) {
257		// Tried using appendslice logic: (if cap < 1024, *2, else *1.25).
258		// However, it was too expensive, causing too many iterations of copy.
259		// Using bytes.Buffer model was much better (2*cap + n)
260		bs := make([]byte, 2*cap(z.b)+n)
261		copy(bs, z.b[:oldcursor])
262		z.b = bs
263	} else if z.c > len(z.b) {
264		z.b = z.b[:cap(z.b)]
265	}
266	return
267}
268
269// ---------------------------------------------
270
271type encFnInfo struct {
272	ti    *typeInfo
273	e     *Encoder
274	ee    encDriver
275	xfFn  func(reflect.Value) ([]byte, error)
276	xfTag byte
277}
278
279func (f *encFnInfo) builtin(rv reflect.Value) {
280	f.ee.encodeBuiltin(f.ti.rtid, rv.Interface())
281}
282
283func (f *encFnInfo) rawExt(rv reflect.Value) {
284	f.e.encRawExt(rv.Interface().(RawExt))
285}
286
287func (f *encFnInfo) ext(rv reflect.Value) {
288	bs, fnerr := f.xfFn(rv)
289	if fnerr != nil {
290		panic(fnerr)
291	}
292	if bs == nil {
293		f.ee.encodeNil()
294		return
295	}
296	if f.e.hh.writeExt() {
297		f.ee.encodeExtPreamble(f.xfTag, len(bs))
298		f.e.w.writeb(bs)
299	} else {
300		f.ee.encodeStringBytes(c_RAW, bs)
301	}
302
303}
304
305func (f *encFnInfo) binaryMarshal(rv reflect.Value) {
306	var bm binaryMarshaler
307	if f.ti.mIndir == 0 {
308		bm = rv.Interface().(binaryMarshaler)
309	} else if f.ti.mIndir == -1 {
310		bm = rv.Addr().Interface().(binaryMarshaler)
311	} else {
312		for j, k := int8(0), f.ti.mIndir; j < k; j++ {
313			if rv.IsNil() {
314				f.ee.encodeNil()
315				return
316			}
317			rv = rv.Elem()
318		}
319		bm = rv.Interface().(binaryMarshaler)
320	}
321	// debugf(">>>> binaryMarshaler: %T", rv.Interface())
322	bs, fnerr := bm.MarshalBinary()
323	if fnerr != nil {
324		panic(fnerr)
325	}
326	if bs == nil {
327		f.ee.encodeNil()
328	} else {
329		f.ee.encodeStringBytes(c_RAW, bs)
330	}
331}
332
333func (f *encFnInfo) kBool(rv reflect.Value) {
334	f.ee.encodeBool(rv.Bool())
335}
336
337func (f *encFnInfo) kString(rv reflect.Value) {
338	f.ee.encodeString(c_UTF8, rv.String())
339}
340
341func (f *encFnInfo) kFloat64(rv reflect.Value) {
342	f.ee.encodeFloat64(rv.Float())
343}
344
345func (f *encFnInfo) kFloat32(rv reflect.Value) {
346	f.ee.encodeFloat32(float32(rv.Float()))
347}
348
349func (f *encFnInfo) kInt(rv reflect.Value) {
350	f.ee.encodeInt(rv.Int())
351}
352
353func (f *encFnInfo) kUint(rv reflect.Value) {
354	f.ee.encodeUint(rv.Uint())
355}
356
357func (f *encFnInfo) kInvalid(rv reflect.Value) {
358	f.ee.encodeNil()
359}
360
361func (f *encFnInfo) kErr(rv reflect.Value) {
362	encErr("Unsupported kind: %s, for: %#v", rv.Kind(), rv)
363}
364
365func (f *encFnInfo) kSlice(rv reflect.Value) {
366	if rv.IsNil() {
367		f.ee.encodeNil()
368		return
369	}
370
371	if shortCircuitReflectToFastPath {
372		switch f.ti.rtid {
373		case intfSliceTypId:
374			f.e.encSliceIntf(rv.Interface().([]interface{}))
375			return
376		case strSliceTypId:
377			f.e.encSliceStr(rv.Interface().([]string))
378			return
379		case uint64SliceTypId:
380			f.e.encSliceUint64(rv.Interface().([]uint64))
381			return
382		case int64SliceTypId:
383			f.e.encSliceInt64(rv.Interface().([]int64))
384			return
385		}
386	}
387
388	// If in this method, then there was no extension function defined.
389	// So it's okay to treat as []byte.
390	if f.ti.rtid == uint8SliceTypId || f.ti.rt.Elem().Kind() == reflect.Uint8 {
391		f.ee.encodeStringBytes(c_RAW, rv.Bytes())
392		return
393	}
394
395	l := rv.Len()
396	if f.ti.mbs {
397		if l%2 == 1 {
398			encErr("mapBySlice: invalid length (must be divisible by 2): %v", l)
399		}
400		f.ee.encodeMapPreamble(l / 2)
401	} else {
402		f.ee.encodeArrayPreamble(l)
403	}
404	if l == 0 {
405		return
406	}
407	for j := 0; j < l; j++ {
408		// TODO: Consider perf implication of encoding odd index values as symbols if type is string
409		f.e.encodeValue(rv.Index(j))
410	}
411}
412
413func (f *encFnInfo) kArray(rv reflect.Value) {
414	// We cannot share kSlice method, because the array may be non-addressable.
415	// E.g. type struct S{B [2]byte}; Encode(S{}) will bomb on "panic: slice of unaddressable array".
416	// So we have to duplicate the functionality here.
417	// f.e.encodeValue(rv.Slice(0, rv.Len()))
418	// f.kSlice(rv.Slice(0, rv.Len()))
419
420	l := rv.Len()
421	// Handle an array of bytes specially (in line with what is done for slices)
422	if f.ti.rt.Elem().Kind() == reflect.Uint8 {
423		if l == 0 {
424			f.ee.encodeStringBytes(c_RAW, nil)
425			return
426		}
427		var bs []byte
428		if rv.CanAddr() {
429			bs = rv.Slice(0, l).Bytes()
430		} else {
431			bs = make([]byte, l)
432			for i := 0; i < l; i++ {
433				bs[i] = byte(rv.Index(i).Uint())
434			}
435		}
436		f.ee.encodeStringBytes(c_RAW, bs)
437		return
438	}
439
440	if f.ti.mbs {
441		if l%2 == 1 {
442			encErr("mapBySlice: invalid length (must be divisible by 2): %v", l)
443		}
444		f.ee.encodeMapPreamble(l / 2)
445	} else {
446		f.ee.encodeArrayPreamble(l)
447	}
448	if l == 0 {
449		return
450	}
451	for j := 0; j < l; j++ {
452		// TODO: Consider perf implication of encoding odd index values as symbols if type is string
453		f.e.encodeValue(rv.Index(j))
454	}
455}
456
457func (f *encFnInfo) kStruct(rv reflect.Value) {
458	fti := f.ti
459	newlen := len(fti.sfi)
460	rvals := make([]reflect.Value, newlen)
461	var encnames []string
462	e := f.e
463	tisfi := fti.sfip
464	toMap := !(fti.toArray || e.h.StructToArray)
465	// if toMap, use the sorted array. If toArray, use unsorted array (to match sequence in struct)
466	if toMap {
467		tisfi = fti.sfi
468		encnames = make([]string, newlen)
469	}
470	newlen = 0
471	for _, si := range tisfi {
472		if si.i != -1 {
473			rvals[newlen] = rv.Field(int(si.i))
474		} else {
475			rvals[newlen] = rv.FieldByIndex(si.is)
476		}
477		if toMap {
478			if si.omitEmpty && isEmptyValue(rvals[newlen]) {
479				continue
480			}
481			encnames[newlen] = si.encName
482		} else {
483			if si.omitEmpty && isEmptyValue(rvals[newlen]) {
484				rvals[newlen] = reflect.Value{} //encode as nil
485			}
486		}
487		newlen++
488	}
489
490	// debugf(">>>> kStruct: newlen: %v", newlen)
491	if toMap {
492		ee := f.ee //don't dereference everytime
493		ee.encodeMapPreamble(newlen)
494		// asSymbols := e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0
495		asSymbols := e.h.AsSymbols == AsSymbolDefault || e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0
496		for j := 0; j < newlen; j++ {
497			if asSymbols {
498				ee.encodeSymbol(encnames[j])
499			} else {
500				ee.encodeString(c_UTF8, encnames[j])
501			}
502			e.encodeValue(rvals[j])
503		}
504	} else {
505		f.ee.encodeArrayPreamble(newlen)
506		for j := 0; j < newlen; j++ {
507			e.encodeValue(rvals[j])
508		}
509	}
510}
511
512// func (f *encFnInfo) kPtr(rv reflect.Value) {
513// 	debugf(">>>>>>> ??? encode kPtr called - shouldn't get called")
514// 	if rv.IsNil() {
515// 		f.ee.encodeNil()
516// 		return
517// 	}
518// 	f.e.encodeValue(rv.Elem())
519// }
520
521func (f *encFnInfo) kInterface(rv reflect.Value) {
522	if rv.IsNil() {
523		f.ee.encodeNil()
524		return
525	}
526	f.e.encodeValue(rv.Elem())
527}
528
529func (f *encFnInfo) kMap(rv reflect.Value) {
530	if rv.IsNil() {
531		f.ee.encodeNil()
532		return
533	}
534
535	if shortCircuitReflectToFastPath {
536		switch f.ti.rtid {
537		case mapIntfIntfTypId:
538			f.e.encMapIntfIntf(rv.Interface().(map[interface{}]interface{}))
539			return
540		case mapStrIntfTypId:
541			f.e.encMapStrIntf(rv.Interface().(map[string]interface{}))
542			return
543		case mapStrStrTypId:
544			f.e.encMapStrStr(rv.Interface().(map[string]string))
545			return
546		case mapInt64IntfTypId:
547			f.e.encMapInt64Intf(rv.Interface().(map[int64]interface{}))
548			return
549		case mapUint64IntfTypId:
550			f.e.encMapUint64Intf(rv.Interface().(map[uint64]interface{}))
551			return
552		}
553	}
554
555	l := rv.Len()
556	f.ee.encodeMapPreamble(l)
557	if l == 0 {
558		return
559	}
560	// keyTypeIsString := f.ti.rt.Key().Kind() == reflect.String
561	keyTypeIsString := f.ti.rt.Key() == stringTyp
562	var asSymbols bool
563	if keyTypeIsString {
564		asSymbols = f.e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
565	}
566	mks := rv.MapKeys()
567	// for j, lmks := 0, len(mks); j < lmks; j++ {
568	for j := range mks {
569		if keyTypeIsString {
570			if asSymbols {
571				f.ee.encodeSymbol(mks[j].String())
572			} else {
573				f.ee.encodeString(c_UTF8, mks[j].String())
574			}
575		} else {
576			f.e.encodeValue(mks[j])
577		}
578		f.e.encodeValue(rv.MapIndex(mks[j]))
579	}
580
581}
582
583// --------------------------------------------------
584
585// encFn encapsulates the captured variables and the encode function.
586// This way, we only do some calculations one times, and pass to the
587// code block that should be called (encapsulated in a function)
588// instead of executing the checks every time.
589type encFn struct {
590	i *encFnInfo
591	f func(*encFnInfo, reflect.Value)
592}
593
594// --------------------------------------------------
595
596// An Encoder writes an object to an output stream in the codec format.
597type Encoder struct {
598	w  encWriter
599	e  encDriver
600	h  *BasicHandle
601	hh Handle
602	f  map[uintptr]encFn
603	x  []uintptr
604	s  []encFn
605}
606
607// NewEncoder returns an Encoder for encoding into an io.Writer.
608//
609// For efficiency, Users are encouraged to pass in a memory buffered writer
610// (eg bufio.Writer, bytes.Buffer).
611func NewEncoder(w io.Writer, h Handle) *Encoder {
612	ww, ok := w.(ioEncWriterWriter)
613	if !ok {
614		sww := simpleIoEncWriterWriter{w: w}
615		sww.bw, _ = w.(io.ByteWriter)
616		sww.sw, _ = w.(ioEncStringWriter)
617		ww = &sww
618		//ww = bufio.NewWriterSize(w, defEncByteBufSize)
619	}
620	z := ioEncWriter{
621		w: ww,
622	}
623	return &Encoder{w: &z, hh: h, h: h.getBasicHandle(), e: h.newEncDriver(&z)}
624}
625
626// NewEncoderBytes returns an encoder for encoding directly and efficiently
627// into a byte slice, using zero-copying to temporary slices.
628//
629// It will potentially replace the output byte slice pointed to.
630// After encoding, the out parameter contains the encoded contents.
631func NewEncoderBytes(out *[]byte, h Handle) *Encoder {
632	in := *out
633	if in == nil {
634		in = make([]byte, defEncByteBufSize)
635	}
636	z := bytesEncWriter{
637		b:   in,
638		out: out,
639	}
640	return &Encoder{w: &z, hh: h, h: h.getBasicHandle(), e: h.newEncDriver(&z)}
641}
642
643// Encode writes an object into a stream in the codec format.
644//
645// Encoding can be configured via the "codec" struct tag for the fields.
646//
647// The "codec" key in struct field's tag value is the key name,
648// followed by an optional comma and options.
649//
650// To set an option on all fields (e.g. omitempty on all fields), you
651// can create a field called _struct, and set flags on it.
652//
653// Struct values "usually" encode as maps. Each exported struct field is encoded unless:
654//    - the field's codec tag is "-", OR
655//    - the field is empty and its codec tag specifies the "omitempty" option.
656//
657// When encoding as a map, the first string in the tag (before the comma)
658// is the map key string to use when encoding.
659//
660// However, struct values may encode as arrays. This happens when:
661//    - StructToArray Encode option is set, OR
662//    - the codec tag on the _struct field sets the "toarray" option
663//
664// Values with types that implement MapBySlice are encoded as stream maps.
665//
666// The empty values (for omitempty option) are false, 0, any nil pointer
667// or interface value, and any array, slice, map, or string of length zero.
668//
669// Anonymous fields are encoded inline if no struct tag is present.
670// Else they are encoded as regular fields.
671//
672// Examples:
673//
674//      type MyStruct struct {
675//          _struct bool    `codec:",omitempty"`   //set omitempty for every field
676//          Field1 string   `codec:"-"`            //skip this field
677//          Field2 int      `codec:"myName"`       //Use key "myName" in encode stream
678//          Field3 int32    `codec:",omitempty"`   //use key "Field3". Omit if empty.
679//          Field4 bool     `codec:"f4,omitempty"` //use key "f4". Omit if empty.
680//          ...
681//      }
682//
683//      type MyStruct struct {
684//          _struct bool    `codec:",omitempty,toarray"`   //set omitempty for every field
685//                                                         //and encode struct as an array
686//      }
687//
688// The mode of encoding is based on the type of the value. When a value is seen:
689//   - If an extension is registered for it, call that extension function
690//   - If it implements BinaryMarshaler, call its MarshalBinary() (data []byte, err error)
691//   - Else encode it based on its reflect.Kind
692//
693// Note that struct field names and keys in map[string]XXX will be treated as symbols.
694// Some formats support symbols (e.g. binc) and will properly encode the string
695// only once in the stream, and use a tag to refer to it thereafter.
696func (e *Encoder) Encode(v interface{}) (err error) {
697	defer panicToErr(&err)
698	e.encode(v)
699	e.w.atEndOfEncode()
700	return
701}
702
703func (e *Encoder) encode(iv interface{}) {
704	switch v := iv.(type) {
705	case nil:
706		e.e.encodeNil()
707
708	case reflect.Value:
709		e.encodeValue(v)
710
711	case string:
712		e.e.encodeString(c_UTF8, v)
713	case bool:
714		e.e.encodeBool(v)
715	case int:
716		e.e.encodeInt(int64(v))
717	case int8:
718		e.e.encodeInt(int64(v))
719	case int16:
720		e.e.encodeInt(int64(v))
721	case int32:
722		e.e.encodeInt(int64(v))
723	case int64:
724		e.e.encodeInt(v)
725	case uint:
726		e.e.encodeUint(uint64(v))
727	case uint8:
728		e.e.encodeUint(uint64(v))
729	case uint16:
730		e.e.encodeUint(uint64(v))
731	case uint32:
732		e.e.encodeUint(uint64(v))
733	case uint64:
734		e.e.encodeUint(v)
735	case float32:
736		e.e.encodeFloat32(v)
737	case float64:
738		e.e.encodeFloat64(v)
739
740	case []interface{}:
741		e.encSliceIntf(v)
742	case []string:
743		e.encSliceStr(v)
744	case []int64:
745		e.encSliceInt64(v)
746	case []uint64:
747		e.encSliceUint64(v)
748	case []uint8:
749		e.e.encodeStringBytes(c_RAW, v)
750
751	case map[interface{}]interface{}:
752		e.encMapIntfIntf(v)
753	case map[string]interface{}:
754		e.encMapStrIntf(v)
755	case map[string]string:
756		e.encMapStrStr(v)
757	case map[int64]interface{}:
758		e.encMapInt64Intf(v)
759	case map[uint64]interface{}:
760		e.encMapUint64Intf(v)
761
762	case *string:
763		e.e.encodeString(c_UTF8, *v)
764	case *bool:
765		e.e.encodeBool(*v)
766	case *int:
767		e.e.encodeInt(int64(*v))
768	case *int8:
769		e.e.encodeInt(int64(*v))
770	case *int16:
771		e.e.encodeInt(int64(*v))
772	case *int32:
773		e.e.encodeInt(int64(*v))
774	case *int64:
775		e.e.encodeInt(*v)
776	case *uint:
777		e.e.encodeUint(uint64(*v))
778	case *uint8:
779		e.e.encodeUint(uint64(*v))
780	case *uint16:
781		e.e.encodeUint(uint64(*v))
782	case *uint32:
783		e.e.encodeUint(uint64(*v))
784	case *uint64:
785		e.e.encodeUint(*v)
786	case *float32:
787		e.e.encodeFloat32(*v)
788	case *float64:
789		e.e.encodeFloat64(*v)
790
791	case *[]interface{}:
792		e.encSliceIntf(*v)
793	case *[]string:
794		e.encSliceStr(*v)
795	case *[]int64:
796		e.encSliceInt64(*v)
797	case *[]uint64:
798		e.encSliceUint64(*v)
799	case *[]uint8:
800		e.e.encodeStringBytes(c_RAW, *v)
801
802	case *map[interface{}]interface{}:
803		e.encMapIntfIntf(*v)
804	case *map[string]interface{}:
805		e.encMapStrIntf(*v)
806	case *map[string]string:
807		e.encMapStrStr(*v)
808	case *map[int64]interface{}:
809		e.encMapInt64Intf(*v)
810	case *map[uint64]interface{}:
811		e.encMapUint64Intf(*v)
812
813	default:
814		e.encodeValue(reflect.ValueOf(iv))
815	}
816}
817
818func (e *Encoder) encodeValue(rv reflect.Value) {
819	for rv.Kind() == reflect.Ptr {
820		if rv.IsNil() {
821			e.e.encodeNil()
822			return
823		}
824		rv = rv.Elem()
825	}
826
827	rt := rv.Type()
828	rtid := reflect.ValueOf(rt).Pointer()
829
830	// if e.f == nil && e.s == nil { debugf("---->Creating new enc f map for type: %v\n", rt) }
831	var fn encFn
832	var ok bool
833	if useMapForCodecCache {
834		fn, ok = e.f[rtid]
835	} else {
836		for i, v := range e.x {
837			if v == rtid {
838				fn, ok = e.s[i], true
839				break
840			}
841		}
842	}
843	if !ok {
844		// debugf("\tCreating new enc fn for type: %v\n", rt)
845		fi := encFnInfo{ti: getTypeInfo(rtid, rt), e: e, ee: e.e}
846		fn.i = &fi
847		if rtid == rawExtTypId {
848			fn.f = (*encFnInfo).rawExt
849		} else if e.e.isBuiltinType(rtid) {
850			fn.f = (*encFnInfo).builtin
851		} else if xfTag, xfFn := e.h.getEncodeExt(rtid); xfFn != nil {
852			fi.xfTag, fi.xfFn = xfTag, xfFn
853			fn.f = (*encFnInfo).ext
854		} else if supportBinaryMarshal && fi.ti.m {
855			fn.f = (*encFnInfo).binaryMarshal
856		} else {
857			switch rk := rt.Kind(); rk {
858			case reflect.Bool:
859				fn.f = (*encFnInfo).kBool
860			case reflect.String:
861				fn.f = (*encFnInfo).kString
862			case reflect.Float64:
863				fn.f = (*encFnInfo).kFloat64
864			case reflect.Float32:
865				fn.f = (*encFnInfo).kFloat32
866			case reflect.Int, reflect.Int8, reflect.Int64, reflect.Int32, reflect.Int16:
867				fn.f = (*encFnInfo).kInt
868			case reflect.Uint8, reflect.Uint64, reflect.Uint, reflect.Uint32, reflect.Uint16:
869				fn.f = (*encFnInfo).kUint
870			case reflect.Invalid:
871				fn.f = (*encFnInfo).kInvalid
872			case reflect.Slice:
873				fn.f = (*encFnInfo).kSlice
874			case reflect.Array:
875				fn.f = (*encFnInfo).kArray
876			case reflect.Struct:
877				fn.f = (*encFnInfo).kStruct
878			// case reflect.Ptr:
879			// 	fn.f = (*encFnInfo).kPtr
880			case reflect.Interface:
881				fn.f = (*encFnInfo).kInterface
882			case reflect.Map:
883				fn.f = (*encFnInfo).kMap
884			default:
885				fn.f = (*encFnInfo).kErr
886			}
887		}
888		if useMapForCodecCache {
889			if e.f == nil {
890				e.f = make(map[uintptr]encFn, 16)
891			}
892			e.f[rtid] = fn
893		} else {
894			e.s = append(e.s, fn)
895			e.x = append(e.x, rtid)
896		}
897	}
898
899	fn.f(fn.i, rv)
900
901}
902
903func (e *Encoder) encRawExt(re RawExt) {
904	if re.Data == nil {
905		e.e.encodeNil()
906		return
907	}
908	if e.hh.writeExt() {
909		e.e.encodeExtPreamble(re.Tag, len(re.Data))
910		e.w.writeb(re.Data)
911	} else {
912		e.e.encodeStringBytes(c_RAW, re.Data)
913	}
914}
915
916// ---------------------------------------------
917// short circuit functions for common maps and slices
918
919func (e *Encoder) encSliceIntf(v []interface{}) {
920	e.e.encodeArrayPreamble(len(v))
921	for _, v2 := range v {
922		e.encode(v2)
923	}
924}
925
926func (e *Encoder) encSliceStr(v []string) {
927	e.e.encodeArrayPreamble(len(v))
928	for _, v2 := range v {
929		e.e.encodeString(c_UTF8, v2)
930	}
931}
932
933func (e *Encoder) encSliceInt64(v []int64) {
934	e.e.encodeArrayPreamble(len(v))
935	for _, v2 := range v {
936		e.e.encodeInt(v2)
937	}
938}
939
940func (e *Encoder) encSliceUint64(v []uint64) {
941	e.e.encodeArrayPreamble(len(v))
942	for _, v2 := range v {
943		e.e.encodeUint(v2)
944	}
945}
946
947func (e *Encoder) encMapStrStr(v map[string]string) {
948	e.e.encodeMapPreamble(len(v))
949	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
950	for k2, v2 := range v {
951		if asSymbols {
952			e.e.encodeSymbol(k2)
953		} else {
954			e.e.encodeString(c_UTF8, k2)
955		}
956		e.e.encodeString(c_UTF8, v2)
957	}
958}
959
960func (e *Encoder) encMapStrIntf(v map[string]interface{}) {
961	e.e.encodeMapPreamble(len(v))
962	asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
963	for k2, v2 := range v {
964		if asSymbols {
965			e.e.encodeSymbol(k2)
966		} else {
967			e.e.encodeString(c_UTF8, k2)
968		}
969		e.encode(v2)
970	}
971}
972
973func (e *Encoder) encMapInt64Intf(v map[int64]interface{}) {
974	e.e.encodeMapPreamble(len(v))
975	for k2, v2 := range v {
976		e.e.encodeInt(k2)
977		e.encode(v2)
978	}
979}
980
981func (e *Encoder) encMapUint64Intf(v map[uint64]interface{}) {
982	e.e.encodeMapPreamble(len(v))
983	for k2, v2 := range v {
984		e.e.encodeUint(uint64(k2))
985		e.encode(v2)
986	}
987}
988
989func (e *Encoder) encMapIntfIntf(v map[interface{}]interface{}) {
990	e.e.encodeMapPreamble(len(v))
991	for k2, v2 := range v {
992		e.encode(k2)
993		e.encode(v2)
994	}
995}
996
997// ----------------------------------------
998
999func encErr(format string, params ...interface{}) {
1000	doPanic(msgTagEnc, format, params...)
1001}
1002