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