You've already forked json-iterator
mirror of
https://github.com/json-iterator/go.git
synced 2025-06-15 22:50:24 +02:00
#62 SkipAndReturnBytes should support reader
This commit is contained in:
@ -70,6 +70,8 @@ type Iterator struct {
|
|||||||
buf []byte
|
buf []byte
|
||||||
head int
|
head int
|
||||||
tail int
|
tail int
|
||||||
|
captureStartedAt int
|
||||||
|
captured []byte
|
||||||
Error error
|
Error error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,6 +214,11 @@ func (iter *Iterator) loadMore() bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if iter.captureStartedAt != -1 {
|
||||||
|
iter.captured = append(iter.captured,
|
||||||
|
iter.buf[iter.captureStartedAt:iter.tail]...)
|
||||||
|
iter.captureStartedAt = 0
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
n, err := iter.reader.Read(iter.buf)
|
n, err := iter.reader.Read(iter.buf)
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
|
@ -30,13 +30,38 @@ func (iter *Iterator) ReadBool() (ret bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (iter *Iterator) SkipAndReturnBytes() []byte {
|
func (iter *Iterator) SkipAndReturnBytes() []byte {
|
||||||
if iter.reader != nil {
|
iter.startCapture()
|
||||||
panic("reader input does not support this api")
|
|
||||||
}
|
|
||||||
before := iter.head
|
|
||||||
iter.Skip()
|
iter.Skip()
|
||||||
after := iter.head
|
return iter.stopCapture()
|
||||||
return iter.buf[before:after]
|
}
|
||||||
|
|
||||||
|
type captureBuffer struct {
|
||||||
|
startedAt int
|
||||||
|
captured []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) startCapture() {
|
||||||
|
if iter.captured != nil {
|
||||||
|
panic("already in capture mode")
|
||||||
|
}
|
||||||
|
iter.captureStartedAt = iter.head
|
||||||
|
iter.captured = make([]byte, 0, 32)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) stopCapture() []byte {
|
||||||
|
if iter.captured == nil {
|
||||||
|
panic("not in capture mode")
|
||||||
|
}
|
||||||
|
captured := iter.captured
|
||||||
|
remaining := iter.buf[iter.captureStartedAt: iter.head]
|
||||||
|
iter.captureStartedAt = -1
|
||||||
|
iter.captured = nil
|
||||||
|
if len(captured) == 0 {
|
||||||
|
return remaining
|
||||||
|
} else {
|
||||||
|
captured = append(captured, remaining...)
|
||||||
|
return captured
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip skips a json object and positions to relatively the next json object
|
// Skip skips a json object and positions to relatively the next json object
|
||||||
|
@ -3,6 +3,8 @@ package jsoniter
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
"github.com/json-iterator/go/require"
|
||||||
|
"bytes"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_skip_number(t *testing.T) {
|
func Test_skip_number(t *testing.T) {
|
||||||
@ -75,6 +77,22 @@ func Test_skip_nested(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_skip_and_return_bytes(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
iter := ParseString(ConfigDefault, `[ {"a" : [{"b": "c"}], "d": 102 }, "b"]`)
|
||||||
|
iter.ReadArray()
|
||||||
|
skipped := iter.SkipAndReturnBytes()
|
||||||
|
should.Equal(`{"a" : [{"b": "c"}], "d": 102 }`, string(skipped))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_skip_and_return_bytes_with_reader(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
iter := Parse(ConfigDefault, bytes.NewBufferString(`[ {"a" : [{"b": "c"}], "d": 102 }, "b"]`), 4)
|
||||||
|
iter.ReadArray()
|
||||||
|
skipped := iter.SkipAndReturnBytes()
|
||||||
|
should.Equal(`{"a" : [{"b": "c"}], "d": 102 }`, string(skipped))
|
||||||
|
}
|
||||||
|
|
||||||
type TestResp struct {
|
type TestResp struct {
|
||||||
Code uint64
|
Code uint64
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user