mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-03 17:52:24 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			251 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			251 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package msgpack
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding"
 | 
						|
	"errors"
 | 
						|
	"fmt"
 | 
						|
	"reflect"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	interfaceType = reflect.TypeOf((*interface{})(nil)).Elem()
 | 
						|
	stringType    = reflect.TypeOf((*string)(nil)).Elem()
 | 
						|
	boolType      = reflect.TypeOf((*bool)(nil)).Elem()
 | 
						|
)
 | 
						|
 | 
						|
var valueDecoders []decoderFunc
 | 
						|
 | 
						|
//nolint:gochecknoinits
 | 
						|
func init() {
 | 
						|
	valueDecoders = []decoderFunc{
 | 
						|
		reflect.Bool:          decodeBoolValue,
 | 
						|
		reflect.Int:           decodeInt64Value,
 | 
						|
		reflect.Int8:          decodeInt64Value,
 | 
						|
		reflect.Int16:         decodeInt64Value,
 | 
						|
		reflect.Int32:         decodeInt64Value,
 | 
						|
		reflect.Int64:         decodeInt64Value,
 | 
						|
		reflect.Uint:          decodeUint64Value,
 | 
						|
		reflect.Uint8:         decodeUint64Value,
 | 
						|
		reflect.Uint16:        decodeUint64Value,
 | 
						|
		reflect.Uint32:        decodeUint64Value,
 | 
						|
		reflect.Uint64:        decodeUint64Value,
 | 
						|
		reflect.Float32:       decodeFloat32Value,
 | 
						|
		reflect.Float64:       decodeFloat64Value,
 | 
						|
		reflect.Complex64:     decodeUnsupportedValue,
 | 
						|
		reflect.Complex128:    decodeUnsupportedValue,
 | 
						|
		reflect.Array:         decodeArrayValue,
 | 
						|
		reflect.Chan:          decodeUnsupportedValue,
 | 
						|
		reflect.Func:          decodeUnsupportedValue,
 | 
						|
		reflect.Interface:     decodeInterfaceValue,
 | 
						|
		reflect.Map:           decodeMapValue,
 | 
						|
		reflect.Ptr:           decodeUnsupportedValue,
 | 
						|
		reflect.Slice:         decodeSliceValue,
 | 
						|
		reflect.String:        decodeStringValue,
 | 
						|
		reflect.Struct:        decodeStructValue,
 | 
						|
		reflect.UnsafePointer: decodeUnsupportedValue,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func getDecoder(typ reflect.Type) decoderFunc {
 | 
						|
	if v, ok := typeDecMap.Load(typ); ok {
 | 
						|
		return v.(decoderFunc)
 | 
						|
	}
 | 
						|
	fn := _getDecoder(typ)
 | 
						|
	typeDecMap.Store(typ, fn)
 | 
						|
	return fn
 | 
						|
}
 | 
						|
 | 
						|
func _getDecoder(typ reflect.Type) decoderFunc {
 | 
						|
	kind := typ.Kind()
 | 
						|
 | 
						|
	if kind == reflect.Ptr {
 | 
						|
		if _, ok := typeDecMap.Load(typ.Elem()); ok {
 | 
						|
			return ptrValueDecoder(typ)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if typ.Implements(customDecoderType) {
 | 
						|
		return nilAwareDecoder(typ, decodeCustomValue)
 | 
						|
	}
 | 
						|
	if typ.Implements(unmarshalerType) {
 | 
						|
		return nilAwareDecoder(typ, unmarshalValue)
 | 
						|
	}
 | 
						|
	if typ.Implements(binaryUnmarshalerType) {
 | 
						|
		return nilAwareDecoder(typ, unmarshalBinaryValue)
 | 
						|
	}
 | 
						|
	if typ.Implements(textUnmarshalerType) {
 | 
						|
		return nilAwareDecoder(typ, unmarshalTextValue)
 | 
						|
	}
 | 
						|
 | 
						|
	// Addressable struct field value.
 | 
						|
	if kind != reflect.Ptr {
 | 
						|
		ptr := reflect.PtrTo(typ)
 | 
						|
		if ptr.Implements(customDecoderType) {
 | 
						|
			return addrDecoder(nilAwareDecoder(typ, decodeCustomValue))
 | 
						|
		}
 | 
						|
		if ptr.Implements(unmarshalerType) {
 | 
						|
			return addrDecoder(nilAwareDecoder(typ, unmarshalValue))
 | 
						|
		}
 | 
						|
		if ptr.Implements(binaryUnmarshalerType) {
 | 
						|
			return addrDecoder(nilAwareDecoder(typ, unmarshalBinaryValue))
 | 
						|
		}
 | 
						|
		if ptr.Implements(textUnmarshalerType) {
 | 
						|
			return addrDecoder(nilAwareDecoder(typ, unmarshalTextValue))
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	switch kind {
 | 
						|
	case reflect.Ptr:
 | 
						|
		return ptrValueDecoder(typ)
 | 
						|
	case reflect.Slice:
 | 
						|
		elem := typ.Elem()
 | 
						|
		if elem.Kind() == reflect.Uint8 {
 | 
						|
			return decodeBytesValue
 | 
						|
		}
 | 
						|
		if elem == stringType {
 | 
						|
			return decodeStringSliceValue
 | 
						|
		}
 | 
						|
	case reflect.Array:
 | 
						|
		if typ.Elem().Kind() == reflect.Uint8 {
 | 
						|
			return decodeByteArrayValue
 | 
						|
		}
 | 
						|
	case reflect.Map:
 | 
						|
		if typ.Key() == stringType {
 | 
						|
			switch typ.Elem() {
 | 
						|
			case stringType:
 | 
						|
				return decodeMapStringStringValue
 | 
						|
			case interfaceType:
 | 
						|
				return decodeMapStringInterfaceValue
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return valueDecoders[kind]
 | 
						|
}
 | 
						|
 | 
						|
func ptrValueDecoder(typ reflect.Type) decoderFunc {
 | 
						|
	decoder := getDecoder(typ.Elem())
 | 
						|
	return func(d *Decoder, v reflect.Value) error {
 | 
						|
		if d.hasNilCode() {
 | 
						|
			if !v.IsNil() {
 | 
						|
				v.Set(d.newValue(typ).Elem())
 | 
						|
			}
 | 
						|
			return d.DecodeNil()
 | 
						|
		}
 | 
						|
		if v.IsNil() {
 | 
						|
			v.Set(d.newValue(typ.Elem()))
 | 
						|
		}
 | 
						|
		return decoder(d, v.Elem())
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func addrDecoder(fn decoderFunc) decoderFunc {
 | 
						|
	return func(d *Decoder, v reflect.Value) error {
 | 
						|
		if !v.CanAddr() {
 | 
						|
			return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface())
 | 
						|
		}
 | 
						|
		return fn(d, v.Addr())
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func nilAwareDecoder(typ reflect.Type, fn decoderFunc) decoderFunc {
 | 
						|
	if nilable(typ.Kind()) {
 | 
						|
		return func(d *Decoder, v reflect.Value) error {
 | 
						|
			if d.hasNilCode() {
 | 
						|
				return d.decodeNilValue(v)
 | 
						|
			}
 | 
						|
			if v.IsNil() {
 | 
						|
				v.Set(d.newValue(typ.Elem()))
 | 
						|
			}
 | 
						|
			return fn(d, v)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return func(d *Decoder, v reflect.Value) error {
 | 
						|
		if d.hasNilCode() {
 | 
						|
			return d.decodeNilValue(v)
 | 
						|
		}
 | 
						|
		return fn(d, v)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func decodeBoolValue(d *Decoder, v reflect.Value) error {
 | 
						|
	flag, err := d.DecodeBool()
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	v.SetBool(flag)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func decodeInterfaceValue(d *Decoder, v reflect.Value) error {
 | 
						|
	if v.IsNil() {
 | 
						|
		return d.interfaceValue(v)
 | 
						|
	}
 | 
						|
	return d.DecodeValue(v.Elem())
 | 
						|
}
 | 
						|
 | 
						|
func (d *Decoder) interfaceValue(v reflect.Value) error {
 | 
						|
	vv, err := d.decodeInterfaceCond()
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	if vv != nil {
 | 
						|
		if v.Type() == errorType {
 | 
						|
			if vv, ok := vv.(string); ok {
 | 
						|
				v.Set(reflect.ValueOf(errors.New(vv)))
 | 
						|
				return nil
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		v.Set(reflect.ValueOf(vv))
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func decodeUnsupportedValue(d *Decoder, v reflect.Value) error {
 | 
						|
	return fmt.Errorf("msgpack: Decode(unsupported %s)", v.Type())
 | 
						|
}
 | 
						|
 | 
						|
//------------------------------------------------------------------------------
 | 
						|
 | 
						|
func decodeCustomValue(d *Decoder, v reflect.Value) error {
 | 
						|
	decoder := v.Interface().(CustomDecoder)
 | 
						|
	return decoder.DecodeMsgpack(d)
 | 
						|
}
 | 
						|
 | 
						|
func unmarshalValue(d *Decoder, v reflect.Value) error {
 | 
						|
	var b []byte
 | 
						|
 | 
						|
	d.rec = make([]byte, 0, 64)
 | 
						|
	if err := d.Skip(); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	b = d.rec
 | 
						|
	d.rec = nil
 | 
						|
 | 
						|
	unmarshaler := v.Interface().(Unmarshaler)
 | 
						|
	return unmarshaler.UnmarshalMsgpack(b)
 | 
						|
}
 | 
						|
 | 
						|
func unmarshalBinaryValue(d *Decoder, v reflect.Value) error {
 | 
						|
	data, err := d.DecodeBytes()
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	unmarshaler := v.Interface().(encoding.BinaryUnmarshaler)
 | 
						|
	return unmarshaler.UnmarshalBinary(data)
 | 
						|
}
 | 
						|
 | 
						|
func unmarshalTextValue(d *Decoder, v reflect.Value) error {
 | 
						|
	data, err := d.DecodeBytes()
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	unmarshaler := v.Interface().(encoding.TextUnmarshaler)
 | 
						|
	return unmarshaler.UnmarshalText(data)
 | 
						|
}
 |