github.com/night-codes/go-json@v0.9.15/decode.go (about)

     1  package json
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"reflect"
     8  	"unsafe"
     9  
    10  	"github.com/night-codes/go-json/internal/decoder"
    11  	"github.com/night-codes/go-json/internal/errors"
    12  	"github.com/night-codes/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  func unmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
    87  	src := make([]byte, len(data)+1) // append nul byte to the end
    88  	copy(src, data)
    89  
    90  	header := (*emptyInterface)(unsafe.Pointer(&v))
    91  
    92  	if err := validateType(header.typ, uintptr(header.ptr)); err != nil {
    93  		return err
    94  	}
    95  	dec, err := decoder.CompileToGetDecoder(header.typ)
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	ctx := decoder.TakeRuntimeContext()
   101  	ctx.Buf = src
   102  	ctx.Option.Flags = 0
   103  	for _, optFunc := range optFuncs {
   104  		optFunc(ctx.Option)
   105  	}
   106  	cursor, err := dec.Decode(ctx, 0, 0, noescape(header.ptr))
   107  	if err != nil {
   108  		decoder.ReleaseRuntimeContext(ctx)
   109  		return err
   110  	}
   111  	decoder.ReleaseRuntimeContext(ctx)
   112  	return validateEndBuf(src, cursor)
   113  }
   114  
   115  func validateEndBuf(src []byte, cursor int64) error {
   116  	for {
   117  		switch src[cursor] {
   118  		case ' ', '\t', '\n', '\r':
   119  			cursor++
   120  			continue
   121  		case nul:
   122  			return nil
   123  		}
   124  		return errors.ErrSyntax(
   125  			fmt.Sprintf("invalid character '%c' after top-level value", src[cursor]),
   126  			cursor+1,
   127  		)
   128  	}
   129  }
   130  
   131  //nolint:staticcheck
   132  //go:nosplit
   133  func noescape(p unsafe.Pointer) unsafe.Pointer {
   134  	x := uintptr(p)
   135  	return unsafe.Pointer(x ^ 0)
   136  }
   137  
   138  func validateType(typ *runtime.Type, p uintptr) error {
   139  	if typ == nil || typ.Kind() != reflect.Ptr || p == 0 {
   140  		return &InvalidUnmarshalError{Type: runtime.RType2Type(typ)}
   141  	}
   142  	return nil
   143  }
   144  
   145  // NewDecoder returns a new decoder that reads from r.
   146  //
   147  // The decoder introduces its own buffering and may
   148  // read data from r beyond the JSON values requested.
   149  func NewDecoder(r io.Reader) *Decoder {
   150  	s := decoder.NewStream(r)
   151  	return &Decoder{
   152  		s: s,
   153  	}
   154  }
   155  
   156  // Buffered returns a reader of the data remaining in the Decoder's
   157  // buffer. The reader is valid until the next call to Decode.
   158  func (d *Decoder) Buffered() io.Reader {
   159  	return d.s.Buffered()
   160  }
   161  
   162  // Decode reads the next JSON-encoded value from its
   163  // input and stores it in the value pointed to by v.
   164  //
   165  // See the documentation for Unmarshal for details about
   166  // the conversion of JSON into a Go value.
   167  func (d *Decoder) Decode(v interface{}) error {
   168  	return d.DecodeWithOption(v)
   169  }
   170  
   171  // DecodeContext reads the next JSON-encoded value from its
   172  // input and stores it in the value pointed to by v with context.Context.
   173  func (d *Decoder) DecodeContext(ctx context.Context, v interface{}) error {
   174  	d.s.Option.Flags |= decoder.ContextOption
   175  	d.s.Option.Context = ctx
   176  	return d.DecodeWithOption(v)
   177  }
   178  
   179  func (d *Decoder) DecodeWithOption(v interface{}, optFuncs ...DecodeOptionFunc) error {
   180  	header := (*emptyInterface)(unsafe.Pointer(&v))
   181  	typ := header.typ
   182  	ptr := uintptr(header.ptr)
   183  	typeptr := uintptr(unsafe.Pointer(typ))
   184  	// noescape trick for header.typ ( reflect.*rtype )
   185  	copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr))
   186  
   187  	if err := validateType(copiedType, ptr); err != nil {
   188  		return err
   189  	}
   190  
   191  	dec, err := decoder.CompileToGetDecoder(typ)
   192  	if err != nil {
   193  		return err
   194  	}
   195  	if err := d.s.PrepareForDecode(); err != nil {
   196  		return err
   197  	}
   198  	s := d.s
   199  	for _, optFunc := range optFuncs {
   200  		optFunc(s.Option)
   201  	}
   202  	if err := dec.DecodeStream(s, 0, header.ptr); err != nil {
   203  		return err
   204  	}
   205  	s.Reset()
   206  	return nil
   207  }
   208  
   209  func (d *Decoder) More() bool {
   210  	return d.s.More()
   211  }
   212  
   213  func (d *Decoder) Token() (Token, error) {
   214  	return d.s.Token()
   215  }
   216  
   217  // DisallowUnknownFields causes the Decoder to return an error when the destination
   218  // is a struct and the input contains object keys which do not match any
   219  // non-ignored, exported fields in the destination.
   220  func (d *Decoder) DisallowUnknownFields() {
   221  	d.s.DisallowUnknownFields = true
   222  }
   223  
   224  func (d *Decoder) InputOffset() int64 {
   225  	return d.s.TotalOffset()
   226  }
   227  
   228  // UseNumber causes the Decoder to unmarshal a number into an interface{} as a
   229  // Number instead of as a float64.
   230  func (d *Decoder) UseNumber() {
   231  	d.s.UseNumber = true
   232  }