gtsocial-umbx

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

unmarshal_json.go (2460B)


      1 package decoder
      2 
      3 import (
      4 	"context"
      5 	"encoding/json"
      6 	"fmt"
      7 	"unsafe"
      8 
      9 	"github.com/goccy/go-json/internal/errors"
     10 	"github.com/goccy/go-json/internal/runtime"
     11 )
     12 
     13 type unmarshalJSONDecoder struct {
     14 	typ        *runtime.Type
     15 	structName string
     16 	fieldName  string
     17 }
     18 
     19 func newUnmarshalJSONDecoder(typ *runtime.Type, structName, fieldName string) *unmarshalJSONDecoder {
     20 	return &unmarshalJSONDecoder{
     21 		typ:        typ,
     22 		structName: structName,
     23 		fieldName:  fieldName,
     24 	}
     25 }
     26 
     27 func (d *unmarshalJSONDecoder) annotateError(cursor int64, err error) {
     28 	switch e := err.(type) {
     29 	case *errors.UnmarshalTypeError:
     30 		e.Struct = d.structName
     31 		e.Field = d.fieldName
     32 	case *errors.SyntaxError:
     33 		e.Offset = cursor
     34 	}
     35 }
     36 
     37 func (d *unmarshalJSONDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
     38 	s.skipWhiteSpace()
     39 	start := s.cursor
     40 	if err := s.skipValue(depth); err != nil {
     41 		return err
     42 	}
     43 	src := s.buf[start:s.cursor]
     44 	dst := make([]byte, len(src))
     45 	copy(dst, src)
     46 
     47 	v := *(*interface{})(unsafe.Pointer(&emptyInterface{
     48 		typ: d.typ,
     49 		ptr: p,
     50 	}))
     51 	switch v := v.(type) {
     52 	case unmarshalerContext:
     53 		var ctx context.Context
     54 		if (s.Option.Flags & ContextOption) != 0 {
     55 			ctx = s.Option.Context
     56 		} else {
     57 			ctx = context.Background()
     58 		}
     59 		if err := v.UnmarshalJSON(ctx, dst); err != nil {
     60 			d.annotateError(s.cursor, err)
     61 			return err
     62 		}
     63 	case json.Unmarshaler:
     64 		if err := v.UnmarshalJSON(dst); err != nil {
     65 			d.annotateError(s.cursor, err)
     66 			return err
     67 		}
     68 	}
     69 	return nil
     70 }
     71 
     72 func (d *unmarshalJSONDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
     73 	buf := ctx.Buf
     74 	cursor = skipWhiteSpace(buf, cursor)
     75 	start := cursor
     76 	end, err := skipValue(buf, cursor, depth)
     77 	if err != nil {
     78 		return 0, err
     79 	}
     80 	src := buf[start:end]
     81 	dst := make([]byte, len(src))
     82 	copy(dst, src)
     83 
     84 	v := *(*interface{})(unsafe.Pointer(&emptyInterface{
     85 		typ: d.typ,
     86 		ptr: p,
     87 	}))
     88 	if (ctx.Option.Flags & ContextOption) != 0 {
     89 		if err := v.(unmarshalerContext).UnmarshalJSON(ctx.Option.Context, dst); err != nil {
     90 			d.annotateError(cursor, err)
     91 			return 0, err
     92 		}
     93 	} else {
     94 		if err := v.(json.Unmarshaler).UnmarshalJSON(dst); err != nil {
     95 			d.annotateError(cursor, err)
     96 			return 0, err
     97 		}
     98 	}
     99 	return end, nil
    100 }
    101 
    102 func (d *unmarshalJSONDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
    103 	return nil, 0, fmt.Errorf("json: unmarshal json decoder does not support decode path")
    104 }