error.go 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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.Kind, t.Size), val.Type())
  38. }
  39. if t.T == ArrayTy && val.Len() != t.Size {
  40. return typeErr(formatSliceString(t.Elem.Kind, t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len()))
  41. }
  42. if t.Elem.T == SliceTy {
  43. if val.Len() > 0 {
  44. return sliceTypeCheck(*t.Elem, val.Index(0))
  45. }
  46. } else if t.Elem.T == ArrayTy {
  47. return sliceTypeCheck(*t.Elem, val.Index(0))
  48. }
  49. if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.Kind {
  50. return typeErr(formatSliceString(t.Elem.Kind, t.Size), val.Type())
  51. }
  52. return nil
  53. }
  54. // typeCheck checks that the given reflection value can be assigned to the reflection
  55. // type in t.
  56. func typeCheck(t Type, value reflect.Value) error {
  57. if t.T == SliceTy || t.T == ArrayTy {
  58. return sliceTypeCheck(t, value)
  59. }
  60. // Check base type validity. Element types will be checked later on.
  61. if t.Kind != value.Kind() {
  62. return typeErr(t.Kind, value.Kind())
  63. } else if t.T == FixedBytesTy && t.Size != value.Len() {
  64. return typeErr(t.Type, value.Type())
  65. } else {
  66. return nil
  67. }
  68. }
  69. // typeErr returns a formatted type casting error.
  70. func typeErr(expected, got interface{}) error {
  71. return fmt.Errorf("abi: cannot use %v as type %v as argument", got, expected)
  72. }