Explorar el Código

#50 map key unlike object field, can contain escaped char

Tao Wen hace 8 años
padre
commit
3307ce3ba2
Se han modificado 3 ficheros con 68 adiciones y 2 borrados
  1. 41 1
      feature_iter_object.go
  2. 1 1
      feature_reflect_map.go
  3. 26 0
      jsoniter_map_test.go

+ 41 - 1
feature_iter_object.go

@@ -84,7 +84,7 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
 				return false
 			}
 			for iter.nextToken() == ',' {
-				field := string(iter.readObjectFieldAsBytes())
+				field = string(iter.readObjectFieldAsBytes())
 				if !callback(iter, field) {
 					return false
 				}
@@ -105,6 +105,46 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
 	return false
 }
 
+func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
+	c := iter.nextToken()
+	if c == '{' {
+		c = iter.nextToken()
+		if c == '"' {
+			iter.unreadByte()
+			field := iter.ReadString()
+			if iter.nextToken() != ':' {
+				iter.reportError("ReadMapCB", "expect : after object field")
+				return false
+			}
+			if !callback(iter, field) {
+				return false
+			}
+			for iter.nextToken() == ',' {
+				field = iter.ReadString()
+				if iter.nextToken() != ':' {
+					iter.reportError("ReadMapCB", "expect : after object field")
+					return false
+				}
+				if !callback(iter, field) {
+					return false
+				}
+			}
+			return true
+		}
+		if c == '}' {
+			return true
+		}
+		iter.reportError("ReadMapCB", `expect " after }`)
+		return false
+	}
+	if c == 'n' {
+		iter.skipFixedBytes(3)
+		return true // null
+	}
+	iter.reportError("ReadMapCB", `expect { or n`)
+	return false
+}
+
 func (iter *Iterator) readObjectStart() bool {
 	c := iter.nextToken()
 	if c == '{' {

+ 1 - 1
feature_reflect_map.go

@@ -25,7 +25,7 @@ func (decoder *mapDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
 	if realVal.IsNil() {
 		realVal.Set(reflect.MakeMap(realVal.Type()))
 	}
-	iter.ReadObjectCB(func(iter *Iterator, keyStr string) bool {
+	iter.ReadMapCB(func(iter *Iterator, keyStr string) bool {
 		elem := reflect.New(decoder.elemType)
 		decoder.elemDecoder.decode(unsafe.Pointer(elem.Pointer()), iter)
 		// to put into map, we have to use reflection

+ 26 - 0
jsoniter_map_test.go

@@ -4,6 +4,7 @@ import (
 	"github.com/json-iterator/go/require"
 	"math/big"
 	"testing"
+	"encoding/json"
 )
 
 func Test_read_map(t *testing.T) {
@@ -101,3 +102,28 @@ func Test_decode_TextMarshaler_key_map(t *testing.T) {
 	should.Nil(err)
 	should.Equal(`{"1":"2"}`, str)
 }
+
+
+
+func Test_map_key_with_escaped_char(t *testing.T) {
+	type Ttest struct {
+		Map map[string]string
+	}
+	var jsonBytes = []byte(`
+	{
+	    "Map":{
+		"k\"ey": "val"
+	    }
+	}`)
+	should := require.New(t)
+	{
+		var obj Ttest
+		should.Nil(json.Unmarshal(jsonBytes, &obj))
+		should.Equal(map[string]string{"k\"ey":"val"}, obj.Map)
+	}
+	{
+		var obj Ttest
+		should.Nil(Unmarshal(jsonBytes, &obj))
+		should.Equal(map[string]string{"k\"ey":"val"}, obj.Map)
+	}
+}