neo-go/pkg/core/interop/iterator/interop.go
2022-07-08 17:05:18 +03:00

60 lines
1.8 KiB
Go

package iterator
import (
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)
type iterator interface {
Next() bool
Value() stackitem.Item
}
// Next advances the iterator, pushes true on success and false otherwise.
func Next(ic *interop.Context) error {
iop := ic.VM.Estack().Pop().Interop()
arr := iop.Value().(iterator)
ic.VM.Estack().PushItem(stackitem.Bool(arr.Next()))
return nil
}
// Value returns current iterator value and depends on iterator type:
// For slices the result is just value.
// For maps the result is key-value pair packed in a struct.
func Value(ic *interop.Context) error {
iop := ic.VM.Estack().Pop().Interop()
arr := iop.Value().(iterator)
ic.VM.Estack().PushItem(arr.Value())
return nil
}
// IsIterator returns whether stackitem implements iterator interface.
func IsIterator(item stackitem.Item) bool {
_, ok := item.Value().(iterator)
return ok
}
// ValuesTruncated returns an array of up to `max` iterator values. The second
// return parameter denotes whether iterator is truncated, i.e. has more values.
// The provided iterator CAN NOT be reused in the subsequent calls to Values and
// to ValuesTruncated.
func ValuesTruncated(item stackitem.Item, max int) ([]stackitem.Item, bool) {
result := Values(item, max)
arr := item.Value().(iterator)
return result, arr.Next()
}
// Values returns an array of up to `max` iterator values. The provided
// iterator can safely be reused to retrieve the rest of its values in the
// subsequent calls to Values and to ValuesTruncated.
func Values(item stackitem.Item, max int) []stackitem.Item {
var result []stackitem.Item
arr := item.Value().(iterator)
for max > 0 && arr.Next() {
result = append(result, arr.Value())
max--
}
return result
}