gtsocial-umbx

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

decode_value.go (5951B)


      1 package msgpack
      2 
      3 import (
      4 	"encoding"
      5 	"errors"
      6 	"fmt"
      7 	"reflect"
      8 )
      9 
     10 var (
     11 	interfaceType = reflect.TypeOf((*interface{})(nil)).Elem()
     12 	stringType    = reflect.TypeOf((*string)(nil)).Elem()
     13 )
     14 
     15 var valueDecoders []decoderFunc
     16 
     17 //nolint:gochecknoinits
     18 func init() {
     19 	valueDecoders = []decoderFunc{
     20 		reflect.Bool:          decodeBoolValue,
     21 		reflect.Int:           decodeInt64Value,
     22 		reflect.Int8:          decodeInt64Value,
     23 		reflect.Int16:         decodeInt64Value,
     24 		reflect.Int32:         decodeInt64Value,
     25 		reflect.Int64:         decodeInt64Value,
     26 		reflect.Uint:          decodeUint64Value,
     27 		reflect.Uint8:         decodeUint64Value,
     28 		reflect.Uint16:        decodeUint64Value,
     29 		reflect.Uint32:        decodeUint64Value,
     30 		reflect.Uint64:        decodeUint64Value,
     31 		reflect.Float32:       decodeFloat32Value,
     32 		reflect.Float64:       decodeFloat64Value,
     33 		reflect.Complex64:     decodeUnsupportedValue,
     34 		reflect.Complex128:    decodeUnsupportedValue,
     35 		reflect.Array:         decodeArrayValue,
     36 		reflect.Chan:          decodeUnsupportedValue,
     37 		reflect.Func:          decodeUnsupportedValue,
     38 		reflect.Interface:     decodeInterfaceValue,
     39 		reflect.Map:           decodeMapValue,
     40 		reflect.Ptr:           decodeUnsupportedValue,
     41 		reflect.Slice:         decodeSliceValue,
     42 		reflect.String:        decodeStringValue,
     43 		reflect.Struct:        decodeStructValue,
     44 		reflect.UnsafePointer: decodeUnsupportedValue,
     45 	}
     46 }
     47 
     48 func getDecoder(typ reflect.Type) decoderFunc {
     49 	if v, ok := typeDecMap.Load(typ); ok {
     50 		return v.(decoderFunc)
     51 	}
     52 	fn := _getDecoder(typ)
     53 	typeDecMap.Store(typ, fn)
     54 	return fn
     55 }
     56 
     57 func _getDecoder(typ reflect.Type) decoderFunc {
     58 	kind := typ.Kind()
     59 
     60 	if kind == reflect.Ptr {
     61 		if _, ok := typeDecMap.Load(typ.Elem()); ok {
     62 			return ptrValueDecoder(typ)
     63 		}
     64 	}
     65 
     66 	if typ.Implements(customDecoderType) {
     67 		return nilAwareDecoder(typ, decodeCustomValue)
     68 	}
     69 	if typ.Implements(unmarshalerType) {
     70 		return nilAwareDecoder(typ, unmarshalValue)
     71 	}
     72 	if typ.Implements(binaryUnmarshalerType) {
     73 		return nilAwareDecoder(typ, unmarshalBinaryValue)
     74 	}
     75 	if typ.Implements(textUnmarshalerType) {
     76 		return nilAwareDecoder(typ, unmarshalTextValue)
     77 	}
     78 
     79 	// Addressable struct field value.
     80 	if kind != reflect.Ptr {
     81 		ptr := reflect.PtrTo(typ)
     82 		if ptr.Implements(customDecoderType) {
     83 			return addrDecoder(nilAwareDecoder(typ, decodeCustomValue))
     84 		}
     85 		if ptr.Implements(unmarshalerType) {
     86 			return addrDecoder(nilAwareDecoder(typ, unmarshalValue))
     87 		}
     88 		if ptr.Implements(binaryUnmarshalerType) {
     89 			return addrDecoder(nilAwareDecoder(typ, unmarshalBinaryValue))
     90 		}
     91 		if ptr.Implements(textUnmarshalerType) {
     92 			return addrDecoder(nilAwareDecoder(typ, unmarshalTextValue))
     93 		}
     94 	}
     95 
     96 	switch kind {
     97 	case reflect.Ptr:
     98 		return ptrValueDecoder(typ)
     99 	case reflect.Slice:
    100 		elem := typ.Elem()
    101 		if elem.Kind() == reflect.Uint8 {
    102 			return decodeBytesValue
    103 		}
    104 		if elem == stringType {
    105 			return decodeStringSliceValue
    106 		}
    107 	case reflect.Array:
    108 		if typ.Elem().Kind() == reflect.Uint8 {
    109 			return decodeByteArrayValue
    110 		}
    111 	case reflect.Map:
    112 		if typ.Key() == stringType {
    113 			switch typ.Elem() {
    114 			case stringType:
    115 				return decodeMapStringStringValue
    116 			case interfaceType:
    117 				return decodeMapStringInterfaceValue
    118 			}
    119 		}
    120 	}
    121 
    122 	return valueDecoders[kind]
    123 }
    124 
    125 func ptrValueDecoder(typ reflect.Type) decoderFunc {
    126 	decoder := getDecoder(typ.Elem())
    127 	return func(d *Decoder, v reflect.Value) error {
    128 		if d.hasNilCode() {
    129 			if !v.IsNil() {
    130 				v.Set(reflect.Zero(v.Type()))
    131 			}
    132 			return d.DecodeNil()
    133 		}
    134 		if v.IsNil() {
    135 			v.Set(reflect.New(v.Type().Elem()))
    136 		}
    137 		return decoder(d, v.Elem())
    138 	}
    139 }
    140 
    141 func addrDecoder(fn decoderFunc) decoderFunc {
    142 	return func(d *Decoder, v reflect.Value) error {
    143 		if !v.CanAddr() {
    144 			return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface())
    145 		}
    146 		return fn(d, v.Addr())
    147 	}
    148 }
    149 
    150 func nilAwareDecoder(typ reflect.Type, fn decoderFunc) decoderFunc {
    151 	if nilable(typ.Kind()) {
    152 		return func(d *Decoder, v reflect.Value) error {
    153 			if d.hasNilCode() {
    154 				return d.decodeNilValue(v)
    155 			}
    156 			if v.IsNil() {
    157 				v.Set(reflect.New(v.Type().Elem()))
    158 			}
    159 			return fn(d, v)
    160 		}
    161 	}
    162 
    163 	return func(d *Decoder, v reflect.Value) error {
    164 		if d.hasNilCode() {
    165 			return d.decodeNilValue(v)
    166 		}
    167 		return fn(d, v)
    168 	}
    169 }
    170 
    171 func decodeBoolValue(d *Decoder, v reflect.Value) error {
    172 	flag, err := d.DecodeBool()
    173 	if err != nil {
    174 		return err
    175 	}
    176 	v.SetBool(flag)
    177 	return nil
    178 }
    179 
    180 func decodeInterfaceValue(d *Decoder, v reflect.Value) error {
    181 	if v.IsNil() {
    182 		return d.interfaceValue(v)
    183 	}
    184 	return d.DecodeValue(v.Elem())
    185 }
    186 
    187 func (d *Decoder) interfaceValue(v reflect.Value) error {
    188 	vv, err := d.decodeInterfaceCond()
    189 	if err != nil {
    190 		return err
    191 	}
    192 
    193 	if vv != nil {
    194 		if v.Type() == errorType {
    195 			if vv, ok := vv.(string); ok {
    196 				v.Set(reflect.ValueOf(errors.New(vv)))
    197 				return nil
    198 			}
    199 		}
    200 
    201 		v.Set(reflect.ValueOf(vv))
    202 	}
    203 
    204 	return nil
    205 }
    206 
    207 func decodeUnsupportedValue(d *Decoder, v reflect.Value) error {
    208 	return fmt.Errorf("msgpack: Decode(unsupported %s)", v.Type())
    209 }
    210 
    211 //------------------------------------------------------------------------------
    212 
    213 func decodeCustomValue(d *Decoder, v reflect.Value) error {
    214 	decoder := v.Interface().(CustomDecoder)
    215 	return decoder.DecodeMsgpack(d)
    216 }
    217 
    218 func unmarshalValue(d *Decoder, v reflect.Value) error {
    219 	var b []byte
    220 
    221 	d.rec = make([]byte, 0, 64)
    222 	if err := d.Skip(); err != nil {
    223 		return err
    224 	}
    225 	b = d.rec
    226 	d.rec = nil
    227 
    228 	unmarshaler := v.Interface().(Unmarshaler)
    229 	return unmarshaler.UnmarshalMsgpack(b)
    230 }
    231 
    232 func unmarshalBinaryValue(d *Decoder, v reflect.Value) error {
    233 	data, err := d.DecodeBytes()
    234 	if err != nil {
    235 		return err
    236 	}
    237 
    238 	unmarshaler := v.Interface().(encoding.BinaryUnmarshaler)
    239 	return unmarshaler.UnmarshalBinary(data)
    240 }
    241 
    242 func unmarshalTextValue(d *Decoder, v reflect.Value) error {
    243 	data, err := d.DecodeBytes()
    244 	if err != nil {
    245 		return err
    246 	}
    247 
    248 	unmarshaler := v.Interface().(encoding.TextUnmarshaler)
    249 	return unmarshaler.UnmarshalText(data)
    250 }