mirror of
https://github.com/json-iterator/go.git
synced 2025-04-23 11:37:32 +02:00
array lazy iterator
This commit is contained in:
parent
8656482625
commit
fa165c684f
@ -13,6 +13,7 @@ type Any interface {
|
|||||||
Size() int
|
Size() int
|
||||||
Keys() []string
|
Keys() []string
|
||||||
IterateObject() (func() (string, Any, bool), bool)
|
IterateObject() (func() (string, Any, bool), bool)
|
||||||
|
IterateArray() (func() (Any, bool), bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
type baseAny struct {}
|
type baseAny struct {}
|
||||||
@ -29,6 +30,10 @@ func (any *baseAny) IterateObject() (func() (string, Any, bool), bool) {
|
|||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (any *baseAny) IterateArray() (func() (Any, bool), bool) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
func (iter *Iterator) ReadAny() Any {
|
func (iter *Iterator) ReadAny() Any {
|
||||||
return iter.readAny(nil)
|
return iter.readAny(nil)
|
||||||
}
|
}
|
||||||
|
@ -125,3 +125,59 @@ func (any *arrayLazyAny) Size() int {
|
|||||||
any.fillCache()
|
any.fillCache()
|
||||||
return len(any.cache)
|
return len(any.cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) IterateArray() (func() (Any, bool), bool) {
|
||||||
|
remaining := any.remaining
|
||||||
|
if len(remaining) == len(any.buf) {
|
||||||
|
iter := any.parse()
|
||||||
|
iter.head++
|
||||||
|
c := iter.nextToken()
|
||||||
|
if c != ']' {
|
||||||
|
iter.unreadByte()
|
||||||
|
v := iter.readAny(iter)
|
||||||
|
any.cache = append(any.cache, v)
|
||||||
|
remaining = iter.buf[iter.head:]
|
||||||
|
any.remaining = remaining
|
||||||
|
} else {
|
||||||
|
remaining = nil
|
||||||
|
any.remaining = nil
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(any.cache) == 0 {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
arr := any.cache
|
||||||
|
nextValue := arr[0]
|
||||||
|
i := 1
|
||||||
|
return func() (Any, bool) {
|
||||||
|
value := nextValue
|
||||||
|
if i < len(arr) {
|
||||||
|
// read from cache
|
||||||
|
nextValue = arr[i]
|
||||||
|
i++
|
||||||
|
return value, true
|
||||||
|
} else {
|
||||||
|
// read from buffer
|
||||||
|
iter := any.iter
|
||||||
|
if iter == nil {
|
||||||
|
iter = NewIterator()
|
||||||
|
any.iter = iter
|
||||||
|
}
|
||||||
|
iter.ResetBytes(remaining)
|
||||||
|
c := iter.nextToken()
|
||||||
|
if c == ',' {
|
||||||
|
nextValue = iter.readAny(iter)
|
||||||
|
any.cache = append(any.cache, nextValue)
|
||||||
|
remaining = iter.buf[iter.head:]
|
||||||
|
any.remaining = remaining
|
||||||
|
return value, true
|
||||||
|
} else {
|
||||||
|
remaining = nil
|
||||||
|
any.remaining = nil
|
||||||
|
return value, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, true
|
||||||
|
}
|
||||||
|
@ -146,6 +146,7 @@ func (any *objectLazyAny) Keys() []string {
|
|||||||
}
|
}
|
||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *objectLazyAny) IterateObject() (func() (string, Any, bool), bool) {
|
func (any *objectLazyAny) IterateObject() (func() (string, Any, bool), bool) {
|
||||||
if any.cache == nil {
|
if any.cache == nil {
|
||||||
any.cache = map[string]Any{}
|
any.cache = map[string]Any{}
|
||||||
|
@ -67,6 +67,19 @@ func Test_read_two_element_array_as_any(t *testing.T) {
|
|||||||
should.Equal(2, any.Size())
|
should.Equal(2, any.Size())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_read_array_with_any_iterator(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
any, err := UnmarshalAnyFromString("[1,2]")
|
||||||
|
should.Nil(err)
|
||||||
|
var element Any
|
||||||
|
var elements []int
|
||||||
|
for next, hasNext := any.IterateArray(); hasNext; {
|
||||||
|
element, hasNext = next()
|
||||||
|
elements = append(elements, element.ToInt())
|
||||||
|
}
|
||||||
|
should.Equal([]int{1, 2}, elements)
|
||||||
|
}
|
||||||
|
|
||||||
func Test_invalid_array(t *testing.T) {
|
func Test_invalid_array(t *testing.T) {
|
||||||
_, err := UnmarshalAnyFromString("[")
|
_, err := UnmarshalAnyFromString("[")
|
||||||
if err == nil || err == io.EOF {
|
if err == nil || err == io.EOF {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user