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