另客网go项目公用的代码库

reflect_array.go 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package jsoniter
  2. import (
  3. "fmt"
  4. "github.com/modern-go/reflect2"
  5. "io"
  6. "unsafe"
  7. )
  8. func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder {
  9. arrayType := typ.(*reflect2.UnsafeArrayType)
  10. decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
  11. return &arrayDecoder{arrayType, decoder}
  12. }
  13. func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder {
  14. arrayType := typ.(*reflect2.UnsafeArrayType)
  15. if arrayType.Len() == 0 {
  16. return emptyArrayEncoder{}
  17. }
  18. encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
  19. return &arrayEncoder{arrayType, encoder}
  20. }
  21. type emptyArrayEncoder struct{}
  22. func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  23. stream.WriteEmptyArray()
  24. }
  25. func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  26. return true
  27. }
  28. type arrayEncoder struct {
  29. arrayType *reflect2.UnsafeArrayType
  30. elemEncoder ValEncoder
  31. }
  32. func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  33. stream.WriteArrayStart()
  34. elemPtr := unsafe.Pointer(ptr)
  35. encoder.elemEncoder.Encode(elemPtr, stream)
  36. for i := 1; i < encoder.arrayType.Len(); i++ {
  37. stream.WriteMore()
  38. elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i)
  39. encoder.elemEncoder.Encode(elemPtr, stream)
  40. }
  41. stream.WriteArrayEnd()
  42. if stream.Error != nil && stream.Error != io.EOF {
  43. stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error())
  44. }
  45. }
  46. func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  47. return false
  48. }
  49. type arrayDecoder struct {
  50. arrayType *reflect2.UnsafeArrayType
  51. elemDecoder ValDecoder
  52. }
  53. func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  54. decoder.doDecode(ptr, iter)
  55. if iter.Error != nil && iter.Error != io.EOF {
  56. iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error())
  57. }
  58. }
  59. func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
  60. c := iter.nextToken()
  61. arrayType := decoder.arrayType
  62. if c == 'n' {
  63. iter.skipThreeBytes('u', 'l', 'l')
  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. return
  73. }
  74. iter.unreadByte()
  75. elemPtr := arrayType.UnsafeGetIndex(ptr, 0)
  76. decoder.elemDecoder.Decode(elemPtr, iter)
  77. length := 1
  78. for c = iter.nextToken(); c == ','; c = iter.nextToken() {
  79. if length >= arrayType.Len() {
  80. iter.Skip()
  81. continue
  82. }
  83. idx := length
  84. length += 1
  85. elemPtr = arrayType.UnsafeGetIndex(ptr, idx)
  86. decoder.elemDecoder.Decode(elemPtr, iter)
  87. }
  88. if c != ']' {
  89. iter.ReportError("decode array", "expect ], but found "+string([]byte{c}))
  90. return
  91. }
  92. }