diff --git a/iter_skip.go b/iter_skip.go index f58beb91..e91eefb1 100644 --- a/iter_skip.go +++ b/iter_skip.go @@ -37,17 +37,24 @@ func (iter *Iterator) SkipAndReturnBytes() []byte { return iter.stopCapture() } -type captureBuffer struct { - startedAt int - captured []byte +// SkipAndAppendBytes skips next JSON element and appends its content to +// buffer, returning the result. +func (iter *Iterator) SkipAndAppendBytes(buf []byte) []byte { + iter.startCaptureTo(buf, iter.head) + iter.Skip() + return iter.stopCapture() } -func (iter *Iterator) startCapture(captureStartedAt int) { +func (iter *Iterator) startCaptureTo(buf []byte, captureStartedAt int) { if iter.captured != nil { panic("already in capture mode") } iter.captureStartedAt = captureStartedAt - iter.captured = make([]byte, 0, 32) + iter.captured = buf +} + +func (iter *Iterator) startCapture(captureStartedAt int) { + iter.startCaptureTo(make([]byte, 0, 32), captureStartedAt) } func (iter *Iterator) stopCapture() []byte { @@ -58,13 +65,7 @@ func (iter *Iterator) stopCapture() []byte { remaining := iter.buf[iter.captureStartedAt:iter.head] iter.captureStartedAt = -1 iter.captured = nil - if len(captured) == 0 { - copied := make([]byte, len(remaining)) - copy(copied, remaining) - return copied - } - captured = append(captured, remaining...) - return captured + return append(captured, remaining...) } // Skip skips a json object and positions to relatively the next json object diff --git a/skip_tests/jsoniter_skip_test.go b/skip_tests/jsoniter_skip_test.go index bf054d1c..785899a9 100644 --- a/skip_tests/jsoniter_skip_test.go +++ b/skip_tests/jsoniter_skip_test.go @@ -105,6 +105,15 @@ func Test_skip_and_return_bytes_with_reader(t *testing.T) { should.Equal(`{"a" : [{"stream": "c"}], "d": 102 }`, string(skipped)) } +func Test_append_skip_and_return_bytes_with_reader(t *testing.T) { + should := require.New(t) + iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(`[ {"a" : [{"stream": "c"}], "d": 102 }, "stream"]`), 4) + iter.ReadArray() + buf := make([]byte, 0, 1024) + buf = iter.SkipAndAppendBytes(buf) + should.Equal(`{"a" : [{"stream": "c"}], "d": 102 }`, string(buf)) +} + func Test_skip_empty(t *testing.T) { should := require.New(t) should.NotNil(jsoniter.Get([]byte("")).LastError())