github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/accounts/abi/error.go (about)

     1  package abi
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"reflect"
     7  )
     8  
     9  var (
    10  	errBadBool = errors.New("abi: improperly encoded boolean value")
    11  )
    12  
    13  // formatSliceString formats the reflection kind with the given slice size
    14  // and returns a formatted string representation.
    15  func formatSliceString(kind reflect.Kind, sliceSize int) string {
    16  	if sliceSize == -1 {
    17  		return fmt.Sprintf("[]%v", kind)
    18  	}
    19  	return fmt.Sprintf("[%d]%v", sliceSize, kind)
    20  }
    21  
    22  // sliceTypeCheck checks that the given slice can by assigned to the reflection
    23  // type in t.
    24  func sliceTypeCheck(t Type, val reflect.Value) error {
    25  	if val.Kind() != reflect.Slice && val.Kind() != reflect.Array {
    26  		return typeErr(formatSliceString(t.Kind, t.Size), val.Type())
    27  	}
    28  
    29  	if t.T == ArrayTy && val.Len() != t.Size {
    30  		return typeErr(formatSliceString(t.Elem.Kind, t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len()))
    31  	}
    32  
    33  	if t.Elem.T == SliceTy {
    34  		if val.Len() > 0 {
    35  			return sliceTypeCheck(*t.Elem, val.Index(0))
    36  		}
    37  	} else if t.Elem.T == ArrayTy {
    38  		return sliceTypeCheck(*t.Elem, val.Index(0))
    39  	}
    40  
    41  	if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.Kind {
    42  		return typeErr(formatSliceString(t.Elem.Kind, t.Size), val.Type())
    43  	}
    44  	return nil
    45  }
    46  
    47  // typeCheck checks that the given reflection value can be assigned to the reflection
    48  // type in t.
    49  func typeCheck(t Type, value reflect.Value) error {
    50  	if t.T == SliceTy || t.T == ArrayTy {
    51  		return sliceTypeCheck(t, value)
    52  	}
    53  
    54  	// Check base type validity. Element types will be checked later on.
    55  	if t.Kind != value.Kind() {
    56  		return typeErr(t.Kind, value.Kind())
    57  	} else if t.T == FixedBytesTy && t.Size != value.Len() {
    58  		return typeErr(t.Type, value.Type())
    59  	} else {
    60  		return nil
    61  	}
    62  
    63  }
    64  
    65  // typeErr returns a formatted type casting error.
    66  func typeErr(expected, got interface{}) error {
    67  	return fmt.Errorf("abi: cannot use %v as type %v as argument", got, expected)
    68  }