forked from TrueCloudLab/neoneo-go
native/std: add overloads for itoa
and atoi
This commit is contained in:
parent
a4b54b2e8a
commit
e4b34833da
4 changed files with 72 additions and 8 deletions
|
@ -225,7 +225,9 @@ func TestNativeHelpersCompile(t *testing.T) {
|
||||||
{"base58Encode", []string{"[]byte{1, 2, 3}"}},
|
{"base58Encode", []string{"[]byte{1, 2, 3}"}},
|
||||||
{"base58Decode", []string{"[]byte{1, 2, 3}"}},
|
{"base58Decode", []string{"[]byte{1, 2, 3}"}},
|
||||||
{"itoa", []string{"4", "10"}},
|
{"itoa", []string{"4", "10"}},
|
||||||
|
{"itoa10", []string{"4"}},
|
||||||
{"atoi", []string{`"4"`, "10"}},
|
{"atoi", []string{`"4"`, "10"}},
|
||||||
|
{"atoi10", []string{`"4"`}},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,10 +241,21 @@ func runNativeTestCases(t *testing.T, ctr interop.ContractMD, name string, testC
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func runNativeTestCase(t *testing.T, ctr interop.ContractMD, name, method string, params ...string) {
|
func getMethod(t *testing.T, ctr interop.ContractMD, name string, params []string) interop.MethodAndPrice {
|
||||||
md, ok := ctr.GetMethod(strings.TrimSuffix(method, "WithData"), len(params))
|
switch {
|
||||||
require.True(t, ok)
|
case name == "itoa10" || name == "atoi10":
|
||||||
|
name = name[:4]
|
||||||
|
default:
|
||||||
|
name = strings.TrimSuffix(name, "WithData")
|
||||||
|
}
|
||||||
|
|
||||||
|
md, ok := ctr.GetMethod(name, len(params))
|
||||||
|
require.True(t, ok)
|
||||||
|
return md
|
||||||
|
}
|
||||||
|
|
||||||
|
func runNativeTestCase(t *testing.T, ctr interop.ContractMD, name, method string, params ...string) {
|
||||||
|
md := getMethod(t, ctr, method, params)
|
||||||
isVoid := md.MD.ReturnType == smartcontract.VoidType
|
isVoid := md.MD.ReturnType == smartcontract.VoidType
|
||||||
srcTmpl := `package foo
|
srcTmpl := `package foo
|
||||||
import "github.com/nspcc-dev/neo-go/pkg/interop/native/%s"
|
import "github.com/nspcc-dev/neo-go/pkg/interop/native/%s"
|
||||||
|
|
|
@ -61,12 +61,22 @@ func newStd() *Std {
|
||||||
md = newMethodAndPrice(s.itoa, 1<<12, callflag.NoneFlag)
|
md = newMethodAndPrice(s.itoa, 1<<12, callflag.NoneFlag)
|
||||||
s.AddMethod(md, desc)
|
s.AddMethod(md, desc)
|
||||||
|
|
||||||
|
desc = newDescriptor("itoa", smartcontract.StringType,
|
||||||
|
manifest.NewParameter("value", smartcontract.IntegerType))
|
||||||
|
md = newMethodAndPrice(s.itoa10, 1<<12, callflag.NoneFlag)
|
||||||
|
s.AddMethod(md, desc)
|
||||||
|
|
||||||
desc = newDescriptor("atoi", smartcontract.IntegerType,
|
desc = newDescriptor("atoi", smartcontract.IntegerType,
|
||||||
manifest.NewParameter("value", smartcontract.StringType),
|
manifest.NewParameter("value", smartcontract.StringType),
|
||||||
manifest.NewParameter("base", smartcontract.IntegerType))
|
manifest.NewParameter("base", smartcontract.IntegerType))
|
||||||
md = newMethodAndPrice(s.atoi, 1<<12, callflag.NoneFlag)
|
md = newMethodAndPrice(s.atoi, 1<<12, callflag.NoneFlag)
|
||||||
s.AddMethod(md, desc)
|
s.AddMethod(md, desc)
|
||||||
|
|
||||||
|
desc = newDescriptor("atoi", smartcontract.IntegerType,
|
||||||
|
manifest.NewParameter("value", smartcontract.StringType))
|
||||||
|
md = newMethodAndPrice(s.atoi10, 1<<12, callflag.NoneFlag)
|
||||||
|
s.AddMethod(md, desc)
|
||||||
|
|
||||||
desc = newDescriptor("base64Encode", smartcontract.StringType,
|
desc = newDescriptor("base64Encode", smartcontract.StringType,
|
||||||
manifest.NewParameter("data", smartcontract.ByteArrayType))
|
manifest.NewParameter("data", smartcontract.ByteArrayType))
|
||||||
md = newMethodAndPrice(s.base64Encode, 1<<12, callflag.NoneFlag)
|
md = newMethodAndPrice(s.base64Encode, 1<<12, callflag.NoneFlag)
|
||||||
|
@ -142,6 +152,11 @@ func (s *Std) jsonDeserialize(_ *interop.Context, args []stackitem.Item) stackit
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Std) itoa10(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||||
|
num := toBigInt(args[0])
|
||||||
|
return stackitem.NewByteArray([]byte(num.Text(10)))
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Std) itoa(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
func (s *Std) itoa(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||||
num := toBigInt(args[0])
|
num := toBigInt(args[0])
|
||||||
base := toBigInt(args[1])
|
base := toBigInt(args[1])
|
||||||
|
@ -170,6 +185,20 @@ func (s *Std) itoa(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||||
return stackitem.NewByteArray([]byte(str))
|
return stackitem.NewByteArray([]byte(str))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Std) atoi10(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||||
|
num := toString(args[0])
|
||||||
|
res := s.atoi10Aux(num)
|
||||||
|
return stackitem.NewBigInteger(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Std) atoi10Aux(num string) *big.Int {
|
||||||
|
bi, ok := new(big.Int).SetString(num, 10)
|
||||||
|
if !ok {
|
||||||
|
panic(ErrInvalidFormat)
|
||||||
|
}
|
||||||
|
return bi
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Std) atoi(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
func (s *Std) atoi(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||||
num := toString(args[0])
|
num := toString(args[0])
|
||||||
base := toBigInt(args[1])
|
base := toBigInt(args[1])
|
||||||
|
@ -179,11 +208,7 @@ func (s *Std) atoi(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||||
var bi *big.Int
|
var bi *big.Int
|
||||||
switch b := base.Int64(); b {
|
switch b := base.Int64(); b {
|
||||||
case 10:
|
case 10:
|
||||||
var ok bool
|
bi = s.atoi10Aux(num)
|
||||||
bi, ok = new(big.Int).SetString(num, int(b))
|
|
||||||
if !ok {
|
|
||||||
panic(ErrInvalidFormat)
|
|
||||||
}
|
|
||||||
case 16:
|
case 16:
|
||||||
changed := len(num)%2 != 0
|
changed := len(num)%2 != 0
|
||||||
if changed {
|
if changed {
|
||||||
|
|
|
@ -49,6 +49,18 @@ func TestStdLibItoaAtoi(t *testing.T) {
|
||||||
actual = s.atoi(ic, []stackitem.Item{stackitem.Make(tc.result), stackitem.Make(tc.base)})
|
actual = s.atoi(ic, []stackitem.Item{stackitem.Make(tc.result), stackitem.Make(tc.base)})
|
||||||
})
|
})
|
||||||
require.Equal(t, stackitem.Make(tc.num), actual)
|
require.Equal(t, stackitem.Make(tc.num), actual)
|
||||||
|
|
||||||
|
if tc.base.Int64() == 10 {
|
||||||
|
require.NotPanics(t, func() {
|
||||||
|
actual = s.itoa10(ic, []stackitem.Item{stackitem.Make(tc.num)})
|
||||||
|
})
|
||||||
|
require.Equal(t, stackitem.Make(tc.result), actual)
|
||||||
|
|
||||||
|
require.NotPanics(t, func() {
|
||||||
|
actual = s.atoi10(ic, []stackitem.Item{stackitem.Make(tc.result)})
|
||||||
|
})
|
||||||
|
require.Equal(t, stackitem.Make(tc.num), actual)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("-1", func(t *testing.T) {
|
t.Run("-1", func(t *testing.T) {
|
||||||
|
|
|
@ -93,9 +93,23 @@ func Itoa(num int, base int) string {
|
||||||
num, base).(string)
|
num, base).(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Itoa10 converts num in a base 10 to string.
|
||||||
|
// It uses `itoa` method of StdLib native contract.
|
||||||
|
func Itoa10(num int) string {
|
||||||
|
return contract.Call(interop.Hash160(Hash), "itoa", contract.NoneFlag,
|
||||||
|
num).(string)
|
||||||
|
}
|
||||||
|
|
||||||
// Atoi converts string to a number in a given base. Base should be either 10 or 16.
|
// Atoi converts string to a number in a given base. Base should be either 10 or 16.
|
||||||
// It uses `atoi` method of StdLib native contract.
|
// It uses `atoi` method of StdLib native contract.
|
||||||
func Atoi(s string, base int) int {
|
func Atoi(s string, base int) int {
|
||||||
return contract.Call(interop.Hash160(Hash), "atoi", contract.NoneFlag,
|
return contract.Call(interop.Hash160(Hash), "atoi", contract.NoneFlag,
|
||||||
s, base).(int)
|
s, base).(int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Atoi10 converts string to a number in a base 10.
|
||||||
|
// It uses `atoi` method of StdLib native contract.
|
||||||
|
func Atoi10(s string) int {
|
||||||
|
return contract.Call(interop.Hash160(Hash), "atoi", contract.NoneFlag,
|
||||||
|
s).(int)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue