int.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. package decoder
  2. import (
  3. "fmt"
  4. "reflect"
  5. "unsafe"
  6. "github.com/goccy/go-json/internal/errors"
  7. "github.com/goccy/go-json/internal/runtime"
  8. )
  9. type intDecoder struct {
  10. typ *runtime.Type
  11. kind reflect.Kind
  12. op func(unsafe.Pointer, int64)
  13. structName string
  14. fieldName string
  15. }
  16. func newIntDecoder(typ *runtime.Type, structName, fieldName string, op func(unsafe.Pointer, int64)) *intDecoder {
  17. return &intDecoder{
  18. typ: typ,
  19. kind: typ.Kind(),
  20. op: op,
  21. structName: structName,
  22. fieldName: fieldName,
  23. }
  24. }
  25. func (d *intDecoder) typeError(buf []byte, offset int64) *errors.UnmarshalTypeError {
  26. return &errors.UnmarshalTypeError{
  27. Value: fmt.Sprintf("number %s", string(buf)),
  28. Type: runtime.RType2Type(d.typ),
  29. Struct: d.structName,
  30. Field: d.fieldName,
  31. Offset: offset,
  32. }
  33. }
  34. var (
  35. pow10i64 = [...]int64{
  36. 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09,
  37. 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18,
  38. }
  39. pow10i64Len = len(pow10i64)
  40. )
  41. func (d *intDecoder) parseInt(b []byte) (int64, error) {
  42. isNegative := false
  43. if b[0] == '-' {
  44. b = b[1:]
  45. isNegative = true
  46. }
  47. maxDigit := len(b)
  48. if maxDigit > pow10i64Len {
  49. return 0, fmt.Errorf("invalid length of number")
  50. }
  51. sum := int64(0)
  52. for i := 0; i < maxDigit; i++ {
  53. c := int64(b[i]) - 48
  54. digitValue := pow10i64[maxDigit-i-1]
  55. sum += c * digitValue
  56. }
  57. if isNegative {
  58. return -1 * sum, nil
  59. }
  60. return sum, nil
  61. }
  62. var (
  63. numTable = [256]bool{
  64. '0': true,
  65. '1': true,
  66. '2': true,
  67. '3': true,
  68. '4': true,
  69. '5': true,
  70. '6': true,
  71. '7': true,
  72. '8': true,
  73. '9': true,
  74. }
  75. )
  76. var (
  77. numZeroBuf = []byte{'0'}
  78. )
  79. func (d *intDecoder) decodeStreamByte(s *Stream) ([]byte, error) {
  80. for {
  81. switch s.char() {
  82. case ' ', '\n', '\t', '\r':
  83. s.cursor++
  84. continue
  85. case '-':
  86. start := s.cursor
  87. for {
  88. s.cursor++
  89. if numTable[s.char()] {
  90. continue
  91. } else if s.char() == nul {
  92. if s.read() {
  93. s.cursor-- // for retry current character
  94. continue
  95. }
  96. }
  97. break
  98. }
  99. num := s.buf[start:s.cursor]
  100. if len(num) < 2 {
  101. goto ERROR
  102. }
  103. return num, nil
  104. case '0':
  105. s.cursor++
  106. return numZeroBuf, nil
  107. case '1', '2', '3', '4', '5', '6', '7', '8', '9':
  108. start := s.cursor
  109. for {
  110. s.cursor++
  111. if numTable[s.char()] {
  112. continue
  113. } else if s.char() == nul {
  114. if s.read() {
  115. s.cursor-- // for retry current character
  116. continue
  117. }
  118. }
  119. break
  120. }
  121. num := s.buf[start:s.cursor]
  122. return num, nil
  123. case 'n':
  124. if err := nullBytes(s); err != nil {
  125. return nil, err
  126. }
  127. return nil, nil
  128. case nul:
  129. if s.read() {
  130. continue
  131. }
  132. goto ERROR
  133. default:
  134. return nil, d.typeError([]byte{s.char()}, s.totalOffset())
  135. }
  136. }
  137. ERROR:
  138. return nil, errors.ErrUnexpectedEndOfJSON("number(integer)", s.totalOffset())
  139. }
  140. func (d *intDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
  141. b := (*sliceHeader)(unsafe.Pointer(&buf)).data
  142. for {
  143. switch char(b, cursor) {
  144. case ' ', '\n', '\t', '\r':
  145. cursor++
  146. continue
  147. case '0':
  148. cursor++
  149. return numZeroBuf, cursor, nil
  150. case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  151. start := cursor
  152. cursor++
  153. for numTable[char(b, cursor)] {
  154. cursor++
  155. }
  156. num := buf[start:cursor]
  157. return num, cursor, nil
  158. case 'n':
  159. if err := validateNull(buf, cursor); err != nil {
  160. return nil, 0, err
  161. }
  162. cursor += 4
  163. return nil, cursor, nil
  164. default:
  165. return nil, 0, d.typeError([]byte{char(b, cursor)}, cursor)
  166. }
  167. }
  168. }
  169. func (d *intDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
  170. bytes, err := d.decodeStreamByte(s)
  171. if err != nil {
  172. return err
  173. }
  174. if bytes == nil {
  175. return nil
  176. }
  177. i64, err := d.parseInt(bytes)
  178. if err != nil {
  179. return d.typeError(bytes, s.totalOffset())
  180. }
  181. switch d.kind {
  182. case reflect.Int8:
  183. if i64 < -1*(1<<7) || (1<<7) <= i64 {
  184. return d.typeError(bytes, s.totalOffset())
  185. }
  186. case reflect.Int16:
  187. if i64 < -1*(1<<15) || (1<<15) <= i64 {
  188. return d.typeError(bytes, s.totalOffset())
  189. }
  190. case reflect.Int32:
  191. if i64 < -1*(1<<31) || (1<<31) <= i64 {
  192. return d.typeError(bytes, s.totalOffset())
  193. }
  194. }
  195. d.op(p, i64)
  196. s.reset()
  197. return nil
  198. }
  199. func (d *intDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
  200. bytes, c, err := d.decodeByte(ctx.Buf, cursor)
  201. if err != nil {
  202. return 0, err
  203. }
  204. if bytes == nil {
  205. return c, nil
  206. }
  207. cursor = c
  208. i64, err := d.parseInt(bytes)
  209. if err != nil {
  210. return 0, d.typeError(bytes, cursor)
  211. }
  212. switch d.kind {
  213. case reflect.Int8:
  214. if i64 < -1*(1<<7) || (1<<7) <= i64 {
  215. return 0, d.typeError(bytes, cursor)
  216. }
  217. case reflect.Int16:
  218. if i64 < -1*(1<<15) || (1<<15) <= i64 {
  219. return 0, d.typeError(bytes, cursor)
  220. }
  221. case reflect.Int32:
  222. if i64 < -1*(1<<31) || (1<<31) <= i64 {
  223. return 0, d.typeError(bytes, cursor)
  224. }
  225. }
  226. d.op(p, i64)
  227. return cursor, nil
  228. }