Prechádzať zdrojové kódy

make ReadObject return safe string

Tao Wen 9 rokov pred
rodič
commit
d14b025931
3 zmenil súbory, kde vykonal 33 pridanie a 23 odobranie
  1. 12 12
      feature_iter_object.go
  2. 20 10
      feature_reflect_object.go
  3. 1 1
      jsoniter_object_test.go

+ 12 - 12
feature_iter_object.go

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

+ 20 - 10
feature_reflect_object.go

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

+ 1 - 1
jsoniter_object_test.go

@@ -82,7 +82,7 @@ func Test_write_object(t *testing.T) {
 	stream.WriteObjectEnd()
 	stream.Flush()
 	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 {