bytes.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package decoder
  2. import (
  3. "encoding/base64"
  4. "fmt"
  5. "unsafe"
  6. "github.com/goccy/go-json/internal/errors"
  7. "github.com/goccy/go-json/internal/runtime"
  8. )
  9. type bytesDecoder struct {
  10. typ *runtime.Type
  11. sliceDecoder Decoder
  12. stringDecoder *stringDecoder
  13. structName string
  14. fieldName string
  15. }
  16. func byteUnmarshalerSliceDecoder(typ *runtime.Type, structName string, fieldName string) Decoder {
  17. var unmarshalDecoder Decoder
  18. switch {
  19. case runtime.PtrTo(typ).Implements(unmarshalJSONType):
  20. unmarshalDecoder = newUnmarshalJSONDecoder(runtime.PtrTo(typ), structName, fieldName)
  21. case runtime.PtrTo(typ).Implements(unmarshalTextType):
  22. unmarshalDecoder = newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName)
  23. default:
  24. unmarshalDecoder, _ = compileUint8(typ, structName, fieldName)
  25. }
  26. return newSliceDecoder(unmarshalDecoder, typ, 1, structName, fieldName)
  27. }
  28. func newBytesDecoder(typ *runtime.Type, structName string, fieldName string) *bytesDecoder {
  29. return &bytesDecoder{
  30. typ: typ,
  31. sliceDecoder: byteUnmarshalerSliceDecoder(typ, structName, fieldName),
  32. stringDecoder: newStringDecoder(structName, fieldName),
  33. structName: structName,
  34. fieldName: fieldName,
  35. }
  36. }
  37. func (d *bytesDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
  38. bytes, err := d.decodeStreamBinary(s, depth, p)
  39. if err != nil {
  40. return err
  41. }
  42. if bytes == nil {
  43. s.reset()
  44. return nil
  45. }
  46. decodedLen := base64.StdEncoding.DecodedLen(len(bytes))
  47. buf := make([]byte, decodedLen)
  48. n, err := base64.StdEncoding.Decode(buf, bytes)
  49. if err != nil {
  50. return err
  51. }
  52. *(*[]byte)(p) = buf[:n]
  53. s.reset()
  54. return nil
  55. }
  56. func (d *bytesDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
  57. bytes, c, err := d.decodeBinary(ctx, cursor, depth, p)
  58. if err != nil {
  59. return 0, err
  60. }
  61. if bytes == nil {
  62. return c, nil
  63. }
  64. cursor = c
  65. decodedLen := base64.StdEncoding.DecodedLen(len(bytes))
  66. b := make([]byte, decodedLen)
  67. n, err := base64.StdEncoding.Decode(b, bytes)
  68. if err != nil {
  69. return 0, err
  70. }
  71. *(*[]byte)(p) = b[:n]
  72. return cursor, nil
  73. }
  74. func (d *bytesDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
  75. return nil, 0, fmt.Errorf("json: []byte decoder does not support decode path")
  76. }
  77. func (d *bytesDecoder) decodeStreamBinary(s *Stream, depth int64, p unsafe.Pointer) ([]byte, error) {
  78. c := s.skipWhiteSpace()
  79. if c == '[' {
  80. if d.sliceDecoder == nil {
  81. return nil, &errors.UnmarshalTypeError{
  82. Type: runtime.RType2Type(d.typ),
  83. Offset: s.totalOffset(),
  84. }
  85. }
  86. err := d.sliceDecoder.DecodeStream(s, depth, p)
  87. return nil, err
  88. }
  89. return d.stringDecoder.decodeStreamByte(s)
  90. }
  91. func (d *bytesDecoder) decodeBinary(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) ([]byte, int64, error) {
  92. buf := ctx.Buf
  93. cursor = skipWhiteSpace(buf, cursor)
  94. if buf[cursor] == '[' {
  95. if d.sliceDecoder == nil {
  96. return nil, 0, &errors.UnmarshalTypeError{
  97. Type: runtime.RType2Type(d.typ),
  98. Offset: cursor,
  99. }
  100. }
  101. c, err := d.sliceDecoder.Decode(ctx, cursor, depth, p)
  102. if err != nil {
  103. return nil, 0, err
  104. }
  105. return nil, c, nil
  106. }
  107. return d.stringDecoder.decodeByte(buf, cursor)
  108. }