wrapped_string.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package decoder
  2. import (
  3. "fmt"
  4. "reflect"
  5. "unsafe"
  6. "github.com/goccy/go-json/internal/runtime"
  7. )
  8. type wrappedStringDecoder struct {
  9. typ *runtime.Type
  10. dec Decoder
  11. stringDecoder *stringDecoder
  12. structName string
  13. fieldName string
  14. isPtrType bool
  15. }
  16. func newWrappedStringDecoder(typ *runtime.Type, dec Decoder, structName, fieldName string) *wrappedStringDecoder {
  17. return &wrappedStringDecoder{
  18. typ: typ,
  19. dec: dec,
  20. stringDecoder: newStringDecoder(structName, fieldName),
  21. structName: structName,
  22. fieldName: fieldName,
  23. isPtrType: typ.Kind() == reflect.Ptr,
  24. }
  25. }
  26. func (d *wrappedStringDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
  27. bytes, err := d.stringDecoder.decodeStreamByte(s)
  28. if err != nil {
  29. return err
  30. }
  31. if bytes == nil {
  32. if d.isPtrType {
  33. *(*unsafe.Pointer)(p) = nil
  34. }
  35. return nil
  36. }
  37. b := make([]byte, len(bytes)+1)
  38. copy(b, bytes)
  39. if _, err := d.dec.Decode(&RuntimeContext{Buf: b}, 0, depth, p); err != nil {
  40. return err
  41. }
  42. return nil
  43. }
  44. func (d *wrappedStringDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
  45. bytes, c, err := d.stringDecoder.decodeByte(ctx.Buf, cursor)
  46. if err != nil {
  47. return 0, err
  48. }
  49. if bytes == nil {
  50. if d.isPtrType {
  51. *(*unsafe.Pointer)(p) = nil
  52. }
  53. return c, nil
  54. }
  55. bytes = append(bytes, nul)
  56. oldBuf := ctx.Buf
  57. ctx.Buf = bytes
  58. if _, err := d.dec.Decode(ctx, 0, depth, p); err != nil {
  59. return 0, err
  60. }
  61. ctx.Buf = oldBuf
  62. return c, nil
  63. }
  64. func (d *wrappedStringDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
  65. return nil, 0, fmt.Errorf("json: wrapped string decoder does not support decode path")
  66. }