github.com/neatio-net/neatio@v1.7.3-0.20231114194659-f4d7a2226baa/chain/accounts/abi/reflect.go (about)

     1  package abi
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"strings"
     7  )
     8  
     9  func indirect(v reflect.Value) reflect.Value {
    10  	if v.Kind() == reflect.Ptr && v.Elem().Type() != derefbigT {
    11  		return indirect(v.Elem())
    12  	}
    13  	return v
    14  }
    15  
    16  func indirectInterfaceOrPtr(v reflect.Value) reflect.Value {
    17  	if (v.Kind() == reflect.Interface || v.Kind() == reflect.Ptr) && v.Elem().IsValid() {
    18  		return indirect(v.Elem())
    19  	}
    20  	return v
    21  }
    22  
    23  func reflectIntKindAndType(unsigned bool, size int) (reflect.Kind, reflect.Type) {
    24  	switch size {
    25  	case 8:
    26  		if unsigned {
    27  			return reflect.Uint8, uint8T
    28  		}
    29  		return reflect.Int8, int8T
    30  	case 16:
    31  		if unsigned {
    32  			return reflect.Uint16, uint16T
    33  		}
    34  		return reflect.Int16, int16T
    35  	case 32:
    36  		if unsigned {
    37  			return reflect.Uint32, uint32T
    38  		}
    39  		return reflect.Int32, int32T
    40  	case 64:
    41  		if unsigned {
    42  			return reflect.Uint64, uint64T
    43  		}
    44  		return reflect.Int64, int64T
    45  	}
    46  	return reflect.Ptr, bigT
    47  }
    48  
    49  func mustArrayToByteSlice(value reflect.Value) reflect.Value {
    50  	slice := reflect.MakeSlice(reflect.TypeOf([]byte{}), value.Len(), value.Len())
    51  	reflect.Copy(slice, value)
    52  	return slice
    53  }
    54  
    55  func set(dst, src reflect.Value) error {
    56  	dstType, srcType := dst.Type(), src.Type()
    57  	switch {
    58  	case dstType.Kind() == reflect.Interface && dst.Elem().IsValid():
    59  		return set(dst.Elem(), src)
    60  	case dstType.Kind() == reflect.Ptr && dstType.Elem() != derefbigT:
    61  		return set(dst.Elem(), src)
    62  	case srcType.AssignableTo(dstType) && dst.CanSet():
    63  		dst.Set(src)
    64  	case dstType.Kind() == reflect.Slice && srcType.Kind() == reflect.Slice:
    65  		return setSlice(dst, src)
    66  	default:
    67  		return fmt.Errorf("abi: cannot unmarshal %v in to %v", src.Type(), dst.Type())
    68  	}
    69  	return nil
    70  }
    71  
    72  func setSlice(dst, src reflect.Value) error {
    73  	slice := reflect.MakeSlice(dst.Type(), src.Len(), src.Len())
    74  	for i := 0; i < src.Len(); i++ {
    75  		v := src.Index(i)
    76  		reflect.Copy(slice.Index(i), v)
    77  	}
    78  
    79  	dst.Set(slice)
    80  	return nil
    81  }
    82  
    83  func requireAssignable(dst, src reflect.Value) error {
    84  	if dst.Kind() != reflect.Ptr && dst.Kind() != reflect.Interface {
    85  		return fmt.Errorf("abi: cannot unmarshal %v into %v", src.Type(), dst.Type())
    86  	}
    87  	return nil
    88  }
    89  
    90  func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind,
    91  	args Arguments) error {
    92  
    93  	switch k {
    94  	case reflect.Struct:
    95  	case reflect.Slice, reflect.Array:
    96  		if minLen := args.LengthNonIndexed(); v.Len() < minLen {
    97  			return fmt.Errorf("abi: insufficient number of elements in the list/array for unpack, want %d, got %d",
    98  				minLen, v.Len())
    99  		}
   100  	default:
   101  		return fmt.Errorf("abi: cannot unmarshal tuple into %v", t)
   102  	}
   103  	return nil
   104  }
   105  
   106  func mapArgNamesToStructFields(argNames []string, value reflect.Value) (map[string]string, error) {
   107  	typ := value.Type()
   108  
   109  	abi2struct := make(map[string]string)
   110  	struct2abi := make(map[string]string)
   111  
   112  	for i := 0; i < typ.NumField(); i++ {
   113  		structFieldName := typ.Field(i).Name
   114  
   115  		if structFieldName[:1] != strings.ToUpper(structFieldName[:1]) {
   116  			continue
   117  		}
   118  
   119  		var ok bool
   120  		var tagName string
   121  		if tagName, ok = typ.Field(i).Tag.Lookup("abi"); !ok {
   122  			continue
   123  		}
   124  
   125  		if tagName == "" {
   126  			return nil, fmt.Errorf("struct: abi tag in '%s' is empty", structFieldName)
   127  		}
   128  
   129  		found := false
   130  		for _, arg := range argNames {
   131  			if arg == tagName {
   132  				if abi2struct[arg] != "" {
   133  					return nil, fmt.Errorf("struct: abi tag in '%s' already mapped", structFieldName)
   134  				}
   135  
   136  				abi2struct[arg] = structFieldName
   137  				struct2abi[structFieldName] = arg
   138  				found = true
   139  			}
   140  		}
   141  
   142  		if !found {
   143  			return nil, fmt.Errorf("struct: abi tag '%s' defined but not found in abi", tagName)
   144  		}
   145  	}
   146  
   147  	for _, argName := range argNames {
   148  
   149  		structFieldName := ToCamelCase(argName)
   150  
   151  		if structFieldName == "" {
   152  			return nil, fmt.Errorf("abi: purely underscored output cannot unpack to struct")
   153  		}
   154  
   155  		if abi2struct[argName] != "" {
   156  			if abi2struct[argName] != structFieldName &&
   157  				struct2abi[structFieldName] == "" &&
   158  				value.FieldByName(structFieldName).IsValid() {
   159  				return nil, fmt.Errorf("abi: multiple variables maps to the same abi field '%s'", argName)
   160  			}
   161  			continue
   162  		}
   163  
   164  		if struct2abi[structFieldName] != "" {
   165  			return nil, fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", structFieldName)
   166  		}
   167  
   168  		if value.FieldByName(structFieldName).IsValid() {
   169  
   170  			abi2struct[argName] = structFieldName
   171  			struct2abi[structFieldName] = argName
   172  		} else {
   173  
   174  			struct2abi[structFieldName] = argName
   175  		}
   176  	}
   177  	return abi2struct, nil
   178  }