github.com/3JoB/go-json@v0.10.4/internal/decoder/interface.go (about)

     1  package decoder
     2  
     3  import (
     4  	"bytes"
     5  	"encoding"
     6  	"encoding/json"
     7  	"strings"
     8  	"unsafe"
     9  
    10  	"github.com/3JoB/go-reflect"
    11  	"github.com/3JoB/unsafeConvert"
    12  
    13  	"github.com/3JoB/go-json/internal/errors"
    14  	"github.com/3JoB/go-json/internal/runtime"
    15  )
    16  
    17  type interfaceDecoder struct {
    18  	typ           *runtime.Type
    19  	structName    string
    20  	fieldName     string
    21  	sliceDecoder  *sliceDecoder
    22  	mapDecoder    *mapDecoder
    23  	floatDecoder  *floatDecoder
    24  	intDecoder    *intDecoder
    25  	numberDecoder *numberDecoder
    26  	stringDecoder *stringDecoder
    27  }
    28  
    29  func newEmptyInterfaceDecoder(structName, fieldName string) *interfaceDecoder {
    30  	ifaceDecoder := &interfaceDecoder{
    31  		typ:        emptyInterfaceType,
    32  		structName: structName,
    33  		fieldName:  fieldName,
    34  		floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
    35  			*(*any)(p) = v
    36  		}),
    37  		intDecoder: newIntDecoder(nil, structName, fieldName, func(p unsafe.Pointer, v int64) {
    38  			*(*any)(p) = v
    39  		}),
    40  		numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) {
    41  			*(*any)(p) = v
    42  		}),
    43  		stringDecoder: newStringDecoder(structName, fieldName),
    44  	}
    45  	ifaceDecoder.sliceDecoder = newSliceDecoder(
    46  		ifaceDecoder,
    47  		emptyInterfaceType,
    48  		emptyInterfaceType.Size(),
    49  		structName, fieldName,
    50  	)
    51  	ifaceDecoder.mapDecoder = newMapDecoder(
    52  		interfaceMapType,
    53  		stringType,
    54  		ifaceDecoder.stringDecoder,
    55  		interfaceMapType.Elem(),
    56  		ifaceDecoder,
    57  		structName,
    58  		fieldName,
    59  	)
    60  	return ifaceDecoder
    61  }
    62  
    63  func newInterfaceDecoder(typ *runtime.Type, structName, fieldName string) *interfaceDecoder {
    64  	emptyIfaceDecoder := newEmptyInterfaceDecoder(structName, fieldName)
    65  	stringDecoder := newStringDecoder(structName, fieldName)
    66  	return &interfaceDecoder{
    67  		typ:        typ,
    68  		structName: structName,
    69  		fieldName:  fieldName,
    70  		sliceDecoder: newSliceDecoder(
    71  			emptyIfaceDecoder,
    72  			emptyInterfaceType,
    73  			emptyInterfaceType.Size(),
    74  			structName, fieldName,
    75  		),
    76  		mapDecoder: newMapDecoder(
    77  			interfaceMapType,
    78  			stringType,
    79  			stringDecoder,
    80  			interfaceMapType.Elem(),
    81  			emptyIfaceDecoder,
    82  			structName,
    83  			fieldName,
    84  		),
    85  		floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
    86  			*(*any)(p) = v
    87  		}),
    88  		intDecoder: newIntDecoder(nil, structName, fieldName, func(p unsafe.Pointer, v int64) {
    89  			*(*any)(p) = v
    90  		}),
    91  		numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) {
    92  			*(*any)(p) = v
    93  		}),
    94  		stringDecoder: stringDecoder,
    95  	}
    96  }
    97  
    98  func (d *interfaceDecoder) numDecoder(s *Stream) Decoder {
    99  	if s.UseNumber {
   100  		return d.numberDecoder
   101  	}
   102  	return d.floatDecoder
   103  }
   104  
   105  var (
   106  	emptyInterfaceType = runtime.Type2RType(reflect.ToRT(reflect.TypeOf((*any)(nil)).Elem()))
   107  	EmptyInterfaceType = emptyInterfaceType
   108  	interfaceMapType   = runtime.Type2RType(
   109  		reflect.ToRT(reflect.TypeOf((*map[string]any)(nil)).Elem()),
   110  	)
   111  	stringType = runtime.Type2RType(
   112  		reflect.ToRT(reflect.TypeOf("")),
   113  	)
   114  )
   115  
   116  func decodeStreamUnmarshaler(s *Stream, depth int64, unmarshaler json.Unmarshaler) error {
   117  	start := s.cursor
   118  	if err := s.skipValue(depth); err != nil {
   119  		return err
   120  	}
   121  	src := s.buf[start:s.cursor]
   122  	dst := make([]byte, len(src))
   123  	copy(dst, src)
   124  
   125  	if err := unmarshaler.UnmarshalJSON(dst); err != nil {
   126  		return err
   127  	}
   128  	return nil
   129  }
   130  
   131  func decodeStreamUnmarshalerContext(s *Stream, depth int64, unmarshaler unmarshalerContext) error {
   132  	start := s.cursor
   133  	if err := s.skipValue(depth); err != nil {
   134  		return err
   135  	}
   136  	src := s.buf[start:s.cursor]
   137  	dst := make([]byte, len(src))
   138  	copy(dst, src)
   139  
   140  	if err := unmarshaler.UnmarshalJSON(s.Option.Context, dst); err != nil {
   141  		return err
   142  	}
   143  	return nil
   144  }
   145  
   146  func decodeUnmarshaler(buf []byte, cursor, depth int64, unmarshaler json.Unmarshaler) (int64, error) {
   147  	cursor = skipWhiteSpace(buf, cursor)
   148  	start := cursor
   149  	end, err := skipValue(buf, cursor, depth)
   150  	if err != nil {
   151  		return 0, err
   152  	}
   153  	src := buf[start:end]
   154  	dst := make([]byte, len(src))
   155  	copy(dst, src)
   156  
   157  	if err := unmarshaler.UnmarshalJSON(dst); err != nil {
   158  		return 0, err
   159  	}
   160  	return end, nil
   161  }
   162  
   163  func decodeUnmarshalerContext(ctx *RuntimeContext, buf []byte, cursor, depth int64, unmarshaler unmarshalerContext) (int64, error) {
   164  	cursor = skipWhiteSpace(buf, cursor)
   165  	start := cursor
   166  	end, err := skipValue(buf, cursor, depth)
   167  	if err != nil {
   168  		return 0, err
   169  	}
   170  	src := buf[start:end]
   171  	dst := make([]byte, len(src))
   172  	copy(dst, src)
   173  
   174  	if err := unmarshaler.UnmarshalJSON(ctx.Option.Context, dst); err != nil {
   175  		return 0, err
   176  	}
   177  	return end, nil
   178  }
   179  
   180  func decodeStreamTextUnmarshaler(s *Stream, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) error {
   181  	start := s.cursor
   182  	if err := s.skipValue(depth); err != nil {
   183  		return err
   184  	}
   185  	src := s.buf[start:s.cursor]
   186  	if bytes.Equal(src, nullbytes) {
   187  		*(*unsafe.Pointer)(p) = nil
   188  		return nil
   189  	}
   190  
   191  	dst := make([]byte, len(src))
   192  	copy(dst, src)
   193  
   194  	if err := unmarshaler.UnmarshalText(dst); err != nil {
   195  		return err
   196  	}
   197  	return nil
   198  }
   199  
   200  func decodeTextUnmarshaler(buf []byte, cursor, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) (int64, error) {
   201  	cursor = skipWhiteSpace(buf, cursor)
   202  	start := cursor
   203  	end, err := skipValue(buf, cursor, depth)
   204  	if err != nil {
   205  		return 0, err
   206  	}
   207  	src := buf[start:end]
   208  	if bytes.Equal(src, nullbytes) {
   209  		*(*unsafe.Pointer)(p) = nil
   210  		return end, nil
   211  	}
   212  	if s, ok := unquoteBytes(src); ok {
   213  		src = s
   214  	}
   215  	if err := unmarshaler.UnmarshalText(src); err != nil {
   216  		return 0, err
   217  	}
   218  	return end, nil
   219  }
   220  
   221  func (d *interfaceDecoder) decodeStreamEmptyInterface(s *Stream, depth int64, p unsafe.Pointer) error {
   222  	c := s.skipWhiteSpace()
   223  	for {
   224  		switch c {
   225  		case '{':
   226  			var v map[string]any
   227  			ptr := unsafe.Pointer(&v)
   228  			if err := d.mapDecoder.DecodeStream(s, depth, ptr); err != nil {
   229  				return err
   230  			}
   231  			*(*any)(p) = v
   232  			return nil
   233  		case '[':
   234  			var v []any
   235  			ptr := unsafe.Pointer(&v)
   236  			if err := d.sliceDecoder.DecodeStream(s, depth, ptr); err != nil {
   237  				return err
   238  			}
   239  			*(*any)(p) = v
   240  			return nil
   241  		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
   242  			return d.numDecoder(s).DecodeStream(s, depth, p)
   243  		case '"':
   244  			b, cursor, err := stringBytes(s)
   245  			s.cursor = cursor
   246  			if err != nil {
   247  				return err
   248  			}
   249  			*(*any)(p) = unsafeConvert.StringReflect(b)
   250  			return nil
   251  		case 't':
   252  			if err := trueBytes(s); err != nil {
   253  				return err
   254  			}
   255  			**(**any)(unsafe.Pointer(&p)) = true
   256  			return nil
   257  		case 'f':
   258  			if err := falseBytes(s); err != nil {
   259  				return err
   260  			}
   261  			**(**any)(unsafe.Pointer(&p)) = false
   262  			return nil
   263  		case 'n':
   264  			if err := nullBytes(s); err != nil {
   265  				return err
   266  			}
   267  			*(*any)(p) = nil
   268  			return nil
   269  		case nul:
   270  			if s.read() {
   271  				c = s.char()
   272  				continue
   273  			}
   274  		}
   275  		break
   276  	}
   277  	return errors.ErrInvalidBeginningOfValue(c, s.totalOffset())
   278  }
   279  
   280  type emptyInterface struct {
   281  	typ *runtime.Type
   282  	ptr unsafe.Pointer
   283  }
   284  
   285  func (d *interfaceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
   286  	runtimeInterfaceValue := *(*any)(unsafe.Pointer(&emptyInterface{
   287  		typ: d.typ,
   288  		ptr: p,
   289  	}))
   290  	rv := reflect.ValueOf(runtimeInterfaceValue)
   291  	if rv.NumMethod() > 0 && rv.CanInterface() {
   292  		if u, ok := rv.Interface().(unmarshalerContext); ok {
   293  			return decodeStreamUnmarshalerContext(s, depth, u)
   294  		}
   295  		if u, ok := rv.Interface().(json.Unmarshaler); ok {
   296  			return decodeStreamUnmarshaler(s, depth, u)
   297  		}
   298  		if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
   299  			return decodeStreamTextUnmarshaler(s, depth, u, p)
   300  		}
   301  		if s.skipWhiteSpace() == 'n' {
   302  			if err := nullBytes(s); err != nil {
   303  				return err
   304  			}
   305  			*(*any)(p) = nil
   306  			return nil
   307  		}
   308  		return d.errUnmarshalType(rv.Type(), s.totalOffset())
   309  	}
   310  	iface := rv.Interface()
   311  	ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface))
   312  	typ := ifaceHeader.typ
   313  	if ifaceHeader.ptr == nil || d.typ == typ || typ == nil {
   314  		// concrete type is empty interface
   315  		return d.decodeStreamEmptyInterface(s, depth, p)
   316  	}
   317  	if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr {
   318  		return d.decodeStreamEmptyInterface(s, depth, p)
   319  	}
   320  	if s.skipWhiteSpace() == 'n' {
   321  		if err := nullBytes(s); err != nil {
   322  			return err
   323  		}
   324  		*(*any)(p) = nil
   325  		return nil
   326  	}
   327  	decoder, err := CompileToGetDecoder(typ)
   328  	if err != nil {
   329  		return err
   330  	}
   331  	return decoder.DecodeStream(s, depth, ifaceHeader.ptr)
   332  }
   333  
   334  func (d *interfaceDecoder) errUnmarshalType(typ reflect.Type, offset int64) *errors.UnmarshalTypeError {
   335  	return &errors.UnmarshalTypeError{
   336  		Value:  typ.String(),
   337  		Type:   typ,
   338  		Offset: offset,
   339  		Struct: d.structName,
   340  		Field:  d.fieldName,
   341  	}
   342  }
   343  
   344  func (d *interfaceDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
   345  	buf := ctx.Buf
   346  	runtimeInterfaceValue := *(*any)(unsafe.Pointer(&emptyInterface{
   347  		typ: d.typ,
   348  		ptr: p,
   349  	}))
   350  	rv := reflect.ValueOf(runtimeInterfaceValue)
   351  	if rv.NumMethod() > 0 && rv.CanInterface() {
   352  		if u, ok := rv.Interface().(unmarshalerContext); ok {
   353  			return decodeUnmarshalerContext(ctx, buf, cursor, depth, u)
   354  		}
   355  		if u, ok := rv.Interface().(json.Unmarshaler); ok {
   356  			return decodeUnmarshaler(buf, cursor, depth, u)
   357  		}
   358  		if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
   359  			return decodeTextUnmarshaler(buf, cursor, depth, u, p)
   360  		}
   361  		cursor = skipWhiteSpace(buf, cursor)
   362  		if buf[cursor] == 'n' {
   363  			if err := validateNull(buf, cursor); err != nil {
   364  				return 0, err
   365  			}
   366  			cursor += 4
   367  			**(**any)(unsafe.Pointer(&p)) = nil
   368  			return cursor, nil
   369  		}
   370  		return 0, d.errUnmarshalType(rv.Type(), cursor)
   371  	}
   372  
   373  	iface := rv.Interface()
   374  	ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface))
   375  	typ := ifaceHeader.typ
   376  	if ifaceHeader.ptr == nil || d.typ == typ || typ == nil {
   377  		// concrete type is empty interface
   378  		return d.decodeEmptyInterface(ctx, cursor, depth, p)
   379  	}
   380  	if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr {
   381  		return d.decodeEmptyInterface(ctx, cursor, depth, p)
   382  	}
   383  	cursor = skipWhiteSpace(buf, cursor)
   384  	if buf[cursor] == 'n' {
   385  		if err := validateNull(buf, cursor); err != nil {
   386  			return 0, err
   387  		}
   388  		cursor += 4
   389  		**(**any)(unsafe.Pointer(&p)) = nil
   390  		return cursor, nil
   391  	}
   392  	decoder, err := CompileToGetDecoder(typ)
   393  	if err != nil {
   394  		return 0, err
   395  	}
   396  	return decoder.Decode(ctx, cursor, depth, ifaceHeader.ptr)
   397  }
   398  
   399  func (d *interfaceDecoder) decodeEmptyInterface(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
   400  	buf := ctx.Buf
   401  	cursor = skipWhiteSpace(buf, cursor)
   402  	switch buf[cursor] {
   403  	case '{':
   404  		var v map[string]any
   405  		ptr := unsafe.Pointer(&v)
   406  		cursor, err := d.mapDecoder.Decode(ctx, cursor, depth, ptr)
   407  		if err != nil {
   408  			return 0, err
   409  		}
   410  		**(**any)(unsafe.Pointer(&p)) = v
   411  		return cursor, nil
   412  	case '[':
   413  		var v []any
   414  		ptr := unsafe.Pointer(&v)
   415  		cursor, err := d.sliceDecoder.Decode(ctx, cursor, depth, ptr)
   416  		if err != nil {
   417  			return 0, err
   418  		}
   419  		**(**any)(unsafe.Pointer(&p)) = v
   420  		return cursor, nil
   421  	case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
   422  		bytes, _, _ := d.numberDecoder.decodeByte(ctx.Buf, cursor)
   423  		numberStr := *(*string)(unsafe.Pointer(&bytes))
   424  		if strings.Contains(numberStr, ".") {
   425  			return d.floatDecoder.Decode(ctx, cursor, depth, p)
   426  		} else {
   427  			return d.intDecoder.Decode(ctx, cursor, depth, p)
   428  		}
   429  	case '"':
   430  		var v string
   431  		ptr := unsafe.Pointer(&v)
   432  		cursor, err := d.stringDecoder.Decode(ctx, cursor, depth, ptr)
   433  		if err != nil {
   434  			return 0, err
   435  		}
   436  		**(**any)(unsafe.Pointer(&p)) = v
   437  		return cursor, nil
   438  	case 't':
   439  		if err := validateTrue(buf, cursor); err != nil {
   440  			return 0, err
   441  		}
   442  		cursor += 4
   443  		**(**any)(unsafe.Pointer(&p)) = true
   444  		return cursor, nil
   445  	case 'f':
   446  		if err := validateFalse(buf, cursor); err != nil {
   447  			return 0, err
   448  		}
   449  		cursor += 5
   450  		**(**any)(unsafe.Pointer(&p)) = false
   451  		return cursor, nil
   452  	case 'n':
   453  		if err := validateNull(buf, cursor); err != nil {
   454  			return 0, err
   455  		}
   456  		cursor += 4
   457  		**(**any)(unsafe.Pointer(&p)) = nil
   458  		return cursor, nil
   459  	}
   460  	return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
   461  }
   462  
   463  func NewPathDecoder() Decoder {
   464  	ifaceDecoder := &interfaceDecoder{
   465  		typ:        emptyInterfaceType,
   466  		structName: "",
   467  		fieldName:  "",
   468  		floatDecoder: newFloatDecoder("", "", func(p unsafe.Pointer, v float64) {
   469  			*(*any)(p) = v
   470  		}),
   471  		numberDecoder: newNumberDecoder("", "", func(p unsafe.Pointer, v json.Number) {
   472  			*(*any)(p) = v
   473  		}),
   474  		stringDecoder: newStringDecoder("", ""),
   475  	}
   476  	ifaceDecoder.sliceDecoder = newSliceDecoder(
   477  		ifaceDecoder,
   478  		emptyInterfaceType,
   479  		emptyInterfaceType.Size(),
   480  		"", "",
   481  	)
   482  	ifaceDecoder.mapDecoder = newMapDecoder(
   483  		interfaceMapType,
   484  		stringType,
   485  		ifaceDecoder.stringDecoder,
   486  		interfaceMapType.Elem(),
   487  		ifaceDecoder,
   488  		"", "",
   489  	)
   490  	return ifaceDecoder
   491  }
   492  
   493  var (
   494  	truebytes  = unsafeConvert.BytesReflect("true")
   495  	falsebytes = unsafeConvert.BytesReflect("false")
   496  )
   497  
   498  func (d *interfaceDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
   499  	buf := ctx.Buf
   500  	cursor = skipWhiteSpace(buf, cursor)
   501  	switch buf[cursor] {
   502  	case '{':
   503  		return d.mapDecoder.DecodePath(ctx, cursor, depth)
   504  	case '[':
   505  		return d.sliceDecoder.DecodePath(ctx, cursor, depth)
   506  	case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
   507  		return d.floatDecoder.DecodePath(ctx, cursor, depth)
   508  	case '"':
   509  		return d.stringDecoder.DecodePath(ctx, cursor, depth)
   510  	case 't':
   511  		if err := validateTrue(buf, cursor); err != nil {
   512  			return nil, 0, err
   513  		}
   514  		cursor += 4
   515  		return [][]byte{truebytes}, cursor, nil
   516  	case 'f':
   517  		if err := validateFalse(buf, cursor); err != nil {
   518  			return nil, 0, err
   519  		}
   520  		cursor += 5
   521  		return [][]byte{falsebytes}, cursor, nil
   522  	case 'n':
   523  		if err := validateNull(buf, cursor); err != nil {
   524  			return nil, 0, err
   525  		}
   526  		cursor += 4
   527  		return [][]byte{nullbytes}, cursor, nil
   528  	}
   529  	return nil, cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
   530  }