github.com/night-codes/go-json@v0.9.15/internal/decoder/interface.go (about)

     1  package decoder
     2  
     3  import (
     4  	"bytes"
     5  	"encoding"
     6  	"encoding/json"
     7  	"reflect"
     8  	"unsafe"
     9  
    10  	"github.com/night-codes/go-json/internal/errors"
    11  	"github.com/night-codes/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  	interfaceMapType   = runtime.Type2RType(
    98  		reflect.TypeOf((*map[string]interface{})(nil)).Elem(),
    99  	)
   100  	stringType = runtime.Type2RType(
   101  		reflect.TypeOf(""),
   102  	)
   103  )
   104  
   105  func decodeStreamUnmarshaler(s *Stream, depth int64, unmarshaler json.Unmarshaler) error {
   106  	start := s.cursor
   107  	if err := s.skipValue(depth); err != nil {
   108  		return err
   109  	}
   110  	src := s.buf[start:s.cursor]
   111  	dst := make([]byte, len(src))
   112  	copy(dst, src)
   113  
   114  	if err := unmarshaler.UnmarshalJSON(dst); err != nil {
   115  		return err
   116  	}
   117  	return nil
   118  }
   119  
   120  func decodeStreamUnmarshalerContext(s *Stream, depth int64, unmarshaler unmarshalerContext) error {
   121  	start := s.cursor
   122  	if err := s.skipValue(depth); err != nil {
   123  		return err
   124  	}
   125  	src := s.buf[start:s.cursor]
   126  	dst := make([]byte, len(src))
   127  	copy(dst, src)
   128  
   129  	if err := unmarshaler.UnmarshalJSON(s.Option.Context, dst); err != nil {
   130  		return err
   131  	}
   132  	return nil
   133  }
   134  
   135  func decodeUnmarshaler(buf []byte, cursor, depth int64, unmarshaler json.Unmarshaler) (int64, error) {
   136  	cursor = skipWhiteSpace(buf, cursor)
   137  	start := cursor
   138  	end, err := skipValue(buf, cursor, depth)
   139  	if err != nil {
   140  		return 0, err
   141  	}
   142  	src := buf[start:end]
   143  	dst := make([]byte, len(src))
   144  	copy(dst, src)
   145  
   146  	if err := unmarshaler.UnmarshalJSON(dst); err != nil {
   147  		return 0, err
   148  	}
   149  	return end, nil
   150  }
   151  
   152  func decodeUnmarshalerContext(ctx *RuntimeContext, buf []byte, cursor, depth int64, unmarshaler unmarshalerContext) (int64, error) {
   153  	cursor = skipWhiteSpace(buf, cursor)
   154  	start := cursor
   155  	end, err := skipValue(buf, cursor, depth)
   156  	if err != nil {
   157  		return 0, err
   158  	}
   159  	src := buf[start:end]
   160  	dst := make([]byte, len(src))
   161  	copy(dst, src)
   162  
   163  	if err := unmarshaler.UnmarshalJSON(ctx.Option.Context, dst); err != nil {
   164  		return 0, err
   165  	}
   166  	return end, nil
   167  }
   168  
   169  func decodeStreamTextUnmarshaler(s *Stream, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) error {
   170  	start := s.cursor
   171  	if err := s.skipValue(depth); err != nil {
   172  		return err
   173  	}
   174  	src := s.buf[start:s.cursor]
   175  	if bytes.Equal(src, nullbytes) {
   176  		*(*unsafe.Pointer)(p) = nil
   177  		return nil
   178  	}
   179  
   180  	dst := make([]byte, len(src))
   181  	copy(dst, src)
   182  
   183  	if err := unmarshaler.UnmarshalText(dst); err != nil {
   184  		return err
   185  	}
   186  	return nil
   187  }
   188  
   189  func decodeTextUnmarshaler(buf []byte, cursor, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) (int64, error) {
   190  	cursor = skipWhiteSpace(buf, cursor)
   191  	start := cursor
   192  	end, err := skipValue(buf, cursor, depth)
   193  	if err != nil {
   194  		return 0, err
   195  	}
   196  	src := buf[start:end]
   197  	if bytes.Equal(src, nullbytes) {
   198  		*(*unsafe.Pointer)(p) = nil
   199  		return end, nil
   200  	}
   201  	if s, ok := unquoteBytes(src); ok {
   202  		src = s
   203  	}
   204  	if err := unmarshaler.UnmarshalText(src); err != nil {
   205  		return 0, err
   206  	}
   207  	return end, nil
   208  }
   209  
   210  func (d *interfaceDecoder) decodeStreamEmptyInterface(s *Stream, depth int64, p unsafe.Pointer) error {
   211  	c := s.skipWhiteSpace()
   212  	for {
   213  		switch c {
   214  		case '{':
   215  			var v map[string]interface{}
   216  			ptr := unsafe.Pointer(&v)
   217  			if err := d.mapDecoder.DecodeStream(s, depth, ptr); err != nil {
   218  				return err
   219  			}
   220  			*(*interface{})(p) = v
   221  			return nil
   222  		case '[':
   223  			var v []interface{}
   224  			ptr := unsafe.Pointer(&v)
   225  			if err := d.sliceDecoder.DecodeStream(s, depth, ptr); err != nil {
   226  				return err
   227  			}
   228  			*(*interface{})(p) = v
   229  			return nil
   230  		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
   231  			return d.numDecoder(s).DecodeStream(s, depth, p)
   232  		case '"':
   233  			s.cursor++
   234  			start := s.cursor
   235  			for {
   236  				switch s.char() {
   237  				case '\\':
   238  					if _, err := decodeEscapeString(s, nil); err != nil {
   239  						return err
   240  					}
   241  				case '"':
   242  					literal := s.buf[start:s.cursor]
   243  					s.cursor++
   244  					*(*interface{})(p) = string(literal)
   245  					return nil
   246  				case nul:
   247  					if s.read() {
   248  						continue
   249  					}
   250  					return errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
   251  				}
   252  				s.cursor++
   253  			}
   254  		case 't':
   255  			if err := trueBytes(s); err != nil {
   256  				return err
   257  			}
   258  			**(**interface{})(unsafe.Pointer(&p)) = true
   259  			return nil
   260  		case 'f':
   261  			if err := falseBytes(s); err != nil {
   262  				return err
   263  			}
   264  			**(**interface{})(unsafe.Pointer(&p)) = false
   265  			return nil
   266  		case 'n':
   267  			if err := nullBytes(s); err != nil {
   268  				return err
   269  			}
   270  			*(*interface{})(p) = nil
   271  			return nil
   272  		case nul:
   273  			if s.read() {
   274  				c = s.char()
   275  				continue
   276  			}
   277  		}
   278  		break
   279  	}
   280  	return errors.ErrInvalidBeginningOfValue(c, s.totalOffset())
   281  }
   282  
   283  type emptyInterface struct {
   284  	typ *runtime.Type
   285  	ptr unsafe.Pointer
   286  }
   287  
   288  func (d *interfaceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
   289  	runtimeInterfaceValue := *(*interface{})(unsafe.Pointer(&emptyInterface{
   290  		typ: d.typ,
   291  		ptr: p,
   292  	}))
   293  	rv := reflect.ValueOf(runtimeInterfaceValue)
   294  	if rv.NumMethod() > 0 && rv.CanInterface() {
   295  		if u, ok := rv.Interface().(unmarshalerContext); ok {
   296  			return decodeStreamUnmarshalerContext(s, depth, u)
   297  		}
   298  		if u, ok := rv.Interface().(json.Unmarshaler); ok {
   299  			return decodeStreamUnmarshaler(s, depth, u)
   300  		}
   301  		if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
   302  			return decodeStreamTextUnmarshaler(s, depth, u, p)
   303  		}
   304  		if s.skipWhiteSpace() == 'n' {
   305  			if err := nullBytes(s); err != nil {
   306  				return err
   307  			}
   308  			*(*interface{})(p) = nil
   309  			return nil
   310  		}
   311  		return d.errUnmarshalType(rv.Type(), s.totalOffset())
   312  	}
   313  	iface := rv.Interface()
   314  	ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface))
   315  	typ := ifaceHeader.typ
   316  	if ifaceHeader.ptr == nil || d.typ == typ || typ == nil {
   317  		// concrete type is empty interface
   318  		return d.decodeStreamEmptyInterface(s, depth, p)
   319  	}
   320  	if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr {
   321  		return d.decodeStreamEmptyInterface(s, depth, p)
   322  	}
   323  	if s.skipWhiteSpace() == 'n' {
   324  		if err := nullBytes(s); err != nil {
   325  			return err
   326  		}
   327  		*(*interface{})(p) = nil
   328  		return nil
   329  	}
   330  	decoder, err := CompileToGetDecoder(typ)
   331  	if err != nil {
   332  		return err
   333  	}
   334  	return decoder.DecodeStream(s, depth, ifaceHeader.ptr)
   335  }
   336  
   337  func (d *interfaceDecoder) errUnmarshalType(typ reflect.Type, offset int64) *errors.UnmarshalTypeError {
   338  	return &errors.UnmarshalTypeError{
   339  		Value:  typ.String(),
   340  		Type:   typ,
   341  		Offset: offset,
   342  		Struct: d.structName,
   343  		Field:  d.fieldName,
   344  	}
   345  }
   346  
   347  func (d *interfaceDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
   348  	buf := ctx.Buf
   349  	runtimeInterfaceValue := *(*interface{})(unsafe.Pointer(&emptyInterface{
   350  		typ: d.typ,
   351  		ptr: p,
   352  	}))
   353  	rv := reflect.ValueOf(runtimeInterfaceValue)
   354  	if rv.NumMethod() > 0 && rv.CanInterface() {
   355  		if u, ok := rv.Interface().(unmarshalerContext); ok {
   356  			return decodeUnmarshalerContext(ctx, buf, cursor, depth, u)
   357  		}
   358  		if u, ok := rv.Interface().(json.Unmarshaler); ok {
   359  			return decodeUnmarshaler(buf, cursor, depth, u)
   360  		}
   361  		if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
   362  			return decodeTextUnmarshaler(buf, cursor, depth, u, p)
   363  		}
   364  		cursor = skipWhiteSpace(buf, cursor)
   365  		if buf[cursor] == 'n' {
   366  			if err := validateNull(buf, cursor); err != nil {
   367  				return 0, err
   368  			}
   369  			cursor += 4
   370  			**(**interface{})(unsafe.Pointer(&p)) = nil
   371  			return cursor, nil
   372  		}
   373  		return 0, d.errUnmarshalType(rv.Type(), cursor)
   374  	}
   375  
   376  	iface := rv.Interface()
   377  	ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface))
   378  	typ := ifaceHeader.typ
   379  	if ifaceHeader.ptr == nil || d.typ == typ || typ == nil {
   380  		// concrete type is empty interface
   381  		return d.decodeEmptyInterface(ctx, cursor, depth, p)
   382  	}
   383  	if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr {
   384  		return d.decodeEmptyInterface(ctx, cursor, depth, p)
   385  	}
   386  	cursor = skipWhiteSpace(buf, cursor)
   387  	if buf[cursor] == 'n' {
   388  		if err := validateNull(buf, cursor); err != nil {
   389  			return 0, err
   390  		}
   391  		cursor += 4
   392  		**(**interface{})(unsafe.Pointer(&p)) = nil
   393  		return cursor, nil
   394  	}
   395  	decoder, err := CompileToGetDecoder(typ)
   396  	if err != nil {
   397  		return 0, err
   398  	}
   399  	return decoder.Decode(ctx, cursor, depth, ifaceHeader.ptr)
   400  }
   401  
   402  func (d *interfaceDecoder) decodeEmptyInterface(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
   403  	buf := ctx.Buf
   404  	cursor = skipWhiteSpace(buf, cursor)
   405  	switch buf[cursor] {
   406  	case '{':
   407  		var v map[string]interface{}
   408  		ptr := unsafe.Pointer(&v)
   409  		cursor, err := d.mapDecoder.Decode(ctx, cursor, depth, ptr)
   410  		if err != nil {
   411  			return 0, err
   412  		}
   413  		**(**interface{})(unsafe.Pointer(&p)) = v
   414  		return cursor, nil
   415  	case '[':
   416  		var v []interface{}
   417  		ptr := unsafe.Pointer(&v)
   418  		cursor, err := d.sliceDecoder.Decode(ctx, cursor, depth, ptr)
   419  		if err != nil {
   420  			return 0, err
   421  		}
   422  		**(**interface{})(unsafe.Pointer(&p)) = v
   423  		return cursor, nil
   424  	case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
   425  		return d.floatDecoder.Decode(ctx, cursor, depth, p)
   426  	case '"':
   427  		var v string
   428  		ptr := unsafe.Pointer(&v)
   429  		cursor, err := d.stringDecoder.Decode(ctx, cursor, depth, ptr)
   430  		if err != nil {
   431  			return 0, err
   432  		}
   433  		**(**interface{})(unsafe.Pointer(&p)) = v
   434  		return cursor, nil
   435  	case 't':
   436  		if err := validateTrue(buf, cursor); err != nil {
   437  			return 0, err
   438  		}
   439  		cursor += 4
   440  		**(**interface{})(unsafe.Pointer(&p)) = true
   441  		return cursor, nil
   442  	case 'f':
   443  		if err := validateFalse(buf, cursor); err != nil {
   444  			return 0, err
   445  		}
   446  		cursor += 5
   447  		**(**interface{})(unsafe.Pointer(&p)) = false
   448  		return cursor, nil
   449  	case 'n':
   450  		if err := validateNull(buf, cursor); err != nil {
   451  			return 0, err
   452  		}
   453  		cursor += 4
   454  		**(**interface{})(unsafe.Pointer(&p)) = nil
   455  		return cursor, nil
   456  	}
   457  	return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
   458  }