number.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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) decodeStreamByte(s *Stream) ([]byte, error) {
  48. start := s.cursor
  49. for {
  50. switch s.char() {
  51. case ' ', '\n', '\t', '\r':
  52. s.cursor++
  53. continue
  54. case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  55. return floatBytes(s), nil
  56. case 'n':
  57. if err := nullBytes(s); err != nil {
  58. return nil, err
  59. }
  60. return nil, nil
  61. case '"':
  62. return d.stringDecoder.decodeStreamByte(s)
  63. case nul:
  64. if s.read() {
  65. continue
  66. }
  67. goto ERROR
  68. default:
  69. goto ERROR
  70. }
  71. }
  72. ERROR:
  73. if s.cursor == start {
  74. return nil, errors.ErrInvalidBeginningOfValue(s.char(), s.totalOffset())
  75. }
  76. return nil, errors.ErrUnexpectedEndOfJSON("json.Number", s.totalOffset())
  77. }
  78. func (d *numberDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
  79. for {
  80. switch buf[cursor] {
  81. case ' ', '\n', '\t', '\r':
  82. cursor++
  83. continue
  84. case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  85. start := cursor
  86. cursor++
  87. for floatTable[buf[cursor]] {
  88. cursor++
  89. }
  90. num := buf[start:cursor]
  91. return num, cursor, nil
  92. case 'n':
  93. if err := validateNull(buf, cursor); err != nil {
  94. return nil, 0, err
  95. }
  96. cursor += 4
  97. return nil, cursor, nil
  98. case '"':
  99. return d.stringDecoder.decodeByte(buf, cursor)
  100. default:
  101. return nil, 0, errors.ErrUnexpectedEndOfJSON("json.Number", cursor)
  102. }
  103. }
  104. }