github.com/goccy/go-json@v0.10.3-0.20240509105655-5e2ae3f23c1d/decode.go (about)

     1  package json
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"reflect"
     8  	"unsafe"
     9  
    10  	"github.com/goccy/go-json/internal/decoder"
    11  	"github.com/goccy/go-json/internal/errors"
    12  	"github.com/goccy/go-json/internal/runtime"
    13  )
    14  
    15  type Decoder struct {
    16  	s *decoder.Stream
    17  }
    18  
    19  const (
    20  	nul = '\000'
    21  )
    22  
    23  type emptyInterface struct {
    24  	typ *runtime.Type
    25  	ptr unsafe.Pointer
    26  }
    27  
    28  func unmarshal(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
    29  	src := make([]byte, len(data)+1) // append nul byte to the end
    30  	copy(src, data)
    31  
    32  	header := (*emptyInterface)(unsafe.Pointer(&v))
    33  
    34  	if err := validateType(header.typ, uintptr(header.ptr)); err != nil {
    35  		return err
    36  	}
    37  	dec, err := decoder.CompileToGetDecoder(header.typ)
    38  	if err != nil {
    39  		return err
    40  	}
    41  	ctx := decoder.TakeRuntimeContext()
    42  	ctx.Buf = src
    43  	ctx.Option.Flags = 0
    44  	for _, optFunc := range optFuncs {
    45  		optFunc(ctx.Option)
    46  	}
    47  	cursor, err := dec.Decode(ctx, 0, 0, header.ptr)
    48  	if err != nil {
    49  		decoder.ReleaseRuntimeContext(ctx)
    50  		return err
    51  	}
    52  	decoder.ReleaseRuntimeContext(ctx)
    53  	return validateEndBuf(src, cursor)
    54  }
    55  
    56  func unmarshalContext(ctx context.Context, data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
    57  	src := make([]byte, len(data)+1) // append nul byte to the end
    58  	copy(src, data)
    59  
    60  	header := (*emptyInterface)(unsafe.Pointer(&v))
    61  
    62  	if err := validateType(header.typ, uintptr(header.ptr)); err != nil {
    63  		return err
    64  	}
    65  	dec, err := decoder.CompileToGetDecoder(header.typ)
    66  	if err != nil {
    67  		return err
    68  	}
    69  	rctx := decoder.TakeRuntimeContext()
    70  	rctx.Buf = src
    71  	rctx.Option.Flags = 0
    72  	rctx.Option.Flags |= decoder.ContextOption
    73  	rctx.Option.Context = ctx
    74  	for _, optFunc := range optFuncs {
    75  		optFunc(rctx.Option)
    76  	}
    77  	cursor, err := dec.Decode(rctx, 0, 0, header.ptr)
    78  	if err != nil {
    79  		decoder.ReleaseRuntimeContext(rctx)
    80  		return err
    81  	}
    82  	decoder.ReleaseRuntimeContext(rctx)
    83  	return validateEndBuf(src, cursor)
    84  }
    85  
    86  var (
    87  	pathDecoder = decoder.NewPathDecoder()
    88  )
    89  
    90  func extractFromPath(path *Path, data []byte, optFuncs ...DecodeOptionFunc) ([][]byte, error) {
    91  	if path.path.RootSelectorOnly {
    92  		return [][]byte{data}, nil
    93  	}
    94  	src := make([]byte, len(data)+1) // append nul byte to the end
    95  	copy(src, data)
    96  
    97  	ctx := decoder.TakeRuntimeContext()
    98  	ctx.Buf = src
    99  	ctx.Option.Flags = 0
   100  	ctx.Option.Flags |= decoder.PathOption
   101  	ctx.Option.Path = path.path
   102  	for _, optFunc := range optFuncs {
   103  		optFunc(ctx.Option)
   104  	}
   105  	paths, cursor, err := pathDecoder.DecodePath(ctx, 0, 0)
   106  	if err != nil {
   107  		decoder.ReleaseRuntimeContext(ctx)
   108  		return nil, err
   109  	}
   110  	decoder.ReleaseRuntimeContext(ctx)
   111  	if err := validateEndBuf(src, cursor); err != nil {
   112  		return nil, err
   113  	}
   114  	return paths, nil
   115  }
   116  
   117  func unmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
   118  	src := make([]byte, len(data)+1) // append nul byte to the end
   119  	copy(src, data)
   120  
   121  	header := (*emptyInterface)(unsafe.Pointer(&v))
   122  
   123  	if err := validateType(header.typ, uintptr(header.ptr)); err != nil {
   124  		return err
   125  	}
   126  	dec, err := decoder.CompileToGetDecoder(header.typ)
   127  	if err != nil {
   128  		return err
   129  	}
   130  
   131  	ctx := decoder.TakeRuntimeContext()
   132  	ctx.Buf = src
   133  	ctx.Option.Flags = 0
   134  	for _, optFunc := range optFuncs {
   135  		optFunc(ctx.Option)
   136  	}
   137  	cursor, err := dec.Decode(ctx, 0, 0, noescape(header.ptr))
   138  	if err != nil {
   139  		decoder.ReleaseRuntimeContext(ctx)
   140  		return err
   141  	}
   142  	decoder.ReleaseRuntimeContext(ctx)
   143  	return validateEndBuf(src, cursor)
   144  }
   145  
   146  func validateEndBuf(src []byte, cursor int64) error {
   147  	for {
   148  		switch src[cursor] {
   149  		case ' ', '\t', '\n', '\r':
   150  			cursor++
   151  			continue
   152  		case nul:
   153  			return nil
   154  		}
   155  		return errors.ErrSyntax(
   156  			fmt.Sprintf("invalid character '%c' after top-level value", src[cursor]),
   157  			cursor+1,
   158  		)
   159  	}
   160  }
   161  
   162  //nolint:staticcheck
   163  //go:nosplit
   164  func noescape(p unsafe.Pointer) unsafe.Pointer {
   165  	x := uintptr(p)
   166  	return unsafe.Pointer(x ^ 0)
   167  }
   168  
   169  func validateType(typ *runtime.Type, p uintptr) error {
   170  	if typ == nil || typ.Kind() != reflect.Ptr || p == 0 {
   171  		return &InvalidUnmarshalError{Type: runtime.RType2Type(typ)}
   172  	}
   173  	return nil
   174  }
   175  
   176  // NewDecoder returns a new decoder that reads from r.
   177  //
   178  // The decoder introduces its own buffering and may
   179  // read data from r beyond the JSON values requested.
   180  func NewDecoder(r io.Reader) *Decoder {
   181  	s := decoder.NewStream(r)
   182  	return &Decoder{
   183  		s: s,
   184  	}
   185  }
   186  
   187  // Buffered returns a reader of the data remaining in the Decoder's
   188  // buffer. The reader is valid until the next call to Decode.
   189  func (d *Decoder) Buffered() io.Reader {
   190  	return d.s.Buffered()
   191  }
   192  
   193  // Decode reads the next JSON-encoded value from its
   194  // input and stores it in the value pointed to by v.
   195  //
   196  // See the documentation for Unmarshal for details about
   197  // the conversion of JSON into a Go value.
   198  func (d *Decoder) Decode(v interface{}) error {
   199  	return d.DecodeWithOption(v)
   200  }
   201  
   202  // DecodeContext reads the next JSON-encoded value from its
   203  // input and stores it in the value pointed to by v with context.Context.
   204  func (d *Decoder) DecodeContext(ctx context.Context, v interface{}) error {
   205  	d.s.Option.Flags |= decoder.ContextOption
   206  	d.s.Option.Context = ctx
   207  	return d.DecodeWithOption(v)
   208  }
   209  
   210  func (d *Decoder) DecodeWithOption(v interface{}, optFuncs ...DecodeOptionFunc) error {
   211  	header := (*emptyInterface)(unsafe.Pointer(&v))
   212  	typ := header.typ
   213  	ptr := uintptr(header.ptr)
   214  	typeptr := uintptr(unsafe.Pointer(typ))
   215  	// noescape trick for header.typ ( reflect.*rtype )
   216  	copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr))
   217  
   218  	if err := validateType(copiedType, ptr); err != nil {
   219  		return err
   220  	}
   221  
   222  	dec, err := decoder.CompileToGetDecoder(typ)
   223  	if err != nil {
   224  		return err
   225  	}
   226  	if err := d.s.PrepareForDecode(); err != nil {
   227  		return err
   228  	}
   229  	s := d.s
   230  	for _, optFunc := range optFuncs {
   231  		optFunc(s.Option)
   232  	}
   233  	if err := dec.DecodeStream(s, 0, header.ptr); err != nil {
   234  		return err
   235  	}
   236  	s.Reset()
   237  	return nil
   238  }
   239  
   240  func (d *Decoder) More() bool {
   241  	return d.s.More()
   242  }
   243  
   244  func (d *Decoder) Token() (Token, error) {
   245  	return d.s.Token()
   246  }
   247  
   248  // DisallowUnknownFields causes the Decoder to return an error when the destination
   249  // is a struct and the input contains object keys which do not match any
   250  // non-ignored, exported fields in the destination.
   251  func (d *Decoder) DisallowUnknownFields() {
   252  	d.s.DisallowUnknownFields = true
   253  }
   254  
   255  func (d *Decoder) InputOffset() int64 {
   256  	return d.s.TotalOffset()
   257  }
   258  
   259  // UseNumber causes the Decoder to unmarshal a number into an interface{} as a
   260  // Number instead of as a float64.
   261  func (d *Decoder) UseNumber() {
   262  	d.s.UseNumber = true
   263  }