reflect_slice.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package jsoniter
  2. import (
  3. "fmt"
  4. "io"
  5. "reflect"
  6. "unsafe"
  7. "github.com/v2pro/plz/reflect2"
  8. )
  9. func decoderOfSlice(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
  10. decoder := decoderOfType(cfg, prefix+"[slice]->", typ.Elem())
  11. sliceType := reflect2.Type2(typ).(*reflect2.UnsafeSliceType)
  12. return &sliceDecoder{sliceType, decoder}
  13. }
  14. func encoderOfSlice(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
  15. encoder := encoderOfType(cfg, prefix+"[slice]->", typ.Elem())
  16. sliceType := reflect2.Type2(typ).(*reflect2.UnsafeSliceType)
  17. return &sliceEncoder{sliceType, encoder}
  18. }
  19. type sliceEncoder struct {
  20. sliceType *reflect2.UnsafeSliceType
  21. elemEncoder ValEncoder
  22. }
  23. func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  24. if encoder.sliceType.UnsafeIsNil(ptr) {
  25. stream.WriteNil()
  26. return
  27. }
  28. length := encoder.sliceType.UnsafeLengthOf(ptr)
  29. if length == 0 {
  30. stream.WriteEmptyArray()
  31. return
  32. }
  33. stream.WriteArrayStart()
  34. encoder.elemEncoder.Encode(encoder.sliceType.UnsafeGetIndex(ptr, 0), stream)
  35. for i := 1; i < length; i++ {
  36. stream.WriteMore()
  37. elemPtr := encoder.sliceType.UnsafeGetIndex(ptr, i)
  38. encoder.elemEncoder.Encode(elemPtr, stream)
  39. }
  40. stream.WriteArrayEnd()
  41. if stream.Error != nil && stream.Error != io.EOF {
  42. stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error())
  43. }
  44. }
  45. func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  46. return encoder.sliceType.UnsafeLengthOf(ptr) == 0
  47. }
  48. type sliceDecoder struct {
  49. sliceType *reflect2.UnsafeSliceType
  50. elemDecoder ValDecoder
  51. }
  52. func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  53. decoder.doDecode(ptr, iter)
  54. if iter.Error != nil && iter.Error != io.EOF {
  55. iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error())
  56. }
  57. }
  58. func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
  59. c := iter.nextToken()
  60. sliceType := decoder.sliceType
  61. if c == 'n' {
  62. iter.skipThreeBytes('u', 'l', 'l')
  63. sliceType.UnsafeSetNil(ptr)
  64. return
  65. }
  66. if c != '[' {
  67. iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c}))
  68. return
  69. }
  70. c = iter.nextToken()
  71. if c == ']' {
  72. sliceType.Set(ptr, sliceType.UnsafeNew())
  73. return
  74. }
  75. iter.unreadByte()
  76. sliceType.UnsafeGrow(ptr, 1)
  77. elemPtr := sliceType.UnsafeGetIndex(ptr, 0)
  78. decoder.elemDecoder.Decode(elemPtr, iter)
  79. length := 1
  80. for c = iter.nextToken(); c == ','; c = iter.nextToken() {
  81. idx := length
  82. length += 1
  83. sliceType.UnsafeGrow(ptr, length)
  84. elemPtr = sliceType.UnsafeGetIndex(ptr, idx)
  85. decoder.elemDecoder.Decode(elemPtr, iter)
  86. }
  87. if c != ']' {
  88. iter.ReportError("decode array", "expect ], but found "+string([]byte{c}))
  89. return
  90. }
  91. }