github.com/kaydxh/golang@v0.0.131/go/reflect/value.go (about) 1 /* 2 *Copyright (c) 2022, kaydxh 3 * 4 *Permission is hereby granted, free of charge, to any person obtaining a copy 5 *of this software and associated documentation files (the "Software"), to deal 6 *in the Software without restriction, including without limitation the rights 7 *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 *copies of the Software, and to permit persons to whom the Software is 9 *furnished to do so, subject to the following conditions: 10 * 11 *The above copyright notice and this permission notice shall be included in all 12 *copies or substantial portions of the Software. 13 * 14 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 *SOFTWARE. 21 */ 22 package reflect 23 24 import ( 25 "context" 26 "encoding/json" 27 "fmt" 28 "math" 29 "reflect" 30 "strings" 31 ) 32 33 var ( 34 typesMap = map[string]reflect.Type{ 35 // base types 36 "bool": reflect.TypeOf(true), 37 "int": reflect.TypeOf(int(1)), 38 "int8": reflect.TypeOf(int8(1)), 39 "int16": reflect.TypeOf(int16(1)), 40 "int32": reflect.TypeOf(int32(1)), 41 "int64": reflect.TypeOf(int64(1)), 42 "uint": reflect.TypeOf(uint(1)), 43 "uint8": reflect.TypeOf(uint8(1)), 44 "uint16": reflect.TypeOf(uint16(1)), 45 "uint32": reflect.TypeOf(uint32(1)), 46 "uint64": reflect.TypeOf(uint64(1)), 47 "float32": reflect.TypeOf(float32(0.5)), 48 "float64": reflect.TypeOf(float64(0.5)), 49 "string": reflect.TypeOf(string("")), 50 // slices 51 "[]bool": reflect.TypeOf(make([]bool, 0)), 52 "[]int": reflect.TypeOf(make([]int, 0)), 53 "[]int8": reflect.TypeOf(make([]int8, 0)), 54 "[]int16": reflect.TypeOf(make([]int16, 0)), 55 "[]int32": reflect.TypeOf(make([]int32, 0)), 56 "[]int64": reflect.TypeOf(make([]int64, 0)), 57 "[]uint": reflect.TypeOf(make([]uint, 0)), 58 "[]uint8": reflect.TypeOf(make([]uint8, 0)), 59 "[]uint16": reflect.TypeOf(make([]uint16, 0)), 60 "[]uint32": reflect.TypeOf(make([]uint32, 0)), 61 "[]uint64": reflect.TypeOf(make([]uint64, 0)), 62 "[]float32": reflect.TypeOf(make([]float32, 0)), 63 "[]float64": reflect.TypeOf(make([]float64, 0)), 64 "[]byte": reflect.TypeOf(make([]byte, 0)), 65 "[]string": reflect.TypeOf([]string{""}), 66 } 67 68 ctxType = reflect.TypeOf((*context.Context)(nil)).Elem() 69 70 typeConversionError = func(argValue interface{}, argTypeStr string) error { 71 return fmt.Errorf("%v is not %v", argValue, argTypeStr) 72 } 73 ) 74 75 // cmd/compile/internal/gc/dump.go 76 func IsZeroValue(v reflect.Value) bool { 77 if !v.IsValid() { 78 return true 79 } 80 81 switch v.Kind() { 82 case reflect.Bool: 83 return !v.Bool() 84 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 85 return v.Int() == 0 86 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 87 return v.Uint() == 0 88 case reflect.Float32, reflect.Float64: 89 return math.Float64bits(v.Float()) == 0 90 case reflect.Complex64, reflect.Complex128: 91 c := v.Complex() 92 return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0 93 case reflect.String: 94 return v.String() == "" 95 case reflect.Array: 96 for i := 0; i < v.Len(); i++ { 97 if !v.Index(i).IsZero() { 98 return false 99 } 100 } 101 return true 102 case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer: 103 return v.IsNil() 104 case reflect.Struct: 105 for i := 0; i < v.NumField(); i++ { 106 if !v.Field(i).IsZero() { 107 return false 108 } 109 } 110 return true 111 default: 112 } 113 114 return reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface()) 115 } 116 117 // ReflectValue converts interface{} to reflect.Value based on string type 118 func ReflectValue(valueType string, value interface{}) (reflect.Value, error) { 119 /* 120 if strings.HasPrefix(valueType, "[]") { 121 return reflectValues(valueType, value) 122 } 123 */ 124 125 return reflectValue(valueType, value) 126 } 127 128 // reflectValue converts interface{} to reflect.Value based on string type 129 // representing a base type (not a slice) 130 func reflectValue(valueType string, value interface{}) (reflect.Value, error) { 131 theType, ok := typesMap[valueType] 132 if !ok { 133 return reflect.Value{}, NewErrUnsupportedType(valueType) 134 } 135 theValue := reflect.New(theType) 136 137 // Booleans 138 if theType.String() == "bool" { 139 boolValue, err := getBoolValue(theType.String(), value) 140 if err != nil { 141 return reflect.Value{}, err 142 } 143 144 theValue.Elem().SetBool(boolValue) 145 return theValue.Elem(), nil 146 } 147 148 // Integers 149 if strings.HasPrefix(theType.String(), "int") { 150 intValue, err := getIntValue(theType.String(), value) 151 if err != nil { 152 return reflect.Value{}, err 153 } 154 155 theValue.Elem().SetInt(intValue) 156 return theValue.Elem(), err 157 } 158 159 // Unsigned integers 160 if strings.HasPrefix(theType.String(), "uint") { 161 uintValue, err := getUintValue(theType.String(), value) 162 if err != nil { 163 return reflect.Value{}, err 164 } 165 166 theValue.Elem().SetUint(uintValue) 167 return theValue.Elem(), err 168 } 169 170 // Floating point numbers 171 if strings.HasPrefix(theType.String(), "float") { 172 floatValue, err := getFloatValue(theType.String(), value) 173 if err != nil { 174 return reflect.Value{}, err 175 } 176 177 theValue.Elem().SetFloat(floatValue) 178 return theValue.Elem(), err 179 } 180 181 // Strings 182 if theType.String() == "string" { 183 stringValue, err := getStringValue(theType.String(), value) 184 if err != nil { 185 return reflect.Value{}, err 186 } 187 188 theValue.Elem().SetString(stringValue) 189 return theValue.Elem(), nil 190 } 191 192 return reflect.Value{}, NewErrUnsupportedType(valueType) 193 } 194 195 func getBoolValue(theType string, value interface{}) (bool, error) { 196 b, ok := value.(bool) 197 if !ok { 198 return false, typeConversionError(value, typesMap[theType].String()) 199 } 200 201 return b, nil 202 } 203 204 func getIntValue(theType string, value interface{}) (int64, error) { 205 // We use https://golang.org/pkg/encoding/json/#Decoder.UseNumber when unmarshaling signatures. 206 // This is because JSON only supports 64-bit floating point numbers and we could lose precision 207 // when converting from float64 to signed integer 208 if strings.HasPrefix(fmt.Sprintf("%T", value), "json.Number") { 209 n, ok := value.(json.Number) 210 if !ok { 211 return 0, typeConversionError(value, typesMap[theType].String()) 212 } 213 214 return n.Int64() 215 } 216 217 var n int64 218 switch value := value.(type) { 219 case int: 220 n = int64(value) 221 case int64: 222 n = value 223 case int32: 224 n = int64(value) 225 case int16: 226 n = int64(value) 227 case int8: 228 n = int64(value) 229 default: 230 fmt.Printf("value: %v\n", value) 231 return 0, typeConversionError(value, typesMap[theType].String()) 232 } 233 234 return n, nil 235 } 236 237 func getUintValue(theType string, value interface{}) (uint64, error) { 238 // We use https://golang.org/pkg/encoding/json/#Decoder.UseNumber when unmarshaling signatures. 239 // This is because JSON only supports 64-bit floating point numbers and we could lose precision 240 // when converting from float64 to unsigned integer 241 if strings.HasPrefix(fmt.Sprintf("%T", value), "json.Number") { 242 n, ok := value.(json.Number) 243 if !ok { 244 fmt.Printf("00000\n") 245 return 0, typeConversionError(value, typesMap[theType].String()) 246 } 247 248 intVal, err := n.Int64() 249 if err != nil { 250 return 0, err 251 } 252 253 return uint64(intVal), nil 254 } 255 256 var n uint64 257 switch value := value.(type) { 258 case uint: 259 n = uint64(value) 260 case uint64: 261 n = value 262 case uint32: 263 n = uint64(value) 264 case uint16: 265 n = uint64(value) 266 case uint8: 267 n = uint64(value) 268 default: 269 fmt.Printf("value: %v\n", value) 270 return 0, typeConversionError(value, typesMap[theType].String()) 271 } 272 return n, nil 273 } 274 275 func getFloatValue(theType string, value interface{}) (float64, error) { 276 // We use https://golang.org/pkg/encoding/json/#Decoder.UseNumber when unmarshaling signatures. 277 // This is because JSON only supports 64-bit floating point numbers and we could lose precision 278 if strings.HasPrefix(fmt.Sprintf("%T", value), "json.Number") { 279 n, ok := value.(json.Number) 280 if !ok { 281 return 0, typeConversionError(value, typesMap[theType].String()) 282 } 283 284 return n.Float64() 285 } 286 287 f, ok := value.(float64) 288 if !ok { 289 return 0, typeConversionError(value, typesMap[theType].String()) 290 } 291 292 return f, nil 293 } 294 295 func getStringValue(theType string, value interface{}) (string, error) { 296 s, ok := value.(string) 297 if !ok { 298 return "", typeConversionError(value, typesMap[theType].String()) 299 } 300 301 return s, nil 302 }