github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/accounts/abi/reflect.go (about) 1 package abi 2 3 import ( 4 "fmt" 5 "reflect" 6 ) 7 8 // indirect recursively dereferences the value until it either gets the value 9 // or finds a big.Int 10 func indirect(v reflect.Value) reflect.Value { 11 if v.Kind() == reflect.Ptr && v.Elem().Type() != derefbigT { 12 return indirect(v.Elem()) 13 } 14 return v 15 } 16 17 // reflectIntKind returns the reflect using the given size and 18 // unsignedness. 19 func reflectIntKindAndType(unsigned bool, size int) (reflect.Kind, reflect.Type) { 20 switch size { 21 case 8: 22 if unsigned { 23 return reflect.Uint8, uint8T 24 } 25 return reflect.Int8, int8T 26 case 16: 27 if unsigned { 28 return reflect.Uint16, uint16T 29 } 30 return reflect.Int16, int16T 31 case 32: 32 if unsigned { 33 return reflect.Uint32, uint32T 34 } 35 return reflect.Int32, int32T 36 case 64: 37 if unsigned { 38 return reflect.Uint64, uint64T 39 } 40 return reflect.Int64, int64T 41 } 42 return reflect.Ptr, bigT 43 } 44 45 // mustArrayToBytesSlice creates a new byte slice with the exact same size as value 46 // and copies the bytes in value to the new slice. 47 func mustArrayToByteSlice(value reflect.Value) reflect.Value { 48 slice := reflect.MakeSlice(reflect.TypeOf([]byte{}), value.Len(), value.Len()) 49 reflect.Copy(slice, value) 50 return slice 51 } 52 53 // set attempts to assign src to dst by either setting, copying or otherwise. 54 // 55 // set is a bit more lenient when it comes to assignment and doesn't force an as 56 // strict ruleset as bare `reflect` does. 57 func set(dst, src reflect.Value, output Argument) error { 58 dstType := dst.Type() 59 srcType := src.Type() 60 switch { 61 case dstType.AssignableTo(srcType): 62 dst.Set(src) 63 case dstType.Kind() == reflect.Interface: 64 dst.Set(src) 65 case dstType.Kind() == reflect.Ptr: 66 return set(dst.Elem(), src, output) 67 default: 68 return fmt.Errorf("abi: cannot unmarshal %v in to %v", src.Type(), dst.Type()) 69 } 70 return nil 71 } 72 73 // requireAssignable assures that `dest` is a pointer and it's not an interface. 74 func requireAssignable(dst, src reflect.Value) error { 75 if dst.Kind() != reflect.Ptr && dst.Kind() != reflect.Interface { 76 return fmt.Errorf("abi: cannot unmarshal %v into %v", src.Type(), dst.Type()) 77 } 78 return nil 79 } 80 81 // requireUnpackKind verifies preconditions for unpacking `args` into `kind` 82 func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind, 83 args Arguments) error { 84 85 switch k { 86 case reflect.Struct: 87 case reflect.Slice, reflect.Array: 88 if minLen := args.LengthNonIndexed(); v.Len() < minLen { 89 return fmt.Errorf("abi: insufficient number of elements in the list/array for unpack, want %d, got %d", 90 minLen, v.Len()) 91 } 92 default: 93 return fmt.Errorf("abi: cannot unmarshal tuple into %v", t) 94 } 95 return nil 96 } 97 98 // requireUniqueStructFieldNames makes sure field names don't collide 99 func requireUniqueStructFieldNames(args Arguments) error { 100 exists := make(map[string]bool) 101 for _, arg := range args { 102 field := capitalise(arg.Name) 103 if field == "" { 104 return fmt.Errorf("abi: purely underscored output cannot unpack to struct") 105 } 106 if exists[field] { 107 return fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", field) 108 } 109 exists[field] = true 110 } 111 return nil 112 }