1
0
mirror of https://github.com/json-iterator/go.git synced 2025-02-13 19:41:56 +02:00

#62 SkipAndReturnBytes should support reader

This commit is contained in:
Tao Wen 2017-06-18 16:28:43 +08:00
parent 7a049ec79c
commit 54dbcda64d
3 changed files with 56 additions and 6 deletions

View File

@ -70,6 +70,8 @@ type Iterator struct {
buf []byte
head int
tail int
captureStartedAt int
captured []byte
Error error
}
@ -212,6 +214,11 @@ func (iter *Iterator) loadMore() bool {
}
return false
}
if iter.captureStartedAt != -1 {
iter.captured = append(iter.captured,
iter.buf[iter.captureStartedAt:iter.tail]...)
iter.captureStartedAt = 0
}
for {
n, err := iter.reader.Read(iter.buf)
if n == 0 {

View File

@ -30,13 +30,38 @@ func (iter *Iterator) ReadBool() (ret bool) {
}
func (iter *Iterator) SkipAndReturnBytes() []byte {
if iter.reader != nil {
panic("reader input does not support this api")
}
before := iter.head
iter.startCapture()
iter.Skip()
after := iter.head
return iter.buf[before:after]
return iter.stopCapture()
}
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

View File

@ -3,6 +3,8 @@ package jsoniter
import (
"encoding/json"
"testing"
"github.com/json-iterator/go/require"
"bytes"
)
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 {
Code uint64
}