|
|
@ -113,16 +113,8 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa |
|
|
|
} |
|
|
|
} |
|
|
|
// If the output interface is a struct, make sure names don't collide
|
|
|
|
// If the output interface is a struct, make sure names don't collide
|
|
|
|
if kind == reflect.Struct { |
|
|
|
if kind == reflect.Struct { |
|
|
|
exists := make(map[string]bool) |
|
|
|
if err := requireUniqueStructFieldNames(arguments); err != nil { |
|
|
|
for _, arg := range arguments { |
|
|
|
return err |
|
|
|
field := capitalise(arg.Name) |
|
|
|
|
|
|
|
if field == "" { |
|
|
|
|
|
|
|
return fmt.Errorf("abi: purely underscored output cannot unpack to struct") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if exists[field] { |
|
|
|
|
|
|
|
return fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", field) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
exists[field] = true |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
for i, arg := range arguments.NonIndexed() { |
|
|
|
for i, arg := range arguments.NonIndexed() { |
|
|
@ -131,14 +123,9 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa |
|
|
|
|
|
|
|
|
|
|
|
switch kind { |
|
|
|
switch kind { |
|
|
|
case reflect.Struct: |
|
|
|
case reflect.Struct: |
|
|
|
name := capitalise(arg.Name) |
|
|
|
err := unpackStruct(value, reflectValue, arg) |
|
|
|
for j := 0; j < typ.NumField(); j++ { |
|
|
|
if err != nil { |
|
|
|
// TODO read tags: `abi:"fieldName"`
|
|
|
|
return err |
|
|
|
if typ.Field(j).Name == name { |
|
|
|
|
|
|
|
if err := set(value.Field(j), reflectValue, arg); err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
case reflect.Slice, reflect.Array: |
|
|
|
case reflect.Slice, reflect.Array: |
|
|
|
if value.Len() < i { |
|
|
|
if value.Len() < i { |
|
|
@ -165,8 +152,20 @@ func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues []interf |
|
|
|
return fmt.Errorf("abi: wrong length, expected single value, got %d", len(marshalledValues)) |
|
|
|
return fmt.Errorf("abi: wrong length, expected single value, got %d", len(marshalledValues)) |
|
|
|
} |
|
|
|
} |
|
|
|
elem := reflect.ValueOf(v).Elem() |
|
|
|
elem := reflect.ValueOf(v).Elem() |
|
|
|
|
|
|
|
kind := elem.Kind() |
|
|
|
reflectValue := reflect.ValueOf(marshalledValues[0]) |
|
|
|
reflectValue := reflect.ValueOf(marshalledValues[0]) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if kind == reflect.Struct { |
|
|
|
|
|
|
|
//make sure names don't collide
|
|
|
|
|
|
|
|
if err := requireUniqueStructFieldNames(arguments); err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return unpackStruct(elem, reflectValue, arguments[0]) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return set(elem, reflectValue, arguments.NonIndexed()[0]) |
|
|
|
return set(elem, reflectValue, arguments.NonIndexed()[0]) |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Computes the full size of an array;
|
|
|
|
// Computes the full size of an array;
|
|
|
@ -278,3 +277,18 @@ func capitalise(input string) string { |
|
|
|
} |
|
|
|
} |
|
|
|
return strings.ToUpper(input[:1]) + input[1:] |
|
|
|
return strings.ToUpper(input[:1]) + input[1:] |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//unpackStruct extracts each argument into its corresponding struct field
|
|
|
|
|
|
|
|
func unpackStruct(value, reflectValue reflect.Value, arg Argument) error { |
|
|
|
|
|
|
|
name := capitalise(arg.Name) |
|
|
|
|
|
|
|
typ := value.Type() |
|
|
|
|
|
|
|
for j := 0; j < typ.NumField(); j++ { |
|
|
|
|
|
|
|
// TODO read tags: `abi:"fieldName"`
|
|
|
|
|
|
|
|
if typ.Field(j).Name == name { |
|
|
|
|
|
|
|
if err := set(value.Field(j), reflectValue, arg); err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|