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