git.gammaspectra.live/P2Pool/go-json@v0.99.0/internal/decoder/interface.go (about)

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