mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
accounts/abi: simplified reflection logic
This commit is contained in:
parent
a10793e412
commit
d0a25e1967
3 changed files with 30 additions and 41 deletions
|
|
@ -217,54 +217,41 @@ func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interfac
|
||||||
// unpackTuple unpacks ( hexdata -> go ) a batch of values.
|
// unpackTuple unpacks ( hexdata -> go ) a batch of values.
|
||||||
func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interface{}) error {
|
func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interface{}) error {
|
||||||
var (
|
var (
|
||||||
value = reflect.ValueOf(v).Elem()
|
value = reflect.ValueOf(v).Elem()
|
||||||
typ = value.Type()
|
typ = value.Type()
|
||||||
kind = value.Kind()
|
kind = value.Kind()
|
||||||
nonIndexedArgs = arguments.NonIndexed()
|
|
||||||
)
|
)
|
||||||
if err := requireUnpackKind(value, len(nonIndexedArgs), arguments); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the interface is a struct, get of abi->struct_field mapping
|
switch kind {
|
||||||
var abi2struct map[string]string
|
case reflect.Struct:
|
||||||
if kind == reflect.Struct {
|
k := 0
|
||||||
argNames := make([]string, len(nonIndexedArgs))
|
for i := 0; i < len(arguments); i++ {
|
||||||
for i, arg := range nonIndexedArgs {
|
// Skip indexed fields
|
||||||
argNames[i] = arg.Name
|
if arguments[i].Indexed {
|
||||||
}
|
continue
|
||||||
var err error
|
|
||||||
if abi2struct, err = mapArgNamesToStructFields(argNames, value); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i, arg := range nonIndexedArgs {
|
|
||||||
switch kind {
|
|
||||||
case reflect.Struct:
|
|
||||||
field := value.FieldByName(abi2struct[arg.Name])
|
|
||||||
if !field.IsValid() {
|
|
||||||
return fmt.Errorf("abi: field %s can't be found in the given value", arg.Name)
|
|
||||||
}
|
}
|
||||||
if err := unpack(&arg.Type, field.Addr().Interface(), marshalledValues[i]); err != nil {
|
if i >= value.NumField() {
|
||||||
|
return fmt.Errorf("Invalid field length while unpacking: %v", i)
|
||||||
|
}
|
||||||
|
if err := set(value.Field(i), reflect.ValueOf(marshalledValues[k])); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case reflect.Slice, reflect.Array:
|
k++
|
||||||
if value.Len() < i {
|
|
||||||
return fmt.Errorf("abi: insufficient number of arguments for unpack, want %d, got %d", len(arguments), value.Len())
|
|
||||||
}
|
|
||||||
v := value.Index(i)
|
|
||||||
if err := requireAssignable(v, reflect.ValueOf(marshalledValues[i])); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := unpack(&arg.Type, v.Addr().Interface(), marshalledValues[i]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("abi:[2] cannot unmarshal tuple in to %v", typ)
|
|
||||||
}
|
}
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
for i := 0; i < value.Len(); i++ {
|
||||||
|
// Skip indexed fields
|
||||||
|
if arguments[i].Indexed {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := set(value.Index(i), reflect.ValueOf(marshalledValues[i])); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("abi:[2] cannot unmarshal tuple in to %v", typ)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnpackValues can be used to unpack ABI-encoded hexdata according to the ABI-specification,
|
// UnpackValues can be used to unpack ABI-encoded hexdata according to the ABI-specification,
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,8 @@ func TestEventMultiValueWithArrayUnpack(t *testing.T) {
|
||||||
func TestEventTupleUnpack(t *testing.T) {
|
func TestEventTupleUnpack(t *testing.T) {
|
||||||
|
|
||||||
type EventTransfer struct {
|
type EventTransfer struct {
|
||||||
|
From common.Address
|
||||||
|
To common.Address
|
||||||
Value *big.Int
|
Value *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ func set(dst, src reflect.Value) error {
|
||||||
dst.Set(src)
|
dst.Set(src)
|
||||||
case dstType.Kind() == reflect.Slice && srcType.Kind() == reflect.Slice && dst.CanSet():
|
case dstType.Kind() == reflect.Slice && srcType.Kind() == reflect.Slice && dst.CanSet():
|
||||||
return setSlice(dst, src)
|
return setSlice(dst, src)
|
||||||
case dstType.Kind() == reflect.Array:
|
case dstType.Kind() == reflect.Array && dst.CanSet():
|
||||||
return setArray(dst, src)
|
return setArray(dst, src)
|
||||||
case dstType.Kind() == reflect.Struct:
|
case dstType.Kind() == reflect.Struct:
|
||||||
return setStruct(dst, src)
|
return setStruct(dst, src)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue