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  }