mirror of
https://github.com/json-iterator/go.git
synced 2025-03-26 21:12:40 +02:00
optimize read string
This commit is contained in:
parent
71cdbd249c
commit
3e376c671c
123
jsoniter.go
123
jsoniter.go
@ -304,55 +304,6 @@ func (iter *Iterator) ReadString() (ret string) {
|
|||||||
return string(iter.ReadStringAsBytes())
|
return string(iter.ReadStringAsBytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// adapted from: https://github.com/buger/jsonparser/blob/master/parser.go
|
|
||||||
// Tries to find the end of string
|
|
||||||
// Support if string contains escaped quote symbols.
|
|
||||||
func (iter *Iterator) findStringEnd() (int, bool) {
|
|
||||||
escaped := false
|
|
||||||
for i := iter.head; i < iter.tail; i++ {
|
|
||||||
c := iter.buf[i]
|
|
||||||
if c == '"' {
|
|
||||||
if !escaped {
|
|
||||||
return i + 1, false
|
|
||||||
} else {
|
|
||||||
j := i - 1
|
|
||||||
for {
|
|
||||||
if j < iter.head || iter.buf[j] != '\\' {
|
|
||||||
// even number of backslashes
|
|
||||||
// either end of buffer, or " found
|
|
||||||
return i + 1, true
|
|
||||||
}
|
|
||||||
j--
|
|
||||||
if j < iter.head || iter.buf[j] != '\\' {
|
|
||||||
// odd number of backslashes
|
|
||||||
// it is \" or \\\"
|
|
||||||
break
|
|
||||||
}
|
|
||||||
j--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if c == '\\' {
|
|
||||||
escaped = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
j := iter.tail - 1
|
|
||||||
for {
|
|
||||||
if j < iter.head || iter.buf[j] != '\\' {
|
|
||||||
// even number of backslashes
|
|
||||||
// either end of buffer, or " found
|
|
||||||
return -1, false // do not end with \
|
|
||||||
}
|
|
||||||
j--
|
|
||||||
if j < iter.head || iter.buf[j] != '\\' {
|
|
||||||
// odd number of backslashes
|
|
||||||
// it is \" or \\\"
|
|
||||||
break
|
|
||||||
}
|
|
||||||
j--
|
|
||||||
|
|
||||||
}
|
|
||||||
return -1, true // end with \
|
|
||||||
}
|
|
||||||
|
|
||||||
func (iter *Iterator) ReadStringAsBytes() (ret []byte) {
|
func (iter *Iterator) ReadStringAsBytes() (ret []byte) {
|
||||||
c := iter.readByte()
|
c := iter.readByte()
|
||||||
@ -364,8 +315,8 @@ func (iter *Iterator) ReadStringAsBytes() (ret []byte) {
|
|||||||
iter.ReportError("ReadString", `expects " or n`)
|
iter.ReportError("ReadString", `expects " or n`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
end, escaped := iter.findStringEnd()
|
end := iter.findStringEndWithoutEscape()
|
||||||
if end != -1 && !escaped {
|
if end != -1 {
|
||||||
// fast path: reuse the underlying buffer
|
// fast path: reuse the underlying buffer
|
||||||
ret = iter.buf[iter.head:end-1]
|
ret = iter.buf[iter.head:end-1]
|
||||||
iter.head = end
|
iter.head = end
|
||||||
@ -726,15 +677,9 @@ func (iter *Iterator) ReadBool() (ret bool) {
|
|||||||
switch c {
|
switch c {
|
||||||
case 't':
|
case 't':
|
||||||
iter.skipUntilBreak()
|
iter.skipUntilBreak()
|
||||||
if iter.Error != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
case 'f':
|
case 'f':
|
||||||
iter.skipUntilBreak()
|
iter.skipUntilBreak()
|
||||||
if iter.Error != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
default:
|
default:
|
||||||
iter.ReportError("ReadBool", "expect t or f")
|
iter.ReportError("ReadBool", "expect t or f")
|
||||||
@ -786,6 +731,70 @@ func (iter *Iterator) skipString() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// adapted from: https://github.com/buger/jsonparser/blob/master/parser.go
|
||||||
|
// Tries to find the end of string
|
||||||
|
// Support if string contains escaped quote symbols.
|
||||||
|
func (iter *Iterator) findStringEnd() (int, bool) {
|
||||||
|
escaped := false
|
||||||
|
for i := iter.head; i < iter.tail; i++ {
|
||||||
|
c := iter.buf[i]
|
||||||
|
if c == '"' {
|
||||||
|
if !escaped {
|
||||||
|
return i + 1, false
|
||||||
|
} else {
|
||||||
|
j := i - 1
|
||||||
|
for {
|
||||||
|
if j < iter.head || iter.buf[j] != '\\' {
|
||||||
|
// even number of backslashes
|
||||||
|
// either end of buffer, or " found
|
||||||
|
return i + 1, true
|
||||||
|
}
|
||||||
|
j--
|
||||||
|
if j < iter.head || iter.buf[j] != '\\' {
|
||||||
|
// odd number of backslashes
|
||||||
|
// it is \" or \\\"
|
||||||
|
break
|
||||||
|
}
|
||||||
|
j--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if c == '\\' {
|
||||||
|
escaped = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
j := iter.tail - 1
|
||||||
|
for {
|
||||||
|
if j < iter.head || iter.buf[j] != '\\' {
|
||||||
|
// even number of backslashes
|
||||||
|
// either end of buffer, or " found
|
||||||
|
return -1, false // do not end with \
|
||||||
|
}
|
||||||
|
j--
|
||||||
|
if j < iter.head || iter.buf[j] != '\\' {
|
||||||
|
// odd number of backslashes
|
||||||
|
// it is \" or \\\"
|
||||||
|
break
|
||||||
|
}
|
||||||
|
j--
|
||||||
|
|
||||||
|
}
|
||||||
|
return -1, true // end with \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (iter *Iterator) findStringEndWithoutEscape() int {
|
||||||
|
for i := iter.head; i < iter.tail; i++ {
|
||||||
|
c := iter.buf[i]
|
||||||
|
if c == '"' {
|
||||||
|
return i + 1
|
||||||
|
} else if c == '\\' {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
func (iter *Iterator) skipArray() {
|
func (iter *Iterator) skipArray() {
|
||||||
level := 1
|
level := 1
|
||||||
for {
|
for {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user