Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scale: encode/decode []string in struct #560

Merged
merged 11 commits into from
Jan 24, 2020
40 changes: 24 additions & 16 deletions codec/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,22 +281,6 @@ func (sd *Decoder) DecodeByteArray() (o []byte, err error) {
return b, nil
}

// DecodePtrByteArray accepts a byte array representing a SCALE encoded byte array and performs SCALE decoding
// of the byte array
func (sd *Decoder) DecodePtrByteArray(output interface{}) error {
_, err := sd.DecodeInteger()
if err != nil {
return err
}

_, err = sd.Reader.Read(output.([]byte))
if err != nil {
return errors.New("could not decode invalid byte array: reached early EOF")
}

return nil
}

// DecodeBool accepts a byte array representing a SCALE encoded bool and performs SCALE decoding
// of the bool then returns it. if invalid, return false and an error
func (sd *Decoder) DecodeBool() (bool, error) {
Expand Down Expand Up @@ -534,6 +518,13 @@ func (sd *Decoder) DecodeTuple(t interface{}) (interface{}, error) {
// get the pointer to the value and set the value
ptr := fieldValue.(*string)
*ptr = string(o.([]byte))
case []string:
o, err = sd.DecodeStringArray()
if err != nil {
break
}
ptr := fieldValue.(*[]string)
*ptr = o.([]string)
default:
_, err = sd.Decode(v.Field(i).Interface())
if err != nil {
Expand Down Expand Up @@ -604,3 +595,20 @@ func (sd *Decoder) DecodeBoolArray() ([]bool, error) {
}
return o, nil
}

func (sd *Decoder) DecodeStringArray() ([]string, error) {
length, err := sd.DecodeInteger()
if err != nil {
return nil, err
}
s := make([]string, length)

for i := 0; i < int(length); i++ {
o, err := sd.DecodeByteArray()
if err != nil {
return nil, err
}
s[i] = string(o[:]) // cast []byte into string
}
return s, nil
}
16 changes: 16 additions & 0 deletions codec/decode_ptr.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,22 @@ func (sd *Decoder) DecodePtrFixedWidthInt(t interface{}) (err error) {
return err
}

// DecodePtrByteArray accepts a byte array representing a SCALE encoded byte array and performs SCALE decoding
// of the byte array
func (sd *Decoder) DecodePtrByteArray(output interface{}) error {
_, err := sd.DecodeInteger()
if err != nil {
return err
}

_, err = sd.Reader.Read(output.([]byte))
if err != nil {
return errors.New("could not decode invalid byte array: reached early EOF")
}

return nil
}

// DecodePtrBigInt decodes a SCALE encoded byte array into a *big.Int
// Changes the value of output to decoded value
// Works for all integers, including ints > 2**64
Expand Down
8 changes: 8 additions & 0 deletions codec/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,14 @@ func (se *Encoder) encodeArray(t interface{}) (bytesEncoded int, err error) {
n, err = se.encodeArray(elem)
bytesEncoded += n
}
case []string:
n, err = se.encodeInteger(uint(len(arr)))
bytesEncoded += n

for _, elem := range arr {
n, err = se.encodeByteArray([]byte(elem))
bytesEncoded += n
}
}

return bytesEncoded, err
Expand Down
20 changes: 20 additions & 0 deletions codec/encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"reflect"
"strings"
"testing"

"github.com/stretchr/testify/require"
)

type encodeTest struct {
Expand Down Expand Up @@ -190,3 +192,21 @@ func TestEncodeAndDecodeStringInStruct(t *testing.T) {
t.Fatalf("Fail: got %v expected %v", dec, test)
}
}

func TestEncodeAndDecodeStringArrayInStruct(t *testing.T) {
test := &struct {
A []string
}{
A: []string{"noot", "noot2"},
}

enc, err := Encode(test)
require.Nil(t, err)
require.NotEqual(t, 0, len(enc), "Failed to encode StringArrayInStruct")

var result = &struct{ A []string }{}

err = DecodePtr(enc, result)
require.Nil(t, err)
require.Equal(t, test, result, "Decoding failed")
}