github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/accounts/abi/reflect.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:26</date>
    10  //</624342583904047104>
    11  
    12  
    13  package abi
    14  
    15  import (
    16  	"fmt"
    17  	"reflect"
    18  	"strings"
    19  )
    20  
    21  //间接递归地取消对值的引用,直到它得到值为止
    22  //或者找到一个大的.int
    23  func indirect(v reflect.Value) reflect.Value {
    24  	if v.Kind() == reflect.Ptr && v.Elem().Type() != derefbigT {
    25  		return indirect(v.Elem())
    26  	}
    27  	return v
    28  }
    29  
    30  //ReflectIntKind返回使用给定大小和
    31  //不拘一格
    32  func reflectIntKindAndType(unsigned bool, size int) (reflect.Kind, reflect.Type) {
    33  	switch size {
    34  	case 8:
    35  		if unsigned {
    36  			return reflect.Uint8, uint8T
    37  		}
    38  		return reflect.Int8, int8T
    39  	case 16:
    40  		if unsigned {
    41  			return reflect.Uint16, uint16T
    42  		}
    43  		return reflect.Int16, int16T
    44  	case 32:
    45  		if unsigned {
    46  			return reflect.Uint32, uint32T
    47  		}
    48  		return reflect.Int32, int32T
    49  	case 64:
    50  		if unsigned {
    51  			return reflect.Uint64, uint64T
    52  		}
    53  		return reflect.Int64, int64T
    54  	}
    55  	return reflect.Ptr, bigT
    56  }
    57  
    58  //mustArrayToBytesSlice创建与值大小完全相同的新字节片
    59  //并将值中的字节复制到新切片。
    60  func mustArrayToByteSlice(value reflect.Value) reflect.Value {
    61  	slice := reflect.MakeSlice(reflect.TypeOf([]byte{}), value.Len(), value.Len())
    62  	reflect.Copy(slice, value)
    63  	return slice
    64  }
    65  
    66  //设置尝试通过设置、复制或其他方式将SRC分配给DST。
    67  //
    68  //当涉及到任务时,set要宽松一点,而不是强制
    69  //严格的规则集为bare`reflect`的规则集。
    70  func set(dst, src reflect.Value, output Argument) error {
    71  	dstType := dst.Type()
    72  	srcType := src.Type()
    73  	switch {
    74  	case dstType.AssignableTo(srcType):
    75  		dst.Set(src)
    76  	case dstType.Kind() == reflect.Interface:
    77  		dst.Set(src)
    78  	case dstType.Kind() == reflect.Ptr:
    79  		return set(dst.Elem(), src, output)
    80  	default:
    81  		return fmt.Errorf("abi: cannot unmarshal %v in to %v", src.Type(), dst.Type())
    82  	}
    83  	return nil
    84  }
    85  
    86  //RequiresSignable确保“dest”是指针,而不是接口。
    87  func requireAssignable(dst, src reflect.Value) error {
    88  	if dst.Kind() != reflect.Ptr && dst.Kind() != reflect.Interface {
    89  		return fmt.Errorf("abi: cannot unmarshal %v into %v", src.Type(), dst.Type())
    90  	}
    91  	return nil
    92  }
    93  
    94  //RequireUnpackKind验证将“args”解包为“kind”的前提条件
    95  func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind,
    96  	args Arguments) error {
    97  
    98  	switch k {
    99  	case reflect.Struct:
   100  	case reflect.Slice, reflect.Array:
   101  		if minLen := args.LengthNonIndexed(); v.Len() < minLen {
   102  			return fmt.Errorf("abi: insufficient number of elements in the list/array for unpack, want %d, got %d",
   103  				minLen, v.Len())
   104  		}
   105  	default:
   106  		return fmt.Errorf("abi: cannot unmarshal tuple into %v", t)
   107  	}
   108  	return nil
   109  }
   110  
   111  //mapabitoStringField将abi映射到结构字段。
   112  //第一轮:对于每个包含“abi:”标记的可导出字段
   113  //这个字段名存在于参数中,将它们配对在一起。
   114  //第二轮:对于每个尚未链接的参数字段,
   115  //如果变量存在且尚未映射,则查找该变量应映射到的对象。
   116  //用过,配对。
   117  func mapAbiToStructFields(args Arguments, value reflect.Value) (map[string]string, error) {
   118  
   119  	typ := value.Type()
   120  
   121  	abi2struct := make(map[string]string)
   122  	struct2abi := make(map[string]string)
   123  
   124  //第一轮~~~
   125  	for i := 0; i < typ.NumField(); i++ {
   126  		structFieldName := typ.Field(i).Name
   127  
   128  //跳过私有结构字段。
   129  		if structFieldName[:1] != strings.ToUpper(structFieldName[:1]) {
   130  			continue
   131  		}
   132  
   133  //跳过没有abi:“”标记的字段。
   134  		var ok bool
   135  		var tagName string
   136  		if tagName, ok = typ.Field(i).Tag.Lookup("abi"); !ok {
   137  			continue
   138  		}
   139  
   140  //检查标签是否为空。
   141  		if tagName == "" {
   142  			return nil, fmt.Errorf("struct: abi tag in '%s' is empty", structFieldName)
   143  		}
   144  
   145  //检查哪个参数字段与ABI标记匹配。
   146  		found := false
   147  		for _, abiField := range args.NonIndexed() {
   148  			if abiField.Name == tagName {
   149  				if abi2struct[abiField.Name] != "" {
   150  					return nil, fmt.Errorf("struct: abi tag in '%s' already mapped", structFieldName)
   151  				}
   152  //配对他们
   153  				abi2struct[abiField.Name] = structFieldName
   154  				struct2abi[structFieldName] = abiField.Name
   155  				found = true
   156  			}
   157  		}
   158  
   159  //检查此标记是否已映射。
   160  		if !found {
   161  			return nil, fmt.Errorf("struct: abi tag '%s' defined but not found in abi", tagName)
   162  		}
   163  
   164  	}
   165  
   166  //第二轮~~~
   167  	for _, arg := range args {
   168  
   169  		abiFieldName := arg.Name
   170  		structFieldName := capitalise(abiFieldName)
   171  
   172  		if structFieldName == "" {
   173  			return nil, fmt.Errorf("abi: purely underscored output cannot unpack to struct")
   174  		}
   175  
   176  //这个ABI已经配对了,跳过它…除非存在另一个尚未分配的
   177  //具有相同字段名的结构字段。如果是,则引发错误:
   178  //ABI:[“name”:“value”]
   179  //结构value*big.int,value1*big.int`abi:“value”`
   180  		if abi2struct[abiFieldName] != "" {
   181  			if abi2struct[abiFieldName] != structFieldName &&
   182  				struct2abi[structFieldName] == "" &&
   183  				value.FieldByName(structFieldName).IsValid() {
   184  				return nil, fmt.Errorf("abi: multiple variables maps to the same abi field '%s'", abiFieldName)
   185  			}
   186  			continue
   187  		}
   188  
   189  //如果此结构字段已配对,则返回错误。
   190  		if struct2abi[structFieldName] != "" {
   191  			return nil, fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", structFieldName)
   192  		}
   193  
   194  		if value.FieldByName(structFieldName).IsValid() {
   195  //配对他们
   196  			abi2struct[abiFieldName] = structFieldName
   197  			struct2abi[structFieldName] = abiFieldName
   198  		} else {
   199  //不是成对的,而是按使用进行注释,以检测
   200  //ABI:[“name”:“value”,“name”:“value”]
   201  //结构值*big.int
   202  			struct2abi[structFieldName] = abiFieldName
   203  		}
   204  
   205  	}
   206  
   207  	return abi2struct, nil
   208  }
   209