reflect_slice.go 2.6 KB

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