feature_reflect_slice.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. slice := (*sliceHeader)(ptr)
  47. return slice.Len == 0
  48. }
  49. type sliceDecoder struct {
  50. sliceType *reflect2.UnsafeSliceType
  51. elemDecoder ValDecoder
  52. }
  53. // sliceHeader is a safe version of SliceHeader used within this package.
  54. type sliceHeader struct {
  55. Data unsafe.Pointer
  56. Len int
  57. Cap int
  58. }
  59. func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  60. decoder.doDecode(ptr, iter)
  61. if iter.Error != nil && iter.Error != io.EOF {
  62. iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error())
  63. }
  64. }
  65. func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
  66. c := iter.nextToken()
  67. sliceType := decoder.sliceType
  68. if c == 'n' {
  69. iter.skipThreeBytes('u', 'l', 'l')
  70. sliceType.UnsafeSetNil(ptr)
  71. return
  72. }
  73. if c != '[' {
  74. iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c}))
  75. return
  76. }
  77. c = iter.nextToken()
  78. if c == ']' {
  79. sliceType.Set(ptr, sliceType.UnsafeNew())
  80. return
  81. }
  82. iter.unreadByte()
  83. sliceType.UnsafeGrow(ptr, 1)
  84. elemPtr := sliceType.UnsafeGetIndex(ptr, 0)
  85. decoder.elemDecoder.Decode(elemPtr, iter)
  86. length := 1
  87. for c = iter.nextToken(); c == ','; c = iter.nextToken() {
  88. idx := length
  89. length += 1
  90. sliceType.UnsafeGrow(ptr, length)
  91. elemPtr = sliceType.UnsafeGetIndex(ptr, idx)
  92. decoder.elemDecoder.Decode(elemPtr, iter)
  93. }
  94. if c != ']' {
  95. iter.ReportError("decode array", "expect ], but found "+string([]byte{c}))
  96. return
  97. }
  98. }