func.go 3.3 KB

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