number.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package decoder
  2. import (
  3. "encoding/json"
  4. "strconv"
  5. "unsafe"
  6. "github.com/goccy/go-json/internal/errors"
  7. )
  8. type numberDecoder struct {
  9. stringDecoder *stringDecoder
  10. op func(unsafe.Pointer, json.Number)
  11. structName string
  12. fieldName string
  13. }
  14. func newNumberDecoder(structName, fieldName string, op func(unsafe.Pointer, json.Number)) *numberDecoder {
  15. return &numberDecoder{
  16. stringDecoder: newStringDecoder(structName, fieldName),
  17. op: op,
  18. structName: structName,
  19. fieldName: fieldName,
  20. }
  21. }
  22. func (d *numberDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
  23. bytes, err := d.decodeStreamByte(s)
  24. if err != nil {
  25. return err
  26. }
  27. if _, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&bytes)), 64); err != nil {
  28. return errors.ErrSyntax(err.Error(), s.totalOffset())
  29. }
  30. d.op(p, json.Number(string(bytes)))
  31. s.reset()
  32. return nil
  33. }
  34. func (d *numberDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
  35. bytes, c, err := d.decodeByte(ctx.Buf, cursor)
  36. if err != nil {
  37. return 0, err
  38. }
  39. if _, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&bytes)), 64); err != nil {
  40. return 0, errors.ErrSyntax(err.Error(), c)
  41. }
  42. cursor = c
  43. s := *(*string)(unsafe.Pointer(&bytes))
  44. d.op(p, json.Number(s))
  45. return cursor, nil
  46. }
  47. func (d *numberDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
  48. bytes, c, err := d.decodeByte(ctx.Buf, cursor)
  49. if err != nil {
  50. return nil, 0, err
  51. }
  52. if bytes == nil {
  53. return [][]byte{nullbytes}, c, nil
  54. }
  55. return [][]byte{bytes}, c, nil
  56. }
  57. func (d *numberDecoder) decodeStreamByte(s *Stream) ([]byte, error) {
  58. start := s.cursor
  59. for {
  60. switch s.char() {
  61. case ' ', '\n', '\t', '\r':
  62. s.cursor++
  63. continue
  64. case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  65. return floatBytes(s), nil
  66. case 'n':
  67. if err := nullBytes(s); err != nil {
  68. return nil, err
  69. }
  70. return nil, nil
  71. case '"':
  72. return d.stringDecoder.decodeStreamByte(s)
  73. case nul:
  74. if s.read() {
  75. continue
  76. }
  77. goto ERROR
  78. default:
  79. goto ERROR
  80. }
  81. }
  82. ERROR:
  83. if s.cursor == start {
  84. return nil, errors.ErrInvalidBeginningOfValue(s.char(), s.totalOffset())
  85. }
  86. return nil, errors.ErrUnexpectedEndOfJSON("json.Number", s.totalOffset())
  87. }
  88. func (d *numberDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
  89. for {
  90. switch buf[cursor] {
  91. case ' ', '\n', '\t', '\r':
  92. cursor++
  93. continue
  94. case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  95. start := cursor
  96. cursor++
  97. for floatTable[buf[cursor]] {
  98. cursor++
  99. }
  100. num := buf[start:cursor]
  101. return num, cursor, nil
  102. case 'n':
  103. if err := validateNull(buf, cursor); err != nil {
  104. return nil, 0, err
  105. }
  106. cursor += 4
  107. return nil, cursor, nil
  108. case '"':
  109. return d.stringDecoder.decodeByte(buf, cursor)
  110. default:
  111. return nil, 0, errors.ErrUnexpectedEndOfJSON("json.Number", cursor)
  112. }
  113. }
  114. }