mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-12 15:03:45 +00:00
Merge 5fbce1ad39 into 061889d4ea
This commit is contained in:
commit
489ce69695
3 changed files with 53 additions and 3 deletions
|
|
@ -304,12 +304,21 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) error {
|
||||||
// struct will match named return values to the struct's field
|
// struct will match named return values to the struct's field
|
||||||
// names
|
// names
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
|
idx := 0
|
||||||
for i := 0; i < len(method.Outputs); i++ {
|
for i := 0; i < len(method.Outputs); i++ {
|
||||||
marshalledValue, err := toGoType(i, method.Outputs[i], output)
|
marshalledValue, err := toGoType(idx, method.Outputs[i], output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
reflectValue := reflect.ValueOf(marshalledValue)
|
reflectValue := reflect.ValueOf(marshalledValue)
|
||||||
|
kind := reflectValue.Type().Kind()
|
||||||
|
if (kind == reflect.Array || kind == reflect.Slice) &&
|
||||||
|
reflectValue.Type().Elem().Kind() != reflect.Uint8 {
|
||||||
|
// This is a slice of something other than bytes.
|
||||||
|
idx += reflectValue.Len()
|
||||||
|
} else {
|
||||||
|
idx++
|
||||||
|
}
|
||||||
|
|
||||||
for j := 0; j < typ.NumField(); j++ {
|
for j := 0; j < typ.NumField(); j++ {
|
||||||
field := typ.Field(j)
|
field := typ.Field(j)
|
||||||
|
|
|
||||||
|
|
@ -1002,7 +1002,8 @@ func TestUnmarshal(t *testing.T) {
|
||||||
{ "name" : "intArraySingle", "constant" : false, "outputs": [ { "type": "uint256[3]" } ] },
|
{ "name" : "intArraySingle", "constant" : false, "outputs": [ { "type": "uint256[3]" } ] },
|
||||||
{ "name" : "addressSliceSingle", "constant" : false, "outputs": [ { "type": "address[]" } ] },
|
{ "name" : "addressSliceSingle", "constant" : false, "outputs": [ { "type": "address[]" } ] },
|
||||||
{ "name" : "addressSliceDouble", "constant" : false, "outputs": [ { "name": "a", "type": "address[]" }, { "name": "b", "type": "address[]" } ] },
|
{ "name" : "addressSliceDouble", "constant" : false, "outputs": [ { "name": "a", "type": "address[]" }, { "name": "b", "type": "address[]" } ] },
|
||||||
{ "name" : "mixedBytes", "constant" : true, "outputs": [ { "name": "a", "type": "bytes" }, { "name": "b", "type": "bytes32" } ] }]`
|
{ "name" : "mixedBytes", "constant" : true, "outputs": [ { "name": "a", "type": "bytes" }, { "name": "b", "type": "bytes32" } ] },
|
||||||
|
{ "name" : "arraysStruct", "constant" : true, "outputs": [ { "name": "a", "type": "bytes4[2]" }, { "name": "b", "type": "bytes20[2]" } ] }]`
|
||||||
|
|
||||||
abi, err := JSON(strings.NewReader(definition))
|
abi, err := JSON(strings.NewReader(definition))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -1238,4 +1239,37 @@ func TestUnmarshal(t *testing.T) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("expected error:", err)
|
t.Fatal("expected error:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// marshal arrays of arrays
|
||||||
|
buff.Reset()
|
||||||
|
buff.Write(common.Hex2Bytes("0000000100000000000000000000000000000000000000000000000000000000")) // a[0]
|
||||||
|
buff.Write(common.Hex2Bytes("0000000200000000000000000000000000000000000000000000000000000000")) // a[1]
|
||||||
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000003000000000000000000000000")) // b[0]
|
||||||
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000004000000000000000000000000")) // b[1]
|
||||||
|
|
||||||
|
var arraysStruct struct {
|
||||||
|
A [2][4]byte
|
||||||
|
B [2][20]byte
|
||||||
|
}
|
||||||
|
err = abi.Unpack(&arraysStruct, "arraysStruct", buff.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("didn't expect error:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
exp4 := [4]byte{0, 0, 0, 1}
|
||||||
|
if arraysStruct.A[0] != exp4 {
|
||||||
|
t.Errorf("expected %x, got %x", exp4, arraysStruct.A[0])
|
||||||
|
}
|
||||||
|
exp4 = [4]byte{0, 0, 0, 2}
|
||||||
|
if arraysStruct.A[1] != exp4 {
|
||||||
|
t.Errorf("expected %x, got %x", exp4, arraysStruct.A[1])
|
||||||
|
}
|
||||||
|
exp20 := [20]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3}
|
||||||
|
if arraysStruct.B[0] != exp20 {
|
||||||
|
t.Errorf("expected %x, got %x", exp20, arraysStruct.B[0])
|
||||||
|
}
|
||||||
|
exp20 = [20]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4}
|
||||||
|
if arraysStruct.B[1] != exp20 {
|
||||||
|
t.Errorf("expected %x, got %x", exp20, arraysStruct.B[1])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,14 @@ func set(dst, src reflect.Value, output Argument) error {
|
||||||
if dst.Len() < output.Type.SliceSize {
|
if dst.Len() < output.Type.SliceSize {
|
||||||
return fmt.Errorf("abi: cannot unmarshal src (len=%d) in to dst (len=%d)", output.Type.SliceSize, dst.Len())
|
return fmt.Errorf("abi: cannot unmarshal src (len=%d) in to dst (len=%d)", output.Type.SliceSize, dst.Len())
|
||||||
}
|
}
|
||||||
reflect.Copy(dst, src)
|
switch dstType.Elem().Kind() {
|
||||||
|
case reflect.Array:
|
||||||
|
for i := 0; i < dst.Len(); i++ {
|
||||||
|
reflect.Copy(dst.Index(i), src.Index(i))
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
reflect.Copy(dst, src)
|
||||||
|
}
|
||||||
case dstType.Kind() == reflect.Interface:
|
case dstType.Kind() == reflect.Interface:
|
||||||
dst.Set(src)
|
dst.Set(src)
|
||||||
case dstType.Kind() == reflect.Ptr:
|
case dstType.Kind() == reflect.Ptr:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue