1package jsoniter 2 3import ( 4 "encoding" 5 "encoding/json" 6 "fmt" 7 "reflect" 8 "time" 9 "unsafe" 10) 11 12// ValDecoder is an internal type registered to cache as needed. 13// Don't confuse jsoniter.ValDecoder with json.Decoder. 14// For json.Decoder's adapter, refer to jsoniter.AdapterDecoder(todo link). 15// 16// Reflection on type to create decoders, which is then cached 17// Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions 18// 1. create instance of new value, for example *int will need a int to be allocated 19// 2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New 20// 3. assignment to map, both key and value will be reflect.Value 21// For a simple struct binding, it will be reflect.Value free and allocation free 22type ValDecoder interface { 23 Decode(ptr unsafe.Pointer, iter *Iterator) 24} 25 26// ValEncoder is an internal type registered to cache as needed. 27// Don't confuse jsoniter.ValEncoder with json.Encoder. 28// For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link). 29type ValEncoder interface { 30 IsEmpty(ptr unsafe.Pointer) bool 31 Encode(ptr unsafe.Pointer, stream *Stream) 32 EncodeInterface(val interface{}, stream *Stream) 33} 34 35type checkIsEmpty interface { 36 IsEmpty(ptr unsafe.Pointer) bool 37} 38 39// WriteToStream the default implementation for TypeEncoder method EncodeInterface 40func WriteToStream(val interface{}, stream *Stream, encoder ValEncoder) { 41 e := (*emptyInterface)(unsafe.Pointer(&val)) 42 if e.word == nil { 43 stream.WriteNil() 44 return 45 } 46 if reflect.TypeOf(val).Kind() == reflect.Ptr { 47 encoder.Encode(unsafe.Pointer(&e.word), stream) 48 } else { 49 encoder.Encode(e.word, stream) 50 } 51} 52 53var jsonNumberType reflect.Type 54var jsoniterNumberType reflect.Type 55var jsonRawMessageType reflect.Type 56var jsoniterRawMessageType reflect.Type 57var anyType reflect.Type 58var marshalerType reflect.Type 59var unmarshalerType reflect.Type 60var textMarshalerType reflect.Type 61var textUnmarshalerType reflect.Type 62 63func init() { 64 jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem() 65 jsoniterNumberType = reflect.TypeOf((*Number)(nil)).Elem() 66 jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem() 67 jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem() 68 anyType = reflect.TypeOf((*Any)(nil)).Elem() 69 marshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem() 70 unmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() 71 textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() 72 textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() 73} 74 75type optionalDecoder struct { 76 valueType reflect.Type 77 valueDecoder ValDecoder 78} 79 80func (decoder *optionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { 81 if iter.ReadNil() { 82 *((*unsafe.Pointer)(ptr)) = nil 83 } else { 84 if *((*unsafe.Pointer)(ptr)) == nil { 85 //pointer to null, we have to allocate memory to hold the value 86 value := reflect.New(decoder.valueType) 87 newPtr := extractInterface(value.Interface()).word 88 decoder.valueDecoder.Decode(newPtr, iter) 89 *((*uintptr)(ptr)) = uintptr(newPtr) 90 } else { 91 //reuse existing instance 92 decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) 93 } 94 } 95} 96 97type deferenceDecoder struct { 98 // only to deference a pointer 99 valueType reflect.Type 100 valueDecoder ValDecoder 101} 102 103func (decoder *deferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { 104 if *((*unsafe.Pointer)(ptr)) == nil { 105 //pointer to null, we have to allocate memory to hold the value 106 value := reflect.New(decoder.valueType) 107 newPtr := extractInterface(value.Interface()).word 108 decoder.valueDecoder.Decode(newPtr, iter) 109 *((*uintptr)(ptr)) = uintptr(newPtr) 110 } else { 111 //reuse existing instance 112 decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) 113 } 114} 115 116type optionalEncoder struct { 117 valueEncoder ValEncoder 118} 119 120func (encoder *optionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { 121 if *((*unsafe.Pointer)(ptr)) == nil { 122 stream.WriteNil() 123 } else { 124 encoder.valueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) 125 } 126} 127 128func (encoder *optionalEncoder) EncodeInterface(val interface{}, stream *Stream) { 129 WriteToStream(val, stream, encoder) 130} 131 132func (encoder *optionalEncoder) IsEmpty(ptr unsafe.Pointer) bool { 133 if *((*unsafe.Pointer)(ptr)) == nil { 134 return true 135 } 136 return false 137} 138 139type placeholderEncoder struct { 140 cfg *frozenConfig 141 cacheKey reflect.Type 142} 143 144func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { 145 encoder.getRealEncoder().Encode(ptr, stream) 146} 147 148func (encoder *placeholderEncoder) EncodeInterface(val interface{}, stream *Stream) { 149 WriteToStream(val, stream, encoder) 150} 151 152func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool { 153 return encoder.getRealEncoder().IsEmpty(ptr) 154} 155 156func (encoder *placeholderEncoder) getRealEncoder() ValEncoder { 157 for i := 0; i < 30; i++ { 158 realDecoder := encoder.cfg.getEncoderFromCache(encoder.cacheKey) 159 _, isPlaceholder := realDecoder.(*placeholderEncoder) 160 if isPlaceholder { 161 time.Sleep(time.Second) 162 } else { 163 return realDecoder 164 } 165 } 166 panic(fmt.Sprintf("real encoder not found for cache key: %v", encoder.cacheKey)) 167} 168 169type placeholderDecoder struct { 170 cfg *frozenConfig 171 cacheKey reflect.Type 172} 173 174func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { 175 for i := 0; i < 30; i++ { 176 realDecoder := decoder.cfg.getDecoderFromCache(decoder.cacheKey) 177 _, isPlaceholder := realDecoder.(*placeholderDecoder) 178 if isPlaceholder { 179 time.Sleep(time.Second) 180 } else { 181 realDecoder.Decode(ptr, iter) 182 return 183 } 184 } 185 panic(fmt.Sprintf("real decoder not found for cache key: %v", decoder.cacheKey)) 186} 187 188// emptyInterface is the header for an interface{} value. 189type emptyInterface struct { 190 typ unsafe.Pointer 191 word unsafe.Pointer 192} 193 194// emptyInterface is the header for an interface with method (not interface{}) 195type nonEmptyInterface struct { 196 // see ../runtime/iface.go:/Itab 197 itab *struct { 198 ityp unsafe.Pointer // static interface type 199 typ unsafe.Pointer // dynamic concrete type 200 link unsafe.Pointer 201 bad int32 202 unused int32 203 fun [100000]unsafe.Pointer // method table 204 } 205 word unsafe.Pointer 206} 207 208// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal 209func (iter *Iterator) ReadVal(obj interface{}) { 210 typ := reflect.TypeOf(obj) 211 cacheKey := typ.Elem() 212 decoder, err := decoderOfType(iter.cfg, cacheKey) 213 if err != nil { 214 iter.Error = err 215 return 216 } 217 e := (*emptyInterface)(unsafe.Pointer(&obj)) 218 decoder.Decode(e.word, iter) 219} 220 221// WriteVal copy the go interface into underlying JSON, same as json.Marshal 222func (stream *Stream) WriteVal(val interface{}) { 223 if nil == val { 224 stream.WriteNil() 225 return 226 } 227 typ := reflect.TypeOf(val) 228 cacheKey := typ 229 encoder, err := encoderOfType(stream.cfg, cacheKey) 230 if err != nil { 231 stream.Error = err 232 return 233 } 234 encoder.EncodeInterface(val, stream) 235} 236 237type prefix string 238 239func (p prefix) addToDecoder(decoder ValDecoder, err error) (ValDecoder, error) { 240 if err != nil { 241 return nil, fmt.Errorf("%s: %s", p, err.Error()) 242 } 243 return decoder, err 244} 245 246func (p prefix) addToEncoder(encoder ValEncoder, err error) (ValEncoder, error) { 247 if err != nil { 248 return nil, fmt.Errorf("%s: %s", p, err.Error()) 249 } 250 return encoder, err 251} 252 253func decoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { 254 cacheKey := typ 255 decoder := cfg.getDecoderFromCache(cacheKey) 256 if decoder != nil { 257 return decoder, nil 258 } 259 decoder = getTypeDecoderFromExtension(typ) 260 if decoder != nil { 261 cfg.addDecoderToCache(cacheKey, decoder) 262 return decoder, nil 263 } 264 decoder = &placeholderDecoder{cfg: cfg, cacheKey: cacheKey} 265 cfg.addDecoderToCache(cacheKey, decoder) 266 decoder, err := createDecoderOfType(cfg, typ) 267 for _, extension := range extensions { 268 decoder = extension.DecorateDecoder(typ, decoder) 269 } 270 cfg.addDecoderToCache(cacheKey, decoder) 271 return decoder, err 272} 273 274func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { 275 typeName := typ.String() 276 if typ == jsonRawMessageType { 277 return &jsonRawMessageCodec{}, nil 278 } 279 if typ == jsoniterRawMessageType { 280 return &jsoniterRawMessageCodec{}, nil 281 } 282 if typ.AssignableTo(jsonNumberType) { 283 return &jsonNumberCodec{}, nil 284 } 285 if typ.AssignableTo(jsoniterNumberType) { 286 return &jsoniterNumberCodec{}, nil 287 } 288 if typ.Implements(unmarshalerType) { 289 templateInterface := reflect.New(typ).Elem().Interface() 290 var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)} 291 if typ.Kind() == reflect.Ptr { 292 decoder = &optionalDecoder{typ.Elem(), decoder} 293 } 294 return decoder, nil 295 } 296 if reflect.PtrTo(typ).Implements(unmarshalerType) { 297 templateInterface := reflect.New(typ).Interface() 298 var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)} 299 return decoder, nil 300 } 301 if typ.Implements(textUnmarshalerType) { 302 templateInterface := reflect.New(typ).Elem().Interface() 303 var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)} 304 if typ.Kind() == reflect.Ptr { 305 decoder = &optionalDecoder{typ.Elem(), decoder} 306 } 307 return decoder, nil 308 } 309 if reflect.PtrTo(typ).Implements(textUnmarshalerType) { 310 templateInterface := reflect.New(typ).Interface() 311 var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)} 312 return decoder, nil 313 } 314 if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 { 315 sliceDecoder, err := prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ)) 316 if err != nil { 317 return nil, err 318 } 319 return &base64Codec{sliceDecoder: sliceDecoder}, nil 320 } 321 if typ.Implements(anyType) { 322 return &anyCodec{}, nil 323 } 324 switch typ.Kind() { 325 case reflect.String: 326 if typeName != "string" { 327 return decoderOfType(cfg, reflect.TypeOf((*string)(nil)).Elem()) 328 } 329 return &stringCodec{}, nil 330 case reflect.Int: 331 if typeName != "int" { 332 return decoderOfType(cfg, reflect.TypeOf((*int)(nil)).Elem()) 333 } 334 return &intCodec{}, nil 335 case reflect.Int8: 336 if typeName != "int8" { 337 return decoderOfType(cfg, reflect.TypeOf((*int8)(nil)).Elem()) 338 } 339 return &int8Codec{}, nil 340 case reflect.Int16: 341 if typeName != "int16" { 342 return decoderOfType(cfg, reflect.TypeOf((*int16)(nil)).Elem()) 343 } 344 return &int16Codec{}, nil 345 case reflect.Int32: 346 if typeName != "int32" { 347 return decoderOfType(cfg, reflect.TypeOf((*int32)(nil)).Elem()) 348 } 349 return &int32Codec{}, nil 350 case reflect.Int64: 351 if typeName != "int64" { 352 return decoderOfType(cfg, reflect.TypeOf((*int64)(nil)).Elem()) 353 } 354 return &int64Codec{}, nil 355 case reflect.Uint: 356 if typeName != "uint" { 357 return decoderOfType(cfg, reflect.TypeOf((*uint)(nil)).Elem()) 358 } 359 return &uintCodec{}, nil 360 case reflect.Uint8: 361 if typeName != "uint8" { 362 return decoderOfType(cfg, reflect.TypeOf((*uint8)(nil)).Elem()) 363 } 364 return &uint8Codec{}, nil 365 case reflect.Uint16: 366 if typeName != "uint16" { 367 return decoderOfType(cfg, reflect.TypeOf((*uint16)(nil)).Elem()) 368 } 369 return &uint16Codec{}, nil 370 case reflect.Uint32: 371 if typeName != "uint32" { 372 return decoderOfType(cfg, reflect.TypeOf((*uint32)(nil)).Elem()) 373 } 374 return &uint32Codec{}, nil 375 case reflect.Uintptr: 376 if typeName != "uintptr" { 377 return decoderOfType(cfg, reflect.TypeOf((*uintptr)(nil)).Elem()) 378 } 379 return &uintptrCodec{}, nil 380 case reflect.Uint64: 381 if typeName != "uint64" { 382 return decoderOfType(cfg, reflect.TypeOf((*uint64)(nil)).Elem()) 383 } 384 return &uint64Codec{}, nil 385 case reflect.Float32: 386 if typeName != "float32" { 387 return decoderOfType(cfg, reflect.TypeOf((*float32)(nil)).Elem()) 388 } 389 return &float32Codec{}, nil 390 case reflect.Float64: 391 if typeName != "float64" { 392 return decoderOfType(cfg, reflect.TypeOf((*float64)(nil)).Elem()) 393 } 394 return &float64Codec{}, nil 395 case reflect.Bool: 396 if typeName != "bool" { 397 return decoderOfType(cfg, reflect.TypeOf((*bool)(nil)).Elem()) 398 } 399 return &boolCodec{}, nil 400 case reflect.Interface: 401 if typ.NumMethod() == 0 { 402 return &emptyInterfaceCodec{}, nil 403 } 404 return &nonEmptyInterfaceCodec{}, nil 405 case reflect.Struct: 406 return prefix(fmt.Sprintf("[%s]", typeName)).addToDecoder(decoderOfStruct(cfg, typ)) 407 case reflect.Array: 408 return prefix("[array]").addToDecoder(decoderOfArray(cfg, typ)) 409 case reflect.Slice: 410 return prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ)) 411 case reflect.Map: 412 return prefix("[map]").addToDecoder(decoderOfMap(cfg, typ)) 413 case reflect.Ptr: 414 return prefix("[optional]").addToDecoder(decoderOfOptional(cfg, typ)) 415 default: 416 return nil, fmt.Errorf("unsupported type: %v", typ) 417 } 418} 419 420func encoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { 421 cacheKey := typ 422 encoder := cfg.getEncoderFromCache(cacheKey) 423 if encoder != nil { 424 return encoder, nil 425 } 426 encoder = getTypeEncoderFromExtension(typ) 427 if encoder != nil { 428 cfg.addEncoderToCache(cacheKey, encoder) 429 return encoder, nil 430 } 431 encoder = &placeholderEncoder{cfg: cfg, cacheKey: cacheKey} 432 cfg.addEncoderToCache(cacheKey, encoder) 433 encoder, err := createEncoderOfType(cfg, typ) 434 for _, extension := range extensions { 435 encoder = extension.DecorateEncoder(typ, encoder) 436 } 437 cfg.addEncoderToCache(cacheKey, encoder) 438 return encoder, err 439} 440 441func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { 442 if typ == jsonRawMessageType { 443 return &jsonRawMessageCodec{}, nil 444 } 445 if typ == jsoniterRawMessageType { 446 return &jsoniterRawMessageCodec{}, nil 447 } 448 if typ.AssignableTo(jsonNumberType) { 449 return &jsonNumberCodec{}, nil 450 } 451 if typ.AssignableTo(jsoniterNumberType) { 452 return &jsoniterNumberCodec{}, nil 453 } 454 if typ.Implements(marshalerType) { 455 checkIsEmpty, err := createCheckIsEmpty(typ) 456 if err != nil { 457 return nil, err 458 } 459 templateInterface := reflect.New(typ).Elem().Interface() 460 var encoder ValEncoder = &marshalerEncoder{ 461 templateInterface: extractInterface(templateInterface), 462 checkIsEmpty: checkIsEmpty, 463 } 464 if typ.Kind() == reflect.Ptr { 465 encoder = &optionalEncoder{encoder} 466 } 467 return encoder, nil 468 } 469 if typ.Implements(textMarshalerType) { 470 checkIsEmpty, err := createCheckIsEmpty(typ) 471 if err != nil { 472 return nil, err 473 } 474 templateInterface := reflect.New(typ).Elem().Interface() 475 var encoder ValEncoder = &textMarshalerEncoder{ 476 templateInterface: extractInterface(templateInterface), 477 checkIsEmpty: checkIsEmpty, 478 } 479 if typ.Kind() == reflect.Ptr { 480 encoder = &optionalEncoder{encoder} 481 } 482 return encoder, nil 483 } 484 if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 { 485 return &base64Codec{}, nil 486 } 487 if typ.Implements(anyType) { 488 return &anyCodec{}, nil 489 } 490 return createEncoderOfSimpleType(cfg, typ) 491} 492 493func createCheckIsEmpty(typ reflect.Type) (checkIsEmpty, error) { 494 kind := typ.Kind() 495 switch kind { 496 case reflect.String: 497 return &stringCodec{}, nil 498 case reflect.Int: 499 return &intCodec{}, nil 500 case reflect.Int8: 501 return &int8Codec{}, nil 502 case reflect.Int16: 503 return &int16Codec{}, nil 504 case reflect.Int32: 505 return &int32Codec{}, nil 506 case reflect.Int64: 507 return &int64Codec{}, nil 508 case reflect.Uint: 509 return &uintCodec{}, nil 510 case reflect.Uint8: 511 return &uint8Codec{}, nil 512 case reflect.Uint16: 513 return &uint16Codec{}, nil 514 case reflect.Uint32: 515 return &uint32Codec{}, nil 516 case reflect.Uintptr: 517 return &uintptrCodec{}, nil 518 case reflect.Uint64: 519 return &uint64Codec{}, nil 520 case reflect.Float32: 521 return &float32Codec{}, nil 522 case reflect.Float64: 523 return &float64Codec{}, nil 524 case reflect.Bool: 525 return &boolCodec{}, nil 526 case reflect.Interface: 527 if typ.NumMethod() == 0 { 528 return &emptyInterfaceCodec{}, nil 529 } 530 return &nonEmptyInterfaceCodec{}, nil 531 case reflect.Struct: 532 return &structEncoder{}, nil 533 case reflect.Array: 534 return &arrayEncoder{}, nil 535 case reflect.Slice: 536 return &sliceEncoder{}, nil 537 case reflect.Map: 538 return &mapEncoder{}, nil 539 case reflect.Ptr: 540 return &optionalEncoder{}, nil 541 default: 542 return nil, fmt.Errorf("unsupported type: %v", typ) 543 } 544} 545 546func createEncoderOfSimpleType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { 547 typeName := typ.String() 548 kind := typ.Kind() 549 switch kind { 550 case reflect.String: 551 if typeName != "string" { 552 return encoderOfType(cfg, reflect.TypeOf((*string)(nil)).Elem()) 553 } 554 return &stringCodec{}, nil 555 case reflect.Int: 556 if typeName != "int" { 557 return encoderOfType(cfg, reflect.TypeOf((*int)(nil)).Elem()) 558 } 559 return &intCodec{}, nil 560 case reflect.Int8: 561 if typeName != "int8" { 562 return encoderOfType(cfg, reflect.TypeOf((*int8)(nil)).Elem()) 563 } 564 return &int8Codec{}, nil 565 case reflect.Int16: 566 if typeName != "int16" { 567 return encoderOfType(cfg, reflect.TypeOf((*int16)(nil)).Elem()) 568 } 569 return &int16Codec{}, nil 570 case reflect.Int32: 571 if typeName != "int32" { 572 return encoderOfType(cfg, reflect.TypeOf((*int32)(nil)).Elem()) 573 } 574 return &int32Codec{}, nil 575 case reflect.Int64: 576 if typeName != "int64" { 577 return encoderOfType(cfg, reflect.TypeOf((*int64)(nil)).Elem()) 578 } 579 return &int64Codec{}, nil 580 case reflect.Uint: 581 if typeName != "uint" { 582 return encoderOfType(cfg, reflect.TypeOf((*uint)(nil)).Elem()) 583 } 584 return &uintCodec{}, nil 585 case reflect.Uint8: 586 if typeName != "uint8" { 587 return encoderOfType(cfg, reflect.TypeOf((*uint8)(nil)).Elem()) 588 } 589 return &uint8Codec{}, nil 590 case reflect.Uint16: 591 if typeName != "uint16" { 592 return encoderOfType(cfg, reflect.TypeOf((*uint16)(nil)).Elem()) 593 } 594 return &uint16Codec{}, nil 595 case reflect.Uint32: 596 if typeName != "uint32" { 597 return encoderOfType(cfg, reflect.TypeOf((*uint32)(nil)).Elem()) 598 } 599 return &uint32Codec{}, nil 600 case reflect.Uintptr: 601 if typeName != "uintptr" { 602 return encoderOfType(cfg, reflect.TypeOf((*uintptr)(nil)).Elem()) 603 } 604 return &uintptrCodec{}, nil 605 case reflect.Uint64: 606 if typeName != "uint64" { 607 return encoderOfType(cfg, reflect.TypeOf((*uint64)(nil)).Elem()) 608 } 609 return &uint64Codec{}, nil 610 case reflect.Float32: 611 if typeName != "float32" { 612 return encoderOfType(cfg, reflect.TypeOf((*float32)(nil)).Elem()) 613 } 614 return &float32Codec{}, nil 615 case reflect.Float64: 616 if typeName != "float64" { 617 return encoderOfType(cfg, reflect.TypeOf((*float64)(nil)).Elem()) 618 } 619 return &float64Codec{}, nil 620 case reflect.Bool: 621 if typeName != "bool" { 622 return encoderOfType(cfg, reflect.TypeOf((*bool)(nil)).Elem()) 623 } 624 return &boolCodec{}, nil 625 case reflect.Interface: 626 if typ.NumMethod() == 0 { 627 return &emptyInterfaceCodec{}, nil 628 } 629 return &nonEmptyInterfaceCodec{}, nil 630 case reflect.Struct: 631 return prefix(fmt.Sprintf("[%s]", typeName)).addToEncoder(encoderOfStruct(cfg, typ)) 632 case reflect.Array: 633 return prefix("[array]").addToEncoder(encoderOfArray(cfg, typ)) 634 case reflect.Slice: 635 return prefix("[slice]").addToEncoder(encoderOfSlice(cfg, typ)) 636 case reflect.Map: 637 return prefix("[map]").addToEncoder(encoderOfMap(cfg, typ)) 638 case reflect.Ptr: 639 return prefix("[optional]").addToEncoder(encoderOfOptional(cfg, typ)) 640 default: 641 return nil, fmt.Errorf("unsupported type: %v", typ) 642 } 643} 644 645func decoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { 646 elemType := typ.Elem() 647 decoder, err := decoderOfType(cfg, elemType) 648 if err != nil { 649 return nil, err 650 } 651 return &optionalDecoder{elemType, decoder}, nil 652} 653 654func encoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { 655 elemType := typ.Elem() 656 elemEncoder, err := encoderOfType(cfg, elemType) 657 if err != nil { 658 return nil, err 659 } 660 encoder := &optionalEncoder{elemEncoder} 661 if elemType.Kind() == reflect.Map { 662 encoder = &optionalEncoder{encoder} 663 } 664 return encoder, nil 665} 666 667func decoderOfMap(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { 668 decoder, err := decoderOfType(cfg, typ.Elem()) 669 if err != nil { 670 return nil, err 671 } 672 mapInterface := reflect.New(typ).Interface() 673 return &mapDecoder{typ, typ.Key(), typ.Elem(), decoder, extractInterface(mapInterface)}, nil 674} 675 676func extractInterface(val interface{}) emptyInterface { 677 return *((*emptyInterface)(unsafe.Pointer(&val))) 678} 679 680func encoderOfMap(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { 681 elemType := typ.Elem() 682 encoder, err := encoderOfType(cfg, elemType) 683 if err != nil { 684 return nil, err 685 } 686 mapInterface := reflect.New(typ).Elem().Interface() 687 if cfg.sortMapKeys { 688 return &sortKeysMapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil 689 } 690 return &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil 691} 692