Tao Wen %!s(int64=9) %!d(string=hai) anos
pai
achega
38e256e526
Modificáronse 3 ficheiros con 68 adicións e 21 borrados
  1. 11 1
      jsoniter.go
  2. 18 12
      jsoniter_reflect.go
  3. 39 8
      jsoniter_reflect_test.go

+ 11 - 1
jsoniter.go

@@ -132,6 +132,16 @@ func (iter *Iterator) ReadUint64() (ret uint64) {
 	return ret
 }
 
+func (iter *Iterator) ReadInt() (ret int) {
+	val := iter.ReadInt64()
+	converted := int(val)
+	if int64(converted) != val {
+		iter.ReportError("ReadInt", "int overflow")
+		return
+	}
+	return converted
+}
+
 func (iter *Iterator) ReadInt64() (ret int64) {
 	c := iter.readByte()
 	if iter.Error != nil {
@@ -163,7 +173,7 @@ func (iter *Iterator) ReadString() (ret string) {
 		}
 		return ""
 	case '"':
-		// nothing
+	// nothing
 	default:
 		iter.ReportError("ReadString", `expects " or n`)
 		return

+ 18 - 12
jsoniter_reflect.go

@@ -19,6 +19,13 @@ func (decoder *stringDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*string)(ptr)) = iter.ReadString()
 }
 
+type intDecoder struct {
+}
+
+func (decoder *intDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*int)(ptr)) = iter.ReadInt()
+}
+
 type optionalDecoder struct {
 	valueType reflect.Type
 	valueDecoder Decoder
@@ -115,7 +122,6 @@ func growOne(slice *sliceHeader, sliceType reflect.Type, elementType reflect.Typ
 	slice.Data = dst
 }
 
-var DECODER_STRING *stringDecoder
 var DECODERS unsafe.Pointer
 
 func addDecoderToCache(cacheKey string, decoder Decoder) {
@@ -139,7 +145,6 @@ func getDecoderFromCache(cacheKey string) Decoder {
 }
 
 func init() {
-	DECODER_STRING = &stringDecoder{}
 	atomic.StorePointer(&DECODERS, unsafe.Pointer(&map[string]Decoder{}))
 }
 
@@ -187,25 +192,26 @@ func decoderOfType(type_ reflect.Type) (Decoder, error) {
 func decoderOfPtr(type_ reflect.Type) (Decoder, error) {
 	switch type_.Kind() {
 	case reflect.String:
-		return DECODER_STRING, nil
+		return &stringDecoder{}, nil
+	case reflect.Int:
+		return &intDecoder{}, nil
 	case reflect.Struct:
 		return decoderOfStruct(type_)
 	case reflect.Slice:
-		return decoderOfSlice(type_)
+		return prefix("[slice]").addTo(decoderOfSlice(type_))
 	case reflect.Ptr:
-		return prefix("optional").addTo(decoderOfOptional(type_.Elem()))
+		return prefix("[optional]").addTo(decoderOfOptional(type_.Elem()))
 	default:
-		return nil, errors.New("expect string, struct, slice")
+		return nil, fmt.Errorf("unsupported type: %v", type_)
 	}
 }
 
 func decoderOfOptional(type_ reflect.Type) (Decoder, error) {
-	switch type_.Kind() {
-	case reflect.String:
-		return &optionalDecoder{type_, DECODER_STRING}, nil
-	default:
-		return nil, errors.New("expect string")
+	decoder, err := decoderOfPtr(type_)
+	if err != nil {
+		return nil, err
 	}
+	return &optionalDecoder{type_, decoder}, nil
 }
 
 
@@ -225,7 +231,7 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) {
 func decoderOfSlice(type_ reflect.Type) (Decoder, error) {
 	decoder, err := decoderOfPtr(type_.Elem())
 	if err != nil {
-		return prefix("[elem]").addTo(decoder, err)
+		return nil, err
 	}
 	return &sliceDecoder{type_, type_.Elem(), decoder}, nil
 }

+ 39 - 8
jsoniter_reflect_test.go

@@ -25,6 +25,15 @@ func Test_reflect_ptr_str(t *testing.T) {
 	}
 }
 
+func Test_reflect_int(t *testing.T) {
+	iter := ParseString(`123`)
+	val := int(0)
+	iter.Read(&val)
+	if val != 123 {
+		t.Fatal(val)
+	}
+}
+
 type StructOfString struct {
 	field1 string
 	field2 string
@@ -65,19 +74,41 @@ func Test_reflect_struct_string_ptr(t *testing.T) {
 
 func Test_reflect_slice(t *testing.T) {
 	iter := ParseString(`["hello", "world"]`)
-	array := make([]string, 0, 1)
-	iter.Read(&array)
-	if len(array) != 2 {
+	slice := make([]string, 0, 1)
+	iter.Read(&slice)
+	if len(slice) != 2 {
+		fmt.Println(iter.Error)
+		t.Fatal(len(slice))
+	}
+	if slice[0] != "hello" {
+		fmt.Println(iter.Error)
+		t.Fatal(slice[0])
+	}
+	if slice[1] != "world" {
+		fmt.Println(iter.Error)
+		t.Fatal(slice[1])
+	}
+}
+
+func Test_reflect_nested(t *testing.T) {
+	iter := ParseString(`[{"field1": "hello"}, null, {"field2": "world"}]`)
+	slice := []*StructOfString{}
+	iter.Read(&slice)
+	if len(slice) != 3 {
+		fmt.Println(iter.Error)
+		t.Fatal(len(slice))
+	}
+	if slice[0].field1 != "hello" {
 		fmt.Println(iter.Error)
-		t.Fatal(len(array))
+		t.Fatal(slice[0])
 	}
-	if array[0] != "hello" {
+	if slice[1] != nil {
 		fmt.Println(iter.Error)
-		t.Fatal(array[0])
+		t.Fatal(slice[1])
 	}
-	if array[1] != "world" {
+	if slice[2].field2 != "world" {
 		fmt.Println(iter.Error)
-		t.Fatal(array[1])
+		t.Fatal(slice[1])
 	}
 }