github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/accounts/abi/error.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 "errors" 16 "fmt" 17 "reflect" 18 ) 19 20 var ( 21 errBadBool = errors.New("abi: improperly encoded boolean value") 22 ) 23 24 // formatSliceString formats the reflection kind with the given slice size 25 // and returns a formatted string representation. 26 func formatSliceString(kind reflect.Kind, sliceSize int) string { 27 if sliceSize == -1 { 28 return fmt.Sprintf("[]%v", kind) 29 } 30 return fmt.Sprintf("[%d]%v", sliceSize, kind) 31 } 32 33 // sliceTypeCheck checks that the given slice can by assigned to the reflection 34 // type in t. 35 func sliceTypeCheck(t Type, val reflect.Value) error { 36 if val.Kind() != reflect.Slice && val.Kind() != reflect.Array { 37 return typeErr(formatSliceString(t.Kind, t.Size), val.Type()) 38 } 39 40 if t.T == ArrayTy && val.Len() != t.Size { 41 return typeErr(formatSliceString(t.Elem.Kind, t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len())) 42 } 43 44 if t.Elem.T == SliceTy { 45 if val.Len() > 0 { 46 return sliceTypeCheck(*t.Elem, val.Index(0)) 47 } 48 } else if t.Elem.T == ArrayTy { 49 return sliceTypeCheck(*t.Elem, val.Index(0)) 50 } 51 52 if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.Kind { 53 return typeErr(formatSliceString(t.Elem.Kind, t.Size), val.Type()) 54 } 55 return nil 56 } 57 58 // typeCheck checks that the given reflection value can be assigned to the reflection 59 // type in t. 60 func typeCheck(t Type, value reflect.Value) error { 61 if t.T == SliceTy || t.T == ArrayTy { 62 return sliceTypeCheck(t, value) 63 } 64 65 // Check base type validity. Element types will be checked later on. 66 if t.Kind != value.Kind() { 67 return typeErr(t.Kind, value.Kind()) 68 } else if t.T == FixedBytesTy && t.Size != value.Len() { 69 return typeErr(t.Type, value.Type()) 70 } else { 71 return nil 72 } 73 74 } 75 76 // typeErr returns a formatted type casting error. 77 func typeErr(expected, got interface{}) error { 78 return fmt.Errorf("abi: cannot use %v as type %v as argument", got, expected) 79 }