mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2025-01-11 11:20:38 +00:00
core: adjust System.Enumerator.Create interop
Part of #1201. It should be able to create enumerator from primitive byte-array-like stack items too.
This commit is contained in:
parent
d6342ab68c
commit
459ac34839
4 changed files with 47 additions and 10 deletions
|
@ -10,7 +10,7 @@ func Concat(_ *interop.Context, v *vm.VM) error {
|
||||||
return vm.EnumeratorConcat(v)
|
return vm.EnumeratorConcat(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates an enumerator from an array-like stack item.
|
// Create creates an enumerator from an array-like or bytearray-like stack item.
|
||||||
func Create(_ *interop.Context, v *vm.VM) error {
|
func Create(_ *interop.Context, v *vm.VM) error {
|
||||||
return vm.EnumeratorCreate(v)
|
return vm.EnumeratorCreate(v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,11 @@ package enumerator
|
||||||
// or structures that have values with no explicit keys.
|
// or structures that have values with no explicit keys.
|
||||||
type Enumerator struct{}
|
type Enumerator struct{}
|
||||||
|
|
||||||
// Create creates a new enumerator from the given items (slice or structure).
|
// Create creates a new enumerator from the given items (slice, structure, byte
|
||||||
// New enumerator points at index -1 of its items, so the user of it has to
|
// array and integer or boolean converted to byte array). New enumerator points
|
||||||
// advance it first with Next. This function uses `System.Enumerator.Create`
|
// at index -1 of its items, so the user of it has to advance it first with Next.
|
||||||
// syscall.
|
// This function uses `System.Enumerator.Create` syscall.
|
||||||
func Create(items []interface{}) Enumerator {
|
func Create(items interface{}) Enumerator {
|
||||||
return Enumerator{}
|
return Enumerator{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,12 +126,25 @@ func init() {
|
||||||
|
|
||||||
// EnumeratorCreate handles syscall System.Enumerator.Create.
|
// EnumeratorCreate handles syscall System.Enumerator.Create.
|
||||||
func EnumeratorCreate(v *VM) error {
|
func EnumeratorCreate(v *VM) error {
|
||||||
data := v.Estack().Pop().Array()
|
var interop interface{}
|
||||||
v.Estack().Push(&Element{
|
switch t := v.Estack().Pop().value.(type) {
|
||||||
value: stackitem.NewInterop(&arrayWrapper{
|
case *stackitem.Array, *stackitem.Struct:
|
||||||
|
interop = &arrayWrapper{
|
||||||
|
index: -1,
|
||||||
|
value: t.Value().([]stackitem.Item),
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
data, err := t.TryBytes()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("can not create enumerator from type %s: %v", t.Type(), err)
|
||||||
|
}
|
||||||
|
interop = &byteArrayWrapper{
|
||||||
index: -1,
|
index: -1,
|
||||||
value: data,
|
value: data,
|
||||||
}),
|
}
|
||||||
|
}
|
||||||
|
v.Estack().Push(&Element{
|
||||||
|
value: stackitem.NewInterop(interop),
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package vm
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,6 +17,11 @@ type (
|
||||||
value []stackitem.Item
|
value []stackitem.Item
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byteArrayWrapper struct {
|
||||||
|
index int
|
||||||
|
value []byte
|
||||||
|
}
|
||||||
|
|
||||||
concatEnum struct {
|
concatEnum struct {
|
||||||
current enumerator
|
current enumerator
|
||||||
second enumerator
|
second enumerator
|
||||||
|
@ -63,6 +70,23 @@ func (a *arrayWrapper) Key() stackitem.Item {
|
||||||
return stackitem.Make(a.index)
|
return stackitem.Make(a.index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *byteArrayWrapper) Next() bool {
|
||||||
|
if next := a.index + 1; next < len(a.value) {
|
||||||
|
a.index = next
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *byteArrayWrapper) Value() stackitem.Item {
|
||||||
|
return stackitem.NewBigInteger(big.NewInt(int64(a.value[a.index])))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *byteArrayWrapper) Key() stackitem.Item {
|
||||||
|
return stackitem.Make(a.index)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *concatEnum) Next() bool {
|
func (c *concatEnum) Next() bool {
|
||||||
if c.current.Next() {
|
if c.current.Next() {
|
||||||
return true
|
return true
|
||||||
|
|
Loading…
Reference in a new issue