gtsocial-umbx

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

interface.go (13699B)


      1 package decoder
      2 
      3 import (
      4 	"bytes"
      5 	"encoding"
      6 	"encoding/json"
      7 	"reflect"
      8 	"unsafe"
      9 
     10 	"github.com/goccy/go-json/internal/errors"
     11 	"github.com/goccy/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 }