smartcontract: implement io.Serializable for Parameter
This commit is contained in:
parent
0f17b9be1d
commit
6ac69d075e
2 changed files with 111 additions and 0 deletions
|
@ -4,11 +4,14 @@ import (
|
|||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/bits"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -210,6 +213,87 @@ func (p *Parameter) UnmarshalJSON(data []byte) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// EncodeBinary implements io.Serializable interface.
|
||||
func (p *Parameter) EncodeBinary(w *io.BinWriter) {
|
||||
w.WriteB(byte(p.Type))
|
||||
switch p.Type {
|
||||
case BoolType:
|
||||
w.WriteBool(p.Value.(bool))
|
||||
case ByteArrayType, PublicKeyType, SignatureType:
|
||||
if p.Value == nil {
|
||||
w.WriteVarUint(math.MaxUint64)
|
||||
} else {
|
||||
w.WriteVarBytes(p.Value.([]byte))
|
||||
}
|
||||
case StringType:
|
||||
w.WriteString(p.Value.(string))
|
||||
case IntegerType:
|
||||
w.WriteU64LE(uint64(p.Value.(int64)))
|
||||
case ArrayType:
|
||||
w.WriteArray(p.Value.([]Parameter))
|
||||
case MapType:
|
||||
m := p.Value.(map[Parameter]Parameter)
|
||||
w.WriteVarUint(uint64(len(m)))
|
||||
for k := range m {
|
||||
v := m[k]
|
||||
k.EncodeBinary(w)
|
||||
v.EncodeBinary(w)
|
||||
}
|
||||
case Hash160Type:
|
||||
w.WriteBytes(p.Value.(util.Uint160).BytesBE())
|
||||
case Hash256Type:
|
||||
w.WriteBytes(p.Value.(util.Uint256).BytesBE())
|
||||
case InteropInterfaceType:
|
||||
default:
|
||||
w.Err = fmt.Errorf("unknown type: %x", p.Type)
|
||||
}
|
||||
}
|
||||
|
||||
// DecodeBinary implements io.Serializable interface.
|
||||
func (p *Parameter) DecodeBinary(r *io.BinReader) {
|
||||
p.Type = ParamType(r.ReadB())
|
||||
switch p.Type {
|
||||
case BoolType:
|
||||
p.Value = r.ReadBool()
|
||||
case ByteArrayType, PublicKeyType, SignatureType:
|
||||
ln := r.ReadVarUint()
|
||||
if ln != math.MaxUint64 {
|
||||
b := make([]byte, ln)
|
||||
r.ReadBytes(b)
|
||||
p.Value = b
|
||||
}
|
||||
case StringType:
|
||||
p.Value = r.ReadString()
|
||||
case IntegerType:
|
||||
p.Value = int64(r.ReadU64LE())
|
||||
case ArrayType:
|
||||
ps := []Parameter{}
|
||||
r.ReadArray(&ps)
|
||||
p.Value = ps
|
||||
case MapType:
|
||||
ln := r.ReadVarUint()
|
||||
m := make(map[Parameter]Parameter, ln)
|
||||
for i := uint64(0); i < ln; i++ {
|
||||
var k, v Parameter
|
||||
k.DecodeBinary(r)
|
||||
v.DecodeBinary(r)
|
||||
m[k] = v
|
||||
}
|
||||
p.Value = m
|
||||
case Hash160Type:
|
||||
var u util.Uint160
|
||||
r.ReadBytes(u[:])
|
||||
p.Value = u
|
||||
case Hash256Type:
|
||||
var u util.Uint256
|
||||
r.ReadBytes(u[:])
|
||||
p.Value = u
|
||||
case InteropInterfaceType:
|
||||
default:
|
||||
r.Err = fmt.Errorf("unknown type: %x", p.Type)
|
||||
}
|
||||
}
|
||||
|
||||
// Params is an array of Parameter (TODO: drop it?).
|
||||
type Params []Parameter
|
||||
|
||||
|
|
|
@ -6,8 +6,10 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var marshalJSONTestCases = []struct {
|
||||
|
@ -441,3 +443,28 @@ func TestNewParameterFromString(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeDecodeBinary(t *testing.T) {
|
||||
for _, tc := range marshalJSONTestCases {
|
||||
w := io.NewBufBinWriter()
|
||||
tc.input.EncodeBinary(w.BinWriter)
|
||||
require.NoError(t, w.Err)
|
||||
|
||||
r := io.NewBinReaderFromBuf(w.Bytes())
|
||||
var p Parameter
|
||||
p.DecodeBinary(r)
|
||||
require.NoError(t, r.Err)
|
||||
require.Equal(t, tc.input, p)
|
||||
}
|
||||
|
||||
t.Run("unknown", func(t *testing.T) {
|
||||
p := Parameter{Type: UnknownType}
|
||||
w := io.NewBufBinWriter()
|
||||
p.EncodeBinary(w.BinWriter)
|
||||
require.Error(t, w.Err)
|
||||
|
||||
r := io.NewBinReaderFromBuf([]byte{0xAA})
|
||||
p.DecodeBinary(r)
|
||||
require.Error(t, r.Err)
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue