gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

decode.go (6435B)


      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 }