github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/thrift/generic/cast.go (about) 1 /** 2 * Copyright 2023 CloudWeGo Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package generic 18 19 import ( 20 "fmt" 21 // "unicode/utf8" 22 "unsafe" 23 24 "github.com/cloudwego/dynamicgo/internal/rt" 25 "github.com/cloudwego/dynamicgo/meta" 26 "github.com/cloudwego/dynamicgo/thrift" 27 ) 28 29 func (self Node) should(api string, t1 thrift.Type) string { 30 if self.t == thrift.STOP || self.t == thrift.ERROR { 31 return self.Error() 32 } 33 if self.t == t1 { 34 return "" 35 } 36 return fmt.Sprintf("API `%s` only supports %+v type", api, t1) 37 } 38 39 func (self Node) should2(api string, t1 thrift.Type, t2 thrift.Type) string { 40 if self.t == thrift.STOP || self.t == thrift.ERROR { 41 return self.Error() 42 } 43 if self.t == t1 || self.t == t2 { 44 return "" 45 } 46 return fmt.Sprintf("API `%s` only supports %s or %s type", api, t1, t2) 47 } 48 49 // Len returns the element count of container-kind type (LIST/SET/MAP) 50 func (self Node) Len() (int, error) { 51 if self.IsError() { 52 return 0, self 53 } 54 return self.len() 55 } 56 57 func (self Node) len() (int, error) { 58 switch self.t { 59 case thrift.LIST, thrift.SET: 60 b := rt.BytesFrom(unsafe.Pointer(uintptr(self.v)+uintptr(1)), 4, 4) 61 return int(thrift.BinaryEncoding{}.DecodeInt32(b)), nil 62 case thrift.MAP: 63 b := rt.BytesFrom(unsafe.Pointer(uintptr(self.v)+uintptr(2)), 4, 4) 64 return int(thrift.BinaryEncoding{}.DecodeInt32(b)), nil 65 default: 66 return -1, errNode(meta.ErrUnsupportedType, "", nil) 67 } 68 } 69 70 func (self Node) raw() []byte { 71 return rt.BytesFrom(self.v, self.l, self.l) 72 } 73 74 // Return its underlying raw data 75 func (self Node) Raw() []byte { 76 if self.Error() != "" { 77 return nil 78 } 79 return self.raw() 80 } 81 82 // Byte returns the byte value contained by a I8/BYTE node 83 func (self Node) Byte() (byte, error) { 84 if self.IsError() { 85 return 0, self 86 } 87 return self.byte() 88 } 89 90 func (self Node) byte() (byte, error) { 91 switch self.t { 92 case thrift.BYTE: 93 return byte(thrift.BinaryEncoding{}.DecodeByte(rt.BytesFrom(self.v, int(self.l), int(self.l)))), nil 94 default: 95 return 0, errNode(meta.ErrUnsupportedType, "", nil) 96 } 97 } 98 99 // Bool returns the bool value contained by a BOOL node 100 func (self Node) Bool() (bool, error) { 101 if self.IsError() { 102 return false, self 103 } 104 return self.bool() 105 } 106 107 func (self Node) bool() (bool, error) { 108 switch self.t { 109 case thrift.BOOL: 110 return thrift.BinaryEncoding{}.DecodeBool(rt.BytesFrom(self.v, int(self.l), int(self.l))), nil 111 default: 112 return false, errNode(meta.ErrUnsupportedType, "", nil) 113 } 114 } 115 116 // Int returns the int value contaned by a I8/I16/I32/I64 node 117 func (self Node) Int() (int, error) { 118 if self.IsError() { 119 return 0, self 120 } 121 return self.int() 122 } 123 124 func (self Node) int() (int, error) { 125 buf := rt.BytesFrom(self.v, int(self.l), int(self.l)) 126 switch self.t { 127 case thrift.I08: 128 return int(thrift.BinaryEncoding{}.DecodeByte(buf)), nil 129 case thrift.I16: 130 return int(thrift.BinaryEncoding{}.DecodeInt16(buf)), nil 131 case thrift.I32: 132 return int(thrift.BinaryEncoding{}.DecodeInt32(buf)), nil 133 case thrift.I64: 134 return int(thrift.BinaryEncoding{}.DecodeInt64(buf)), nil 135 default: 136 return 0, errNode(meta.ErrUnsupportedType, "", nil) 137 } 138 } 139 140 // Float64 returns the float64 value contained by a DOUBLE node 141 func (self Node) Float64() (float64, error) { 142 if self.IsError() { 143 return 0, self 144 } 145 return self.float64() 146 } 147 148 func (self Node) float64() (float64, error) { 149 switch self.t { 150 case thrift.DOUBLE: 151 return thrift.BinaryEncoding{}.DecodeDouble(rt.BytesFrom(self.v, int(self.l), int(self.l))), nil 152 default: 153 return 0, errNode(meta.ErrUnsupportedType, "", nil) 154 } 155 } 156 157 // String returns the string value contianed by a STRING node 158 func (self Node) String() (string, error) { 159 if self.IsError() { 160 return "", self 161 } 162 return self.string() 163 } 164 165 func (self Node) string() (string, error) { 166 switch self.t { 167 case thrift.STRING: 168 str := thrift.BinaryEncoding{}.DecodeString(rt.BytesFrom(self.v, int(self.l), int(self.l))) 169 // if self.d.IsBinary() { 170 // if !utf8.Valid(rt.Str2Mem(str)) { 171 // return "", errNode(meta.ErrInvalidParam, "invalid utf8 string", nil) 172 // } 173 // } 174 return str, nil 175 default: 176 return "", errNode(meta.ErrUnsupportedType, "", nil) 177 } 178 } 179 180 // Binary returns the bytes value contained by a BINARY node 181 func (self Node) Binary() ([]byte, error) { 182 if self.IsError() { 183 return nil, self 184 } 185 return self.binary() 186 } 187 188 func (self Node) binary() ([]byte, error) { 189 switch self.t { 190 case thrift.STRING: 191 return thrift.BinaryEncoding{}.DecodeBytes(rt.BytesFrom(self.v, int(self.l), int(self.l))), nil 192 default: 193 return nil, errNode(meta.ErrUnsupportedType, "", nil) 194 } 195 } 196 197 // List returns interface elements contained by a LIST/SET node 198 func (self Node) List(opts *Options) ([]interface{}, error) { 199 if self.IsError() { 200 return nil, self 201 } 202 if err := self.should2("List", thrift.LIST, thrift.SET); err != "" { 203 return nil, errNode(meta.ErrUnsupportedType, err, nil) 204 } 205 206 it := self.iterElems() 207 if it.Err != nil { 208 return nil, it.Err 209 } 210 ret := make([]interface{}, 0, it.Size()) 211 for it.HasNext() { 212 s, e := it.Next(opts.UseNativeSkip) 213 if it.Err != nil { 214 return nil, it.Err 215 } 216 v := self.slice(s, e, self.et) 217 vv, err := v.Interface(opts) 218 if err != nil { 219 return ret, err 220 } 221 ret = append(ret, vv) 222 } 223 return ret, it.Err 224 } 225 226 // StrMap returns the string keys and interface elements contained by a MAP<STRING,XX> node 227 func (self Node) StrMap(opts *Options) (map[string]interface{}, error) { 228 if self.IsError() { 229 return nil, self 230 } 231 if err := self.should("StrMap", thrift.MAP); err != "" { 232 return nil, errNode(meta.ErrUnsupportedType, err, nil) 233 } 234 it := self.iterPairs() 235 if it.Err != nil { 236 return nil, it.Err 237 } 238 if self.kt != thrift.STRING { 239 return nil, errNode(meta.ErrUnsupportedType, "key type must by STRING", nil) 240 } 241 ret := make(map[string]interface{}, it.Size()) 242 for it.HasNext() { 243 _, ks, s, e := it.NextStr(opts.UseNativeSkip) 244 if it.Err != nil { 245 return nil, it.Err 246 } 247 v := self.slice(s, e, self.et) 248 vv, err := v.Interface(opts) 249 if err != nil { 250 return ret, err 251 } 252 ret[ks] = vv 253 } 254 return ret, it.Err 255 } 256 257 // StrMap returns the integer keys and interface elements contained by a MAP<I8|I16|I32|I64,XX> node 258 func (self Node) IntMap(opts *Options) (map[int]interface{}, error) { 259 if self.IsError() { 260 return nil, self 261 } 262 if err := self.should("IntMap", thrift.MAP); err != "" { 263 return nil, errNode(meta.ErrUnsupportedType, err, nil) 264 } 265 if !self.kt.IsInt() { 266 return nil, errNode(meta.ErrUnsupportedType, "key must be INT type", nil) 267 } 268 it := self.iterPairs() 269 if it.Err != nil { 270 return nil, it.Err 271 } 272 ret := make(map[int]interface{}, it.Size()) 273 for it.HasNext() { 274 _, ks, s, e := it.NextInt(opts.UseNativeSkip) 275 if it.Err != nil { 276 return nil, it.Err 277 } 278 v := self.slice(s, e, self.et) 279 vv, err := v.Interface(opts) 280 if err != nil { 281 return ret, err 282 } 283 ret[ks] = vv 284 } 285 return ret, it.Err 286 } 287 288 // InterfaceMap returns the interface keys and interface elements contained by a MAP node. 289 // If the key type is complex (LIST/SET/MAP/STRUCT), 290 // it will be stored using its pointer since its value are not supported by Go 291 func (self Node) InterfaceMap(opts *Options) (map[interface{}]interface{}, error) { 292 if self.IsError() { 293 return nil, self 294 } 295 if err := self.should("InterfaceMap", thrift.MAP); err != "" { 296 return nil, errNode(meta.ErrUnsupportedType, err, nil) 297 } 298 // if self.kt.IsInt() || self.kt == thrift.STRING { 299 // return nil, errNode(meta.ErrUnsupportedType, "key must be non-integer-nor-string type", nil) 300 // } 301 it := self.iterPairs() 302 if it.Err != nil { 303 return nil, it.Err 304 } 305 ret := make(map[interface{}]interface{}, it.Size()) 306 for it.HasNext() { 307 _, ks, s, e := it.NextBin(opts.UseNativeSkip) 308 if it.Err != nil { 309 return nil, it.Err 310 } 311 k := NewNode(self.kt, ks) 312 kv, err := k.Interface(opts) 313 if err != nil { 314 return ret, err 315 } 316 v := self.slice(s, e, self.et) 317 vv, err := v.Interface(opts) 318 if err != nil { 319 return ret, err 320 } 321 switch x := kv.(type) { 322 case map[string]interface{}: 323 ret[&x] = vv 324 case map[int]interface{}: 325 ret[&x] = vv 326 case map[interface{}]interface{}: 327 ret[&x] = vv 328 case []interface{}: 329 ret[&x] = vv 330 case map[thrift.FieldID]interface{}: 331 ret[&x] = vv 332 default: 333 ret[kv] = vv 334 } 335 } 336 return ret, it.Err 337 } 338 339 // Interface returns the go interface value contained by a node. 340 // If the node is a STRUCT, it will return a map[thrift.FieldID]interface{} 341 // If it is a map, it will return map[int|string|interface{}]interface{}, which depends on the key type 342 func (self Node) Interface(opts *Options) (interface{}, error) { 343 switch self.t { 344 case thrift.ERROR: 345 return nil, self 346 case thrift.BOOL: 347 return self.bool() 348 case thrift.I08, thrift.I16, thrift.I32, thrift.I64: 349 return self.int() 350 case thrift.DOUBLE: 351 return self.float64() 352 case thrift.STRING: 353 if opts.CastStringAsBinary { 354 return self.binary() 355 } 356 return self.string() 357 case thrift.LIST, thrift.SET: 358 return self.List(opts) 359 case thrift.MAP: 360 if kt := self.kt; kt == thrift.STRING { 361 return self.StrMap(opts) 362 } else if kt.IsInt() { 363 return self.IntMap(opts) 364 } else { 365 return self.InterfaceMap(opts) 366 } 367 case thrift.STRUCT: 368 // if opts.StructByName { 369 // it := self.iterFields() 370 // if it.Err != nil { 371 // return nil, it.Err 372 // } 373 // ret := make(map[string]interface{}, defaultNodeSliceCap) 374 // for it.HasNext() { 375 // id, t, s, e := it.Next(opts.UseNativeSkip) 376 // if it.Err != nil { 377 // return nil, it.Err 378 // } 379 // f := self.d.Struct().FieldById(id) 380 // if f == nil { 381 // if opts.DisallowUnknow { 382 // return nil, errNode(meta.ErrUnknownField, fmt.Sprintf("unknow field %d", id), nil) 383 // } 384 // continue 385 // } 386 // if f.Type().Type() != t { 387 // return nil, errNode(meta.ErrDismatchType, "", nil) 388 // } 389 // v := self.slice(s, e, f.Type()) 390 // vv, err := v.Interface(opts) 391 // if err != nil { 392 // return ret, err 393 // } 394 // ret[f.Name()] = vv 395 // } 396 // return ret, it.Err 397 // } else { 398 it := self.iterFields() 399 if it.Err != nil { 400 return nil, it.Err 401 } 402 var ret1 map[thrift.FieldID]interface{} 403 var ret2 map[int]interface{} 404 if opts.MapStructById { 405 ret1 = make(map[thrift.FieldID]interface{}, DefaultNodeSliceCap) 406 } else { 407 ret2 = make(map[int]interface{}, DefaultNodeSliceCap) 408 } 409 for it.HasNext() { 410 id, t, s, e := it.Next(opts.UseNativeSkip) 411 if it.Err != nil { 412 return nil, it.Err 413 } 414 // f := self.d.Struct().FieldById(id) 415 // if f == nil { 416 // if opts.DisallowUnknow { 417 // return nil, errNode(meta.ErrUnknownField, fmt.Sprintf("unknow field %d", id), nil) 418 // } 419 // continue 420 // } 421 // if f.Type().Type() != t { 422 // return nil, errNode(meta.ErrDismatchType, "", nil) 423 // } 424 v := self.slice(s, e, t) 425 vv, err := v.Interface(opts) 426 if err != nil { 427 return nil, err 428 } 429 if opts.MapStructById { 430 ret1[thrift.FieldID(id)] = vv 431 } else { 432 ret2[int(id)] = vv 433 } 434 } 435 if opts.MapStructById { 436 return ret1, it.Err 437 } else { 438 return ret2, it.Err 439 } 440 // } 441 default: 442 return 0, errNode(meta.ErrUnsupportedType, "", nil) 443 } 444 }