func.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package decoder
  2. import (
  3. "bytes"
  4. "fmt"
  5. "unsafe"
  6. "github.com/goccy/go-json/internal/errors"
  7. "github.com/goccy/go-json/internal/runtime"
  8. )
  9. type funcDecoder struct {
  10. typ *runtime.Type
  11. structName string
  12. fieldName string
  13. }
  14. func newFuncDecoder(typ *runtime.Type, structName, fieldName string) *funcDecoder {
  15. fnDecoder := &funcDecoder{typ, structName, fieldName}
  16. return fnDecoder
  17. }
  18. func (d *funcDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
  19. s.skipWhiteSpace()
  20. start := s.cursor
  21. if err := s.skipValue(depth); err != nil {
  22. return err
  23. }
  24. src := s.buf[start:s.cursor]
  25. if len(src) > 0 {
  26. switch src[0] {
  27. case '"':
  28. return &errors.UnmarshalTypeError{
  29. Value: "string",
  30. Type: runtime.RType2Type(d.typ),
  31. Offset: s.totalOffset(),
  32. }
  33. case '[':
  34. return &errors.UnmarshalTypeError{
  35. Value: "array",
  36. Type: runtime.RType2Type(d.typ),
  37. Offset: s.totalOffset(),
  38. }
  39. case '{':
  40. return &errors.UnmarshalTypeError{
  41. Value: "object",
  42. Type: runtime.RType2Type(d.typ),
  43. Offset: s.totalOffset(),
  44. }
  45. case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  46. return &errors.UnmarshalTypeError{
  47. Value: "number",
  48. Type: runtime.RType2Type(d.typ),
  49. Offset: s.totalOffset(),
  50. }
  51. case 'n':
  52. if err := nullBytes(s); err != nil {
  53. return err
  54. }
  55. *(*unsafe.Pointer)(p) = nil
  56. return nil
  57. case 't':
  58. if err := trueBytes(s); err == nil {
  59. return &errors.UnmarshalTypeError{
  60. Value: "boolean",
  61. Type: runtime.RType2Type(d.typ),
  62. Offset: s.totalOffset(),
  63. }
  64. }
  65. case 'f':
  66. if err := falseBytes(s); err == nil {
  67. return &errors.UnmarshalTypeError{
  68. Value: "boolean",
  69. Type: runtime.RType2Type(d.typ),
  70. Offset: s.totalOffset(),
  71. }
  72. }
  73. }
  74. }
  75. return errors.ErrInvalidBeginningOfValue(s.buf[s.cursor], s.totalOffset())
  76. }
  77. func (d *funcDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
  78. buf := ctx.Buf
  79. cursor = skipWhiteSpace(buf, cursor)
  80. start := cursor
  81. end, err := skipValue(buf, cursor, depth)
  82. if err != nil {
  83. return 0, err
  84. }
  85. src := buf[start:end]
  86. if len(src) > 0 {
  87. switch src[0] {
  88. case '"':
  89. return 0, &errors.UnmarshalTypeError{
  90. Value: "string",
  91. Type: runtime.RType2Type(d.typ),
  92. Offset: start,
  93. }
  94. case '[':
  95. return 0, &errors.UnmarshalTypeError{
  96. Value: "array",
  97. Type: runtime.RType2Type(d.typ),
  98. Offset: start,
  99. }
  100. case '{':
  101. return 0, &errors.UnmarshalTypeError{
  102. Value: "object",
  103. Type: runtime.RType2Type(d.typ),
  104. Offset: start,
  105. }
  106. case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  107. return 0, &errors.UnmarshalTypeError{
  108. Value: "number",
  109. Type: runtime.RType2Type(d.typ),
  110. Offset: start,
  111. }
  112. case 'n':
  113. if bytes.Equal(src, nullbytes) {
  114. *(*unsafe.Pointer)(p) = nil
  115. return end, nil
  116. }
  117. case 't':
  118. if err := validateTrue(buf, start); err == nil {
  119. return 0, &errors.UnmarshalTypeError{
  120. Value: "boolean",
  121. Type: runtime.RType2Type(d.typ),
  122. Offset: start,
  123. }
  124. }
  125. case 'f':
  126. if err := validateFalse(buf, start); err == nil {
  127. return 0, &errors.UnmarshalTypeError{
  128. Value: "boolean",
  129. Type: runtime.RType2Type(d.typ),
  130. Offset: start,
  131. }
  132. }
  133. }
  134. }
  135. return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
  136. }
  137. func (d *funcDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
  138. return nil, 0, fmt.Errorf("json: func decoder does not support decode path")
  139. }