array.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package decoder
  2. import (
  3. "unsafe"
  4. "github.com/goccy/go-json/internal/errors"
  5. "github.com/goccy/go-json/internal/runtime"
  6. )
  7. type arrayDecoder struct {
  8. elemType *runtime.Type
  9. size uintptr
  10. valueDecoder Decoder
  11. alen int
  12. structName string
  13. fieldName string
  14. zeroValue unsafe.Pointer
  15. }
  16. func newArrayDecoder(dec Decoder, elemType *runtime.Type, alen int, structName, fieldName string) *arrayDecoder {
  17. zeroValue := *(*unsafe.Pointer)(unsafe_New(elemType))
  18. return &arrayDecoder{
  19. valueDecoder: dec,
  20. elemType: elemType,
  21. size: elemType.Size(),
  22. alen: alen,
  23. structName: structName,
  24. fieldName: fieldName,
  25. zeroValue: zeroValue,
  26. }
  27. }
  28. func (d *arrayDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
  29. depth++
  30. if depth > maxDecodeNestingDepth {
  31. return errors.ErrExceededMaxDepth(s.char(), s.cursor)
  32. }
  33. for {
  34. switch s.char() {
  35. case ' ', '\n', '\t', '\r':
  36. case 'n':
  37. if err := nullBytes(s); err != nil {
  38. return err
  39. }
  40. return nil
  41. case '[':
  42. idx := 0
  43. s.cursor++
  44. if s.skipWhiteSpace() == ']' {
  45. for idx < d.alen {
  46. *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
  47. idx++
  48. }
  49. s.cursor++
  50. return nil
  51. }
  52. for {
  53. if idx < d.alen {
  54. if err := d.valueDecoder.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+uintptr(idx)*d.size)); err != nil {
  55. return err
  56. }
  57. } else {
  58. if err := s.skipValue(depth); err != nil {
  59. return err
  60. }
  61. }
  62. idx++
  63. switch s.skipWhiteSpace() {
  64. case ']':
  65. for idx < d.alen {
  66. *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
  67. idx++
  68. }
  69. s.cursor++
  70. return nil
  71. case ',':
  72. s.cursor++
  73. continue
  74. case nul:
  75. if s.read() {
  76. s.cursor++
  77. continue
  78. }
  79. goto ERROR
  80. default:
  81. goto ERROR
  82. }
  83. }
  84. case nul:
  85. if s.read() {
  86. continue
  87. }
  88. goto ERROR
  89. default:
  90. goto ERROR
  91. }
  92. s.cursor++
  93. }
  94. ERROR:
  95. return errors.ErrUnexpectedEndOfJSON("array", s.totalOffset())
  96. }
  97. func (d *arrayDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
  98. buf := ctx.Buf
  99. depth++
  100. if depth > maxDecodeNestingDepth {
  101. return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
  102. }
  103. for {
  104. switch buf[cursor] {
  105. case ' ', '\n', '\t', '\r':
  106. cursor++
  107. continue
  108. case 'n':
  109. if err := validateNull(buf, cursor); err != nil {
  110. return 0, err
  111. }
  112. cursor += 4
  113. return cursor, nil
  114. case '[':
  115. idx := 0
  116. cursor++
  117. cursor = skipWhiteSpace(buf, cursor)
  118. if buf[cursor] == ']' {
  119. for idx < d.alen {
  120. *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
  121. idx++
  122. }
  123. cursor++
  124. return cursor, nil
  125. }
  126. for {
  127. if idx < d.alen {
  128. c, err := d.valueDecoder.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+uintptr(idx)*d.size))
  129. if err != nil {
  130. return 0, err
  131. }
  132. cursor = c
  133. } else {
  134. c, err := skipValue(buf, cursor, depth)
  135. if err != nil {
  136. return 0, err
  137. }
  138. cursor = c
  139. }
  140. idx++
  141. cursor = skipWhiteSpace(buf, cursor)
  142. switch buf[cursor] {
  143. case ']':
  144. for idx < d.alen {
  145. *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
  146. idx++
  147. }
  148. cursor++
  149. return cursor, nil
  150. case ',':
  151. cursor++
  152. continue
  153. default:
  154. return 0, errors.ErrInvalidCharacter(buf[cursor], "array", cursor)
  155. }
  156. }
  157. default:
  158. return 0, errors.ErrUnexpectedEndOfJSON("array", cursor)
  159. }
  160. }
  161. }