error.go 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright 2016 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package abi
  17. import (
  18. "errors"
  19. "fmt"
  20. "reflect"
  21. )
  22. var (
  23. errBadBool = errors.New("abi: improperly encoded boolean value")
  24. )
  25. // formatSliceString formats the reflection kind with the given slice size
  26. // and returns a formatted string representation.
  27. func formatSliceString(kind reflect.Kind, sliceSize int) string {
  28. if sliceSize == -1 {
  29. return fmt.Sprintf("[]%v", kind)
  30. }
  31. return fmt.Sprintf("[%d]%v", sliceSize, kind)
  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.GetType().Kind(), t.Size), val.Type())
  38. }
  39. if t.T == ArrayTy && val.Len() != t.Size {
  40. return typeErr(formatSliceString(t.Elem.GetType().Kind(), t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len()))
  41. }
  42. if t.Elem.T == SliceTy || t.Elem.T == ArrayTy {
  43. if val.Len() > 0 {
  44. return sliceTypeCheck(*t.Elem, val.Index(0))
  45. }
  46. }
  47. if val.Type().Elem().Kind() != t.Elem.GetType().Kind() {
  48. return typeErr(formatSliceString(t.Elem.GetType().Kind(), t.Size), val.Type())
  49. }
  50. return nil
  51. }
  52. // typeCheck checks that the given reflection value can be assigned to the reflection
  53. // type in t.
  54. func typeCheck(t Type, value reflect.Value) error {
  55. if t.T == SliceTy || t.T == ArrayTy {
  56. return sliceTypeCheck(t, value)
  57. }
  58. // Check base type validity. Element types will be checked later on.
  59. if t.GetType().Kind() != value.Kind() {
  60. return typeErr(t.GetType().Kind(), value.Kind())
  61. } else if t.T == FixedBytesTy && t.Size != value.Len() {
  62. return typeErr(t.GetType(), value.Type())
  63. } else {
  64. return nil
  65. }
  66. }
  67. // typeErr returns a formatted type casting error.
  68. func typeErr(expected, got interface{}) error {
  69. return fmt.Errorf("abi: cannot use %v as type %v as argument", got, expected)
  70. }