github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/accounts/abi/reflect.go (about)

     1  // This file is part of the go-sberex library. The go-sberex library is 
     2  // free software: you can redistribute it and/or modify it under the terms 
     3  // of the GNU Lesser General Public License as published by the Free 
     4  // Software Foundation, either version 3 of the License, or (at your option)
     5  // any later version.
     6  //
     7  // The go-sberex library is distributed in the hope that it will be useful, 
     8  // but WITHOUT ANY WARRANTY; without even the implied warranty of
     9  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 
    10  // General Public License <http://www.gnu.org/licenses/> for more details.
    11  
    12  package abi
    13  
    14  import (
    15  	"fmt"
    16  	"reflect"
    17  )
    18  
    19  // indirect recursively dereferences the value until it either gets the value
    20  // or finds a big.Int
    21  func indirect(v reflect.Value) reflect.Value {
    22  	if v.Kind() == reflect.Ptr && v.Elem().Type() != derefbig_t {
    23  		return indirect(v.Elem())
    24  	}
    25  	return v
    26  }
    27  
    28  // reflectIntKind returns the reflect using the given size and
    29  // unsignedness.
    30  func reflectIntKindAndType(unsigned bool, size int) (reflect.Kind, reflect.Type) {
    31  	switch size {
    32  	case 8:
    33  		if unsigned {
    34  			return reflect.Uint8, uint8_t
    35  		}
    36  		return reflect.Int8, int8_t
    37  	case 16:
    38  		if unsigned {
    39  			return reflect.Uint16, uint16_t
    40  		}
    41  		return reflect.Int16, int16_t
    42  	case 32:
    43  		if unsigned {
    44  			return reflect.Uint32, uint32_t
    45  		}
    46  		return reflect.Int32, int32_t
    47  	case 64:
    48  		if unsigned {
    49  			return reflect.Uint64, uint64_t
    50  		}
    51  		return reflect.Int64, int64_t
    52  	}
    53  	return reflect.Ptr, big_t
    54  }
    55  
    56  // mustArrayToBytesSlice creates a new byte slice with the exact same size as value
    57  // and copies the bytes in value to the new slice.
    58  func mustArrayToByteSlice(value reflect.Value) reflect.Value {
    59  	slice := reflect.MakeSlice(reflect.TypeOf([]byte{}), value.Len(), value.Len())
    60  	reflect.Copy(slice, value)
    61  	return slice
    62  }
    63  
    64  // set attempts to assign src to dst by either setting, copying or otherwise.
    65  //
    66  // set is a bit more lenient when it comes to assignment and doesn't force an as
    67  // strict ruleset as bare `reflect` does.
    68  func set(dst, src reflect.Value, output Argument) error {
    69  	dstType := dst.Type()
    70  	srcType := src.Type()
    71  	switch {
    72  	case dstType.AssignableTo(srcType):
    73  		dst.Set(src)
    74  	case dstType.Kind() == reflect.Interface:
    75  		dst.Set(src)
    76  	case dstType.Kind() == reflect.Ptr:
    77  		return set(dst.Elem(), src, output)
    78  	default:
    79  		return fmt.Errorf("abi: cannot unmarshal %v in to %v", src.Type(), dst.Type())
    80  	}
    81  	return nil
    82  }
    83  
    84  // requireAssignable assures that `dest` is a pointer and it's not an interface.
    85  func requireAssignable(dst, src reflect.Value) error {
    86  	if dst.Kind() != reflect.Ptr && dst.Kind() != reflect.Interface {
    87  		return fmt.Errorf("abi: cannot unmarshal %v into %v", src.Type(), dst.Type())
    88  	}
    89  	return nil
    90  }
    91  
    92  // requireUnpackKind verifies preconditions for unpacking `args` into `kind`
    93  func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind,
    94  	args Arguments) error {
    95  
    96  	switch k {
    97  	case reflect.Struct:
    98  	case reflect.Slice, reflect.Array:
    99  		if minLen := args.LengthNonIndexed(); v.Len() < minLen {
   100  			return fmt.Errorf("abi: insufficient number of elements in the list/array for unpack, want %d, got %d",
   101  				minLen, v.Len())
   102  		}
   103  	default:
   104  		return fmt.Errorf("abi: cannot unmarshal tuple into %v", t)
   105  	}
   106  	return nil
   107  }