1
0
mirror of https://github.com/json-iterator/go.git synced 2025-04-14 11:18:49 +02:00

make ReadObject return safe string

This commit is contained in:
Tao Wen 2017-01-20 12:40:52 +08:00
parent a73e48e8bf
commit d14b025931
3 changed files with 33 additions and 23 deletions

View File

@ -1,7 +1,5 @@
package jsoniter package jsoniter
import "unsafe"
// ReadObject is a implemented iterator for json // ReadObject is a implemented iterator for json
func (iter *Iterator) ReadObject() (ret string) { func (iter *Iterator) ReadObject() (ret string) {
c := iter.nextToken() c := iter.nextToken()
@ -25,13 +23,13 @@ func (iter *Iterator) ReadObject() (ret string) {
return "" // end of object return "" // end of object
case '"': case '"':
iter.unreadByte() iter.unreadByte()
return iter.readObjectField() return string(iter.readObjectFieldAsBytes())
default: default:
iter.reportError("ReadObject", `expect " after {`) iter.reportError("ReadObject", `expect " after {`)
return return
} }
case ',': case ',':
return iter.readObjectField() return string(iter.readObjectFieldAsBytes())
case '}': case '}':
return "" // end of object return "" // end of object
default: default:
@ -54,31 +52,33 @@ func (iter *Iterator) readObjectStart() bool {
return false return false
} }
func (iter *Iterator) readObjectField() (ret string) { func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) {
str := iter.ReadStringAsSlice() str := iter.ReadStringAsSlice()
if iter.skipWhitespacesWithoutLoadMore() { if iter.skipWhitespacesWithoutLoadMore() {
if ret == "" { if ret == nil {
ret = string(str) ret = make([]byte, len(str))
copy(ret, str)
} }
if !iter.loadMore() { if !iter.loadMore() {
return return
} }
} }
if iter.buf[iter.head] != ':' { if iter.buf[iter.head] != ':' {
iter.reportError("ReadObject", "expect : after object field") iter.reportError("readObjectFieldAsBytes", "expect : after object field")
return return
} }
iter.head++ iter.head++
if iter.skipWhitespacesWithoutLoadMore() { if iter.skipWhitespacesWithoutLoadMore() {
if ret == "" { if ret == nil {
ret = string(str) ret = make([]byte, len(str))
copy(ret, str)
} }
if !iter.loadMore() { if !iter.loadMore() {
return return
} }
} }
if ret == "" { if ret == nil {
return *(*string)(unsafe.Pointer(&str)) return str
} }
return ret return ret
} }

View File

@ -177,7 +177,8 @@ func (decoder *generalStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator)
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
field := iter.readObjectField() fieldBytes := iter.readObjectFieldAsBytes()
field := *(*string)(unsafe.Pointer(&fieldBytes))
fieldDecoder := decoder.fields[field] fieldDecoder := decoder.fields[field]
if fieldDecoder == nil { if fieldDecoder == nil {
iter.Skip() iter.Skip()
@ -185,7 +186,8 @@ func (decoder *generalStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator)
fieldDecoder.decode(ptr, iter) fieldDecoder.decode(ptr, iter)
} }
for iter.nextToken() == ',' { for iter.nextToken() == ',' {
field = iter.readObjectField() fieldBytes = iter.readObjectFieldAsBytes()
field = *(*string)(unsafe.Pointer(&fieldBytes))
fieldDecoder = decoder.fields[field] fieldDecoder = decoder.fields[field]
if fieldDecoder == nil { if fieldDecoder == nil {
iter.Skip() iter.Skip()
@ -219,14 +221,16 @@ func (decoder *oneFieldStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator)
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
field := iter.readObjectField() fieldBytes := iter.readObjectFieldAsBytes()
field := *(*string)(unsafe.Pointer(&fieldBytes))
if field == decoder.fieldName { if field == decoder.fieldName {
decoder.fieldDecoder.decode(ptr, iter) decoder.fieldDecoder.decode(ptr, iter)
} else { } else {
iter.Skip() iter.Skip()
} }
for iter.nextToken() == ',' { for iter.nextToken() == ',' {
field = iter.readObjectField() fieldBytes = iter.readObjectFieldAsBytes()
field = *(*string)(unsafe.Pointer(&fieldBytes))
if field == decoder.fieldName { if field == decoder.fieldName {
decoder.fieldDecoder.decode(ptr, iter) decoder.fieldDecoder.decode(ptr, iter)
} else { } else {
@ -250,7 +254,8 @@ func (decoder *twoFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
field := iter.readObjectField() fieldBytes := iter.readObjectFieldAsBytes()
field := *(*string)(unsafe.Pointer(&fieldBytes))
switch field { switch field {
case decoder.fieldName1: case decoder.fieldName1:
decoder.fieldDecoder1.decode(ptr, iter) decoder.fieldDecoder1.decode(ptr, iter)
@ -260,7 +265,8 @@ func (decoder *twoFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator
iter.Skip() iter.Skip()
} }
for iter.nextToken() == ',' { for iter.nextToken() == ',' {
field = iter.readObjectField() fieldBytes = iter.readObjectFieldAsBytes()
field = *(*string)(unsafe.Pointer(&fieldBytes))
switch field { switch field {
case decoder.fieldName1: case decoder.fieldName1:
decoder.fieldDecoder1.decode(ptr, iter) decoder.fieldDecoder1.decode(ptr, iter)
@ -289,7 +295,8 @@ func (decoder *threeFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterat
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
field := iter.readObjectField() fieldBytes := iter.readObjectFieldAsBytes()
field := *(*string)(unsafe.Pointer(&fieldBytes))
switch field { switch field {
case decoder.fieldName1: case decoder.fieldName1:
decoder.fieldDecoder1.decode(ptr, iter) decoder.fieldDecoder1.decode(ptr, iter)
@ -301,7 +308,8 @@ func (decoder *threeFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterat
iter.Skip() iter.Skip()
} }
for iter.nextToken() == ',' { for iter.nextToken() == ',' {
field = iter.readObjectField() fieldBytes = iter.readObjectFieldAsBytes()
field = *(*string)(unsafe.Pointer(&fieldBytes))
switch field { switch field {
case decoder.fieldName1: case decoder.fieldName1:
decoder.fieldDecoder1.decode(ptr, iter) decoder.fieldDecoder1.decode(ptr, iter)
@ -334,7 +342,8 @@ func (decoder *fourFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterato
if !iter.readObjectStart() { if !iter.readObjectStart() {
return return
} }
field := iter.readObjectField() fieldBytes := iter.readObjectFieldAsBytes()
field := *(*string)(unsafe.Pointer(&fieldBytes))
switch field { switch field {
case decoder.fieldName1: case decoder.fieldName1:
decoder.fieldDecoder1.decode(ptr, iter) decoder.fieldDecoder1.decode(ptr, iter)
@ -348,7 +357,8 @@ func (decoder *fourFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterato
iter.Skip() iter.Skip()
} }
for iter.nextToken() == ',' { for iter.nextToken() == ',' {
field = iter.readObjectField() fieldBytes = iter.readObjectFieldAsBytes()
field = *(*string)(unsafe.Pointer(&fieldBytes))
switch field { switch field {
case decoder.fieldName1: case decoder.fieldName1:
decoder.fieldDecoder1.decode(ptr, iter) decoder.fieldDecoder1.decode(ptr, iter)

View File

@ -82,7 +82,7 @@ func Test_write_object(t *testing.T) {
stream.WriteObjectEnd() stream.WriteObjectEnd()
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
should.Equal("{\n hello:1,\n world:2\n}", buf.String()) should.Equal("{\n \"hello\":1,\n \"world\":2\n}", buf.String())
} }
type TestObj struct { type TestObj struct {