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.
19 const defEncByteBufSize = 1 << 6 // 4:16, 6:64, 8:256, 10:1024
21 var errEncoderNotInitialized = errors.New("Encoder not initialized")
23 // encWriter abstracts writing to a byte array or to an io.Writer.
24 type encWriter interface {
32 // encDriver abstracts the actual codec (binc vs msgpack, etc)
33 type encDriver interface {
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)
47 //encBignum(f *big.Int)
48 //encStringRunes(c charEncoding, v []rune)
49 WriteArrayStart(length int)
52 WriteMapStart(length int)
61 type ioEncStringWriter interface {
62 WriteString(s string) (n int, err error)
65 type encDriverAsis interface {
69 type encodeError struct {
73 func (e encodeError) Error() string {
74 return fmt.Sprintf("%s encode error: %v", e.name, e.err)
77 type encDriverNoopContainerWriter struct{}
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() {}
88 type encDriverTrackContainerWriter struct {
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() {}
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)
107 // EncodeOptions captures configuration options during encode.
108 type EncodeOptions struct {
109 // WriterBufferSize is the size of the buffer used when writing.
111 // if > 0, we use a smart buffer internally for performance purposes.
114 // ChanRecvTimeout is the timeout used when selecting from a chan.
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
122 // StructToArray specifies to encode a struct as an array, and not as a map
125 // Canonical representation means that encoding a value will always result in the same
126 // sequence of bytes.
128 // This only affects maps, as the iteration order for maps is random.
130 // The implementation MAY use the natural sort order for the map keys if possible:
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.
141 // CheckCircularRef controls whether we check for circular references
142 // and error fast during an encode.
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).
147 // This is opt-in, as there may be a performance hit to checking circular references.
148 CheckCircularRef bool
150 // RecursiveEmptyCheck controls whether we descend into interfaces, structs and pointers
151 // when checking if a value is empty.
153 // Note that this may make OmitEmpty more expensive, as it incurs a lot more reflect calls.
154 RecursiveEmptyCheck bool
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.
163 // // AsSymbols defines what should be encoded as symbols.
165 // // Encoding as symbols can reduce the encoded size significantly.
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.
174 // // AsSymbolMapStringKeys
175 // // AsSymbolMapStringKeysFlag | AsSymbolStructFieldNameFlag
176 // AsSymbols AsSymbolFlag
179 // ---------------------------------------------
181 // ioEncWriter implements encWriter and can write to an io.Writer implementation
182 type ioEncWriter struct {
191 func (z *ioEncWriter) WriteByte(b byte) (err error) {
193 _, err = z.w.Write(z.b[:1])
197 func (z *ioEncWriter) WriteString(s string) (n int, err error) {
198 return z.w.Write(bytesView(s))
201 func (z *ioEncWriter) writeb(bs []byte) {
202 if _, err := z.ww.Write(bs); err != nil {
207 func (z *ioEncWriter) writestr(s string) {
208 if _, err := z.sw.WriteString(s); err != nil {
213 func (z *ioEncWriter) writen1(b byte) {
214 if err := z.bw.WriteByte(b); err != nil {
219 func (z *ioEncWriter) writen2(b1, b2 byte) {
221 if err = z.bw.WriteByte(b1); err == nil {
222 if err = z.bw.WriteByte(b2); err == nil {
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 {
236 func (z *ioEncWriter) atEndOfEncode() {
238 if err := z.fw.Flush(); err != nil {
244 // ---------------------------------------------
246 // bytesEncAppender implements encWriter and can write to an byte slice.
247 type bytesEncAppender struct {
252 func (z *bytesEncAppender) writeb(s []byte) {
253 z.b = append(z.b, s...)
255 func (z *bytesEncAppender) writestr(s string) {
256 z.b = append(z.b, s...)
258 func (z *bytesEncAppender) writen1(b1 byte) {
259 z.b = append(z.b, b1)
261 func (z *bytesEncAppender) writen2(b1, b2 byte) {
262 z.b = append(z.b, b1, b2)
264 func (z *bytesEncAppender) atEndOfEncode() {
267 func (z *bytesEncAppender) reset(in []byte, out *[]byte) {
272 // ---------------------------------------------
274 func (e *Encoder) rawExt(f *codecFnInfo, rv reflect.Value) {
275 e.e.EncodeRawExt(rv2i(rv).(*RawExt), e)
278 func (e *Encoder) ext(f *codecFnInfo, rv reflect.Value) {
279 e.e.EncodeExt(rv2i(rv), f.xfTag, f.xfFn, e)
282 func (e *Encoder) selferMarshal(f *codecFnInfo, rv reflect.Value) {
283 rv2i(rv).(Selfer).CodecEncodeSelf(e)
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)
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)
296 func (e *Encoder) jsonMarshal(f *codecFnInfo, rv reflect.Value) {
297 bs, fnerr := rv2i(rv).(jsonMarshaler).MarshalJSON()
298 e.marshal(bs, fnerr, true, cUTF8)
301 func (e *Encoder) raw(f *codecFnInfo, rv reflect.Value) {
302 e.rawBytes(rv2i(rv).(Raw))
305 func (e *Encoder) kInvalid(f *codecFnInfo, rv reflect.Value) {
309 func (e *Encoder) kErr(f *codecFnInfo, rv reflect.Value) {
310 e.errorf("unsupported kind %s, for %#v", rv.Kind(), rv)
313 func (e *Encoder) kSlice(f *codecFnInfo, rv reflect.Value) {
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 {
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())
332 if f.seq == seqTypeChan && ti.chandir&uint8(reflect.RecvDir) == 0 {
333 e.errorf("send-only channel cannot be encoded")
337 rtelemIsByte := uint8TypId == rt2id(rtelem) // NOT rtelem.Kind() == reflect.Uint8
339 // if a slice, array or chan of bytes, treat specially
343 ee.EncodeStringBytes(cRAW, rv.Bytes())
347 ee.EncodeStringBytes(cRAW, rv.Slice(0, l).Bytes())
355 reflect.Copy(reflect.ValueOf(bs), rv)
356 ee.EncodeStringBytes(cRAW, bs)
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.
370 ch, ok := irv.(<-chan byte)
376 switch timeout := e.h.ChanRecvTimeout; {
377 case timeout == 0: // only consume available
386 case timeout > 0: // consume until timeout
387 tt := time.NewTimer(timeout)
397 default: // consume until close
403 ee.EncodeStringBytes(cRAW, bs)
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
415 recv, recvOk := rv.Recv()
419 rvcs = reflect.Append(rvcs, recv)
422 cases := make([]reflect.SelectCase, 2)
423 cases[0] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: rv}
425 cases[1] = reflect.SelectCase{Dir: reflect.SelectDefault}
427 tt := time.NewTimer(timeout)
428 cases[1] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(tt.C)}
431 chosen, recv, recvOk := reflect.Select(cases)
432 if chosen == 1 || !recvOk {
435 rvcs = reflect.Append(rvcs, recv)
438 rv = rvcs // TODO: ensure this doesn't mess up anywhere that rv of kind chan is expected
444 e.errorf("mapBySlice requires even slice length, but got %v", l)
447 ee.WriteMapStart(l / 2)
449 ee.WriteArrayStart(l)
454 for rtelem.Kind() == reflect.Ptr {
455 rtelem = rtelem.Elem()
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)
463 for j := 0; j < l; j++ {
469 ee.WriteMapElemValue()
475 e.encodeValue(rv.Index(j), fn, true)
486 func (e *Encoder) kStructNoOmitempty(f *codecFnInfo, rv reflect.Value) {
490 toMap := !(fti.toArray || e.h.StructToArray)
496 sfn := structFieldNode{v: rv, update: false}
498 ee.WriteMapStart(len(tisfi))
500 for _, si := range tisfi {
502 // ee.EncodeString(cUTF8, si.encName)
503 e.kStructFieldKey(fti.keyType, si)
504 ee.WriteMapElemValue()
505 e.encodeValue(sfn.field(si), nil, true)
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)
516 ee.WriteArrayStart(len(tisfi))
518 for _, si := range tisfi {
520 e.encodeValue(sfn.field(si), nil, true)
523 for _, si := range tisfi {
524 e.encodeValue(sfn.field(si), nil, true)
531 func (e *Encoder) kStructFieldKey(keyType valueType, s *structFieldInfo) {
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
538 e.w.writestr(s.encName)
540 } else { // keyType == valueTypeString
541 e.e.EncodeString(cUTF8, s.encName)
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)))
552 func (e *Encoder) kStructFieldKeyName(keyType valueType, encName string) {
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)))
567 func (e *Encoder) kStruct(f *codecFnInfo, rv reflect.Value) {
572 toMap := !(fti.toArray || e.h.StructToArray)
573 var mf map[string]interface{}
575 mf = rv2i(rv).(MissingFielder).CodecMissingFields()
580 mf = rv2i(rv.Addr()).(MissingFielder).CodecMissingFields()
582 // make a new addressable value of same one, and use it
583 rv2 := reflect.New(rv.Type())
585 mf = rv2i(rv2).(MissingFielder).CodecMissingFields()
590 // if toMap, use the sorted array. If toArray, use unsorted array (to match sequence in struct)
597 // Use sync.Pool to reduce allocating slices unnecessarily.
598 // The cost of sync.Pool is less than the cost of new allocation.
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.
610 var poolv interface{}
612 // fmt.Printf(">>>>>>>>>>>>>> encode.kStruct: newlen: %d\n", newlen)
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]
629 fkvs = make([]sfiRv, newlen)
634 recur := e.h.RecursiveEmptyCheck
635 sfn := structFieldNode{v: rv, update: false}
636 for _, si := range tisfi {
637 // kv.r = si.field(rv, false)
640 if si.omitEmpty() && isEmptyValue(kv.r, e.h.TypeInfos, recur, recur) {
643 kv.v = si // si.encName
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) {
649 case reflect.Struct, reflect.Interface, reflect.Ptr, reflect.Array, reflect.Map, reflect.Slice:
650 kv.r = reflect.Value{} //encode as nil
659 for k, v := range mf {
664 if fti.infoFieldOmitempty && isEmptyValue(reflect.ValueOf(v), e.h.TypeInfos, recur, recur) {
672 ee.WriteMapStart(newlen + mflen)
674 for j := 0; j < newlen; j++ {
677 // ee.EncodeString(cUTF8, kv.v)
678 e.kStructFieldKey(fti.keyType, kv.v)
679 ee.WriteMapElemValue()
680 e.encodeValue(kv.r, nil, true)
683 for j := 0; j < newlen; j++ {
685 // ee.EncodeString(cUTF8, kv.v)
686 e.kStructFieldKey(fti.keyType, kv.v)
687 e.encodeValue(kv.r, nil, true)
690 // now, add the others
691 for k, v := range mf {
693 e.kStructFieldKeyName(fti.keyType, k)
694 ee.WriteMapElemValue()
699 ee.WriteArrayStart(newlen)
701 for j := 0; j < newlen; j++ {
703 e.encodeValue(fkvs[j].r, nil, true)
706 for j := 0; j < newlen; j++ {
707 e.encodeValue(fkvs[j].r, nil, true)
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.
721 func (e *Encoder) kMap(f *codecFnInfo, rv reflect.Value) {
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.
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
749 // rtkeyid := rt2id(rtkey0)
750 for rtval.Kind() == reflect.Ptr {
753 if rtval.Kind() != reflect.Interface {
754 valFn = e.cfer().get(rtval, true, true)
759 e.kMapCanonical(rtkey, rv, mks, valFn)
764 var keyTypeIsString = stringTypId == rt2id(rtkey0) // rtkeyid
765 if !keyTypeIsString {
766 for rtkey.Kind() == reflect.Ptr {
769 if rtkey.Kind() != reflect.Interface {
770 // rtkeyid = rt2id(rtkey)
771 keyFn = e.cfer().get(rtkey, true, true)
775 // for j, lmks := 0, len(mks); j < lmks; j++ {
781 ee.EncodeString(cUTF8, mks[j].String())
783 e.encodeValue(mks[j], keyFn, true)
786 ee.WriteMapElemValue()
788 e.encodeValue(rv.MapIndex(mks[j]), valFn, true)
794 func (e *Encoder) kMapCanonical(rtkey reflect.Type, rv reflect.Value, mks []reflect.Value, valFn *codecFn) {
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.
800 switch rtkey.Kind() {
802 mksv := make([]boolRv, len(mks))
803 for i, k := range mks {
808 sort.Sort(boolRvSlice(mksv))
809 for i := range mksv {
813 ee.EncodeBool(mksv[i].v)
815 ee.WriteMapElemValue()
817 e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
820 mksv := make([]stringRv, len(mks))
821 for i, k := range mks {
826 sort.Sort(stringRvSlice(mksv))
827 for i := range mksv {
831 ee.EncodeString(cUTF8, mksv[i].v)
833 ee.WriteMapElemValue()
835 e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
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 {
844 sort.Sort(uintRvSlice(mksv))
845 for i := range mksv {
849 ee.EncodeUint(mksv[i].v)
851 ee.WriteMapElemValue()
853 e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
855 case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
856 mksv := make([]intRv, len(mks))
857 for i, k := range mks {
862 sort.Sort(intRvSlice(mksv))
863 for i := range mksv {
867 ee.EncodeInt(mksv[i].v)
869 ee.WriteMapElemValue()
871 e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
873 case reflect.Float32:
874 mksv := make([]floatRv, len(mks))
875 for i, k := range mks {
880 sort.Sort(floatRvSlice(mksv))
881 for i := range mksv {
885 ee.EncodeFloat32(float32(mksv[i].v))
887 ee.WriteMapElemValue()
889 e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
891 case reflect.Float64:
892 mksv := make([]floatRv, len(mks))
893 for i, k := range mks {
898 sort.Sort(floatRvSlice(mksv))
899 for i := range mksv {
903 ee.EncodeFloat64(mksv[i].v)
905 ee.WriteMapElemValue()
907 e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
910 if rv.Type() == timeTyp {
911 mksv := make([]timeRv, len(mks))
912 for i, k := range mks {
915 v.v = rv2i(k).(time.Time)
917 sort.Sort(timeRvSlice(mksv))
918 for i := range mksv {
922 ee.EncodeTime(mksv[i].v)
924 ee.WriteMapElemValue()
926 e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
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 {
944 sort.Sort(bytesRvSlice(mksbv))
945 for j := range mksbv {
951 ee.WriteMapElemValue()
953 e.encodeValue(rv.MapIndex(mksbv[j].r), valFn, true)
958 // // --------------------------------------------------
960 type encWriterSwitch struct {
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
969 _ [2]uint64 // padding
974 func (z *encWriterSwitch) writeb(s []byte) {
981 func (z *encWriterSwitch) writestr(s string) {
988 func (z *encWriterSwitch) writen1(b1 byte) {
995 func (z *encWriterSwitch) writen2(b1, b2 byte) {
1002 func (z *encWriterSwitch) atEndOfEncode() {
1004 z.wb.atEndOfEncode()
1006 z.wi.atEndOfEncode()
1012 // An Encoder writes an object to an output stream in the codec format.
1013 type Encoder struct {
1015 // hopefully, reduce derefencing cost by laying the encWriter inside the Encoder
1017 // NOTE: Encoder shouldn't call it's write methods,
1018 // as the handler MAY need to do some coordination.
1026 // ---- cpu cache line boundary?
1029 // ---- cpu cache line boundary?
1034 // ---- writable fields during execution --- *try* to keep in sep cache line
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
1042 // NewEncoder returns an Encoder for encoding into an io.Writer.
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 {
1052 // NewEncoderBytes returns an encoder for encoding directly and efficiently
1053 // into a byte slice, using zero-copying to temporary slices.
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 {
1063 func newEncoder(h Handle) *Encoder {
1064 e := &Encoder{h: h.getBasicHandle(), err: errEncoderNotInitialized}
1066 e.esep = h.hasElemSeparators()
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)
1077 e.be = e.hh.isBinary()
1078 _, e.js = e.hh.(*JsonHandle)
1083 // Reset resets the Encoder with a new output stream.
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) {
1092 e.wi = new(ioEncWriter)
1097 if e.h.WriterBufferSize > 0 {
1098 bw := bufio.NewWriterSize(w, e.h.WriterBufferSize)
1104 if e.wi.bw, ok = w.(io.ByteWriter); !ok {
1107 if e.wi.sw, ok = w.(ioEncStringWriter); !ok {
1110 e.wi.fw, _ = w.(ioFlusher)
1117 // ResetBytes resets the Encoder with a new destination output []byte.
1118 func (e *Encoder) ResetBytes(out *[]byte) {
1127 in = make([]byte, defEncByteBufSize)
1135 // Encode writes an object into a stream.
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.
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.
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.
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.
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.
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).
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.
1175 // Values with types that implement MapBySlice are encoded as stream maps.
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.
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
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
1199 // type MyStruct struct {
1200 // _struct bool `codec:",toarray"` //encode struct as an array
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)
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
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)
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{}) {
1236 func (e *Encoder) deferred(err1 *error) {
1238 if recoverPanicToErr {
1239 if x := recover(); x != nil {
1240 panicValToErr(e, x, err1)
1241 panicValToErr(e, x, &e.err)
1246 // func (e *Encoder) alwaysAtEnd() {
1247 // e.codecFnPooler.alwaysAtEnd()
1250 func (e *Encoder) encode(iv interface{}) {
1251 if iv == nil || definitelyNil(iv) {
1255 if v, ok := iv.(Selfer); ok {
1256 v.CodecEncodeSelf(e)
1260 // a switch with only concrete types can be optimized.
1261 // consequently, we deal with nil and interfaces outside.
1263 switch v := iv.(type) {
1267 e.encodeValue(v, nil, true)
1270 e.e.EncodeString(cUTF8, v)
1274 e.e.EncodeInt(int64(v))
1276 e.e.EncodeInt(int64(v))
1278 e.e.EncodeInt(int64(v))
1280 e.e.EncodeInt(int64(v))
1284 e.e.EncodeUint(uint64(v))
1286 e.e.EncodeUint(uint64(v))
1288 e.e.EncodeUint(uint64(v))
1290 e.e.EncodeUint(uint64(v))
1294 e.e.EncodeUint(uint64(v))
1296 e.e.EncodeFloat32(v)
1298 e.e.EncodeFloat64(v)
1302 e.e.EncodeStringBytes(cRAW, v)
1308 e.e.EncodeString(cUTF8, *v)
1312 e.e.EncodeInt(int64(*v))
1314 e.e.EncodeInt(int64(*v))
1316 e.e.EncodeInt(int64(*v))
1318 e.e.EncodeInt(int64(*v))
1322 e.e.EncodeUint(uint64(*v))
1324 e.e.EncodeUint(uint64(*v))
1326 e.e.EncodeUint(uint64(*v))
1328 e.e.EncodeUint(uint64(*v))
1332 e.e.EncodeUint(uint64(*v))
1334 e.e.EncodeFloat32(*v)
1336 e.e.EncodeFloat64(*v)
1341 e.e.EncodeStringBytes(cRAW, *v)
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)
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
1354 var rvp reflect.Value
1366 if e.h.CheckCircularRef && rv.Kind() == reflect.Struct {
1367 // TODO: Movable pointers will be an issue here. Future problem.
1368 sptr = rv.UnsafeAddr()
1372 case reflect.Interface:
1379 case reflect.Slice, reflect.Map:
1384 case reflect.Invalid, reflect.Func:
1389 if sptr != 0 && (&e.ci).add(sptr) {
1390 e.errorf("circular reference found: # %d", sptr)
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)
1400 fn.fe(e, &fn.i, rvp)
1401 } else if rv.CanAddr() {
1402 fn.fe(e, &fn.i, rv.Addr())
1404 rv2 := reflect.New(rv.Type())
1406 fn.fe(e, &fn.i, rv2)
1412 (&e.ci).remove(sptr)
1416 func (e *Encoder) marshal(bs []byte, fnerr error, asis bool, c charEncoding) {
1425 e.e.EncodeStringBytes(c, bs)
1429 func (e *Encoder) asis(v []byte) {
1437 func (e *Encoder) rawBytes(vv Raw) {
1440 e.errorf("Raw values cannot be encoded: %v", v)
1445 func (e *Encoder) wrapErr(v interface{}, err *error) {
1446 *err = encodeError{codecError{name: e.hh.Name(), err: v}}