feature_reflect_array.go 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package jsoniter
  2. import (
  3. "fmt"
  4. "io"
  5. "reflect"
  6. "unsafe"
  7. )
  8. func decoderOfArray(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
  9. decoder := decoderOfType(cfg, prefix+"[array]->", typ.Elem())
  10. return &arrayDecoder{typ, typ.Elem(), decoder}
  11. }
  12. func encoderOfArray(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
  13. encoder := encoderOfType(cfg, prefix+"[array]->", typ.Elem())
  14. if typ.Elem().Kind() == reflect.Map {
  15. encoder = &OptionalEncoder{encoder}
  16. }
  17. return &arrayEncoder{typ, typ.Elem(), encoder}
  18. }
  19. type arrayEncoder struct {
  20. arrayType reflect.Type
  21. elemType reflect.Type
  22. elemEncoder ValEncoder
  23. }
  24. func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  25. if encoder.arrayType.Len() == 0 {
  26. stream.WriteEmptyArray()
  27. return
  28. }
  29. stream.WriteArrayStart()
  30. elemPtr := unsafe.Pointer(ptr)
  31. encoder.elemEncoder.Encode(elemPtr, stream)
  32. for i := 1; i < encoder.arrayType.Len(); i++ {
  33. stream.WriteMore()
  34. elemPtr = unsafe.Pointer(uintptr(elemPtr) + encoder.elemType.Size())
  35. encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream)
  36. }
  37. stream.WriteArrayEnd()
  38. if stream.Error != nil && stream.Error != io.EOF {
  39. stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error())
  40. }
  41. }
  42. func (encoder *arrayEncoder) EncodeInterface(val interface{}, stream *Stream) {
  43. // special optimization for interface{}
  44. e := (*emptyInterface)(unsafe.Pointer(&val))
  45. if e.word == nil {
  46. stream.WriteArrayStart()
  47. stream.WriteNil()
  48. stream.WriteArrayEnd()
  49. return
  50. }
  51. elemType := encoder.arrayType.Elem()
  52. if encoder.arrayType.Len() == 1 && (elemType.Kind() == reflect.Ptr || elemType.Kind() == reflect.Map) {
  53. ptr := uintptr(e.word)
  54. e.word = unsafe.Pointer(&ptr)
  55. }
  56. if reflect.TypeOf(val).Kind() == reflect.Ptr {
  57. encoder.Encode(unsafe.Pointer(&e.word), stream)
  58. } else {
  59. encoder.Encode(e.word, stream)
  60. }
  61. }
  62. func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  63. return false
  64. }
  65. type arrayDecoder struct {
  66. arrayType reflect.Type
  67. elemType reflect.Type
  68. elemDecoder ValDecoder
  69. }
  70. func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  71. decoder.doDecode(ptr, iter)
  72. if iter.Error != nil && iter.Error != io.EOF {
  73. iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error())
  74. }
  75. }
  76. func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
  77. offset := uintptr(0)
  78. iter.ReadArrayCB(func(iter *Iterator) bool {
  79. if offset < decoder.arrayType.Size() {
  80. decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(ptr)+offset), iter)
  81. offset += decoder.elemType.Size()
  82. } else {
  83. iter.Skip()
  84. }
  85. return true
  86. })
  87. }