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 }