1
0
mirror of https://github.com/json-iterator/go.git synced 2024-11-24 08:22:14 +02:00
json-iterator/iter_skip.go

130 lines
3.2 KiB
Go
Raw Normal View History

2017-01-18 17:33:40 +02:00
package jsoniter
import "fmt"
// ReadNil reads a json object as nil and
// returns whether it's a nil or not
func (iter *Iterator) ReadNil() (ret bool) {
c := iter.nextToken()
if c == 'n' {
2017-07-10 09:23:35 +02:00
iter.skipThreeBytes('u', 'l', 'l') // null
2017-01-18 17:33:40 +02:00
return true
}
iter.unreadByte()
return false
}
// ReadBool reads a json object as BoolValue
2017-01-18 17:33:40 +02:00
func (iter *Iterator) ReadBool() (ret bool) {
c := iter.nextToken()
if c == 't' {
2017-07-10 09:23:35 +02:00
iter.skipThreeBytes('r', 'u', 'e')
2017-01-18 17:33:40 +02:00
return true
}
if c == 'f' {
2017-07-10 09:23:35 +02:00
iter.skipFourBytes('a', 'l', 's', 'e')
2017-01-18 17:33:40 +02:00
return false
}
2017-10-10 02:57:02 +02:00
iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c}))
2017-01-18 17:33:40 +02:00
return
}
2017-07-09 10:09:23 +02:00
// SkipAndReturnBytes skip next JSON element, and return its content as []byte.
// The []byte can be kept, it is a copy of data.
2017-05-24 10:04:11 +02:00
func (iter *Iterator) SkipAndReturnBytes() []byte {
2017-06-18 11:00:28 +02:00
iter.startCapture(iter.head)
2017-05-24 10:04:11 +02:00
iter.Skip()
return iter.stopCapture()
}
type captureBuffer struct {
startedAt int
captured []byte
}
2017-06-18 11:00:28 +02:00
func (iter *Iterator) startCapture(captureStartedAt int) {
if iter.captured != nil {
panic("already in capture mode")
}
2017-06-18 11:00:28 +02:00
iter.captureStartedAt = captureStartedAt
iter.captured = make([]byte, 0, 32)
}
func (iter *Iterator) stopCapture() []byte {
if iter.captured == nil {
panic("not in capture mode")
}
captured := iter.captured
2017-06-19 17:43:53 +02:00
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
}
2017-07-09 10:09:23 +02:00
captured = append(captured, remaining...)
return captured
2017-05-24 10:04:11 +02:00
}
2017-01-18 17:33:40 +02:00
// Skip skips a json object and positions to relatively the next json object
func (iter *Iterator) Skip() {
c := iter.nextToken()
switch c {
case '"':
iter.skipString()
2017-07-10 09:23:35 +02:00
case 'n':
iter.skipThreeBytes('u', 'l', 'l') // null
case 't':
iter.skipThreeBytes('r', 'u', 'e') // true
2017-01-18 17:33:40 +02:00
case 'f':
2017-07-10 09:23:35 +02:00
iter.skipFourBytes('a', 'l', 's', 'e') // false
2017-07-18 05:23:29 +02:00
case '0':
iter.unreadByte()
iter.ReadFloat32()
case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9':
2017-06-18 11:00:28 +02:00
iter.skipNumber()
2017-01-18 17:33:40 +02:00
case '[':
2017-07-18 03:45:25 +02:00
iter.skipArray()
2017-01-18 17:33:40 +02:00
case '{':
2017-07-18 03:45:25 +02:00
iter.skipObject()
2017-01-18 17:33:40 +02:00
default:
2017-06-20 09:11:01 +02:00
iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c))
2017-01-18 17:33:40 +02:00
return
}
}
2017-07-10 09:23:35 +02:00
func (iter *Iterator) skipFourBytes(b1, b2, b3, b4 byte) {
if iter.readByte() != b1 {
iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
return
}
if iter.readByte() != b2 {
iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
return
}
if iter.readByte() != b3 {
iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
return
}
if iter.readByte() != b4 {
iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
return
}
}
func (iter *Iterator) skipThreeBytes(b1, b2, b3 byte) {
if iter.readByte() != b1 {
iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
return
}
if iter.readByte() != b2 {
iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
return
}
if iter.readByte() != b3 {
iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
return
2017-01-18 17:33:40 +02:00
}
2017-06-06 17:27:00 +02:00
}