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