1
0
mirror of https://github.com/json-iterator/go.git synced 2025-12-05 22:56:06 +02:00

optimize read string

This commit is contained in:
Tao Wen
2016-12-06 14:23:59 +08:00
parent c457aeaac2
commit c44e7c496a
3 changed files with 70 additions and 4 deletions

View File

@@ -271,7 +271,40 @@ func (iter *Iterator) ReadInt64() (ret int64) {
}
func (iter *Iterator) ReadString() (ret string) {
str := make([]byte, 0, 8)
return string(iter.ReadStringAsBytes())
}
// Tries to find the end of string
// Support if string contains escaped quote symbols.
func stringEnd(data []byte) (int, bool) {
escaped := false
for i, c := range data {
if c == '"' {
if !escaped {
return i + 1, false
} else {
j := i - 1
for {
if j < 0 || data[j] != '\\' {
return i + 1, true // even number of backslashes
}
j--
if j < 0 || data[j] != '\\' {
break // odd number of backslashes
}
j--
}
}
} else if c == '\\' {
escaped = true
}
}
return -1, escaped
}
func (iter *Iterator) ReadStringAsBytes() (ret []byte) {
c := iter.readByte()
if c == 'n' {
iter.skipNull()
@@ -281,10 +314,17 @@ func (iter *Iterator) ReadString() (ret string) {
iter.ReportError("ReadString", `expects " or n`)
return
}
end, escaped := stringEnd(iter.buf[iter.head:])
if end != -1 && !escaped {
ret = iter.buf[iter.head:iter.head+end-1]
iter.head += end
return ret
}
str := make([]byte, 0, 8)
for iter.Error == nil {
c = iter.readByte()
if c == '"' {
return string(str)
return str
}
if c == '\\' {
c = iter.readByte()
@@ -543,7 +583,8 @@ func (iter *Iterator) ReadObject() (ret string) {
}
func (iter *Iterator) readObjectField() (ret string) {
field := iter.ReadString()
str := iter.ReadStringAsBytes()
field := *(*string)(unsafe.Pointer(&str))
if iter.Error != nil {
return
}