Ver Fonte

#30 support json.Number

Tao Wen há 8 anos atrás
pai
commit
ad3a7fde32
3 ficheiros alterados com 38 adições e 0 exclusões
  1. 8 0
      feature_reflect.go
  2. 19 0
      feature_reflect_native.go
  3. 11 0
      jsoniter_int_test.go

+ 8 - 0
feature_reflect.go

@@ -72,6 +72,7 @@ var fieldDecoders map[string]Decoder
 var typeEncoders map[string]Encoder
 var fieldEncoders map[string]Encoder
 var extensions []ExtensionFunc
+var jsonNumberType reflect.Type
 var anyType reflect.Type
 var marshalerType reflect.Type
 var unmarshalerType reflect.Type
@@ -84,6 +85,7 @@ func init() {
 	extensions = []ExtensionFunc{}
 	atomic.StorePointer(&DECODERS, unsafe.Pointer(&map[string]Decoder{}))
 	atomic.StorePointer(&ENCODERS, unsafe.Pointer(&map[string]Encoder{}))
+	jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem()
 	anyType = reflect.TypeOf((*Any)(nil)).Elem()
 	marshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
 	unmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
@@ -333,6 +335,9 @@ func decoderOfType(typ reflect.Type) (Decoder, error) {
 }
 
 func createDecoderOfType(typ reflect.Type) (Decoder, error) {
+	if typ.ConvertibleTo(jsonNumberType) {
+		return &jsonNumberCodec{}, nil
+	}
 	if typ.ConvertibleTo(anyType) {
 		return &anyCodec{}, nil
 	}
@@ -414,6 +419,9 @@ func encoderOfType(typ reflect.Type) (Encoder, error) {
 }
 
 func createEncoderOfType(typ reflect.Type) (Encoder, error) {
+	if typ.ConvertibleTo(jsonNumberType) {
+		return &jsonNumberCodec{}, nil
+	}
 	if typ.ConvertibleTo(anyType) {
 		return &anyCodec{}, nil
 	}

+ 19 - 0
feature_reflect_native.go

@@ -341,6 +341,25 @@ func (encoder *anyCodec) isEmpty(ptr unsafe.Pointer) bool {
 	return (*((*Any)(ptr))).Size() == 0
 }
 
+type jsonNumberCodec struct {
+}
+
+func (codec *jsonNumberCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString()))
+}
+
+func (codec *jsonNumberCodec) encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteRaw(string(*((*json.Number)(ptr))))
+}
+
+func (encoder *jsonNumberCodec) encodeInterface(val interface{}, stream *Stream) {
+	stream.WriteRaw(string(val.(json.Number)))
+}
+
+func (encoder *jsonNumberCodec) isEmpty(ptr unsafe.Pointer) bool {
+	return len(*((*json.Number)(ptr))) == 0
+}
+
 type stringNumberDecoder struct {
 	elemDecoder Decoder
 }

+ 11 - 0
jsoniter_int_test.go

@@ -421,6 +421,17 @@ func Test_write_val_int_ptr(t *testing.T) {
 	should.Equal("1001", buf.String())
 }
 
+func Test_json_number(t *testing.T) {
+	should := require.New(t)
+	var arr []json.Number
+	err := Unmarshal([]byte(`[1]`), &arr)
+	should.Nil(err)
+	should.Equal(json.Number("1"), arr[0])
+	str, err := MarshalToString(arr)
+	should.Nil(err)
+	should.Equal(`[1]`, str)
+}
+
 func Benchmark_jsoniter_encode_int(b *testing.B) {
 	stream := NewStream(ioutil.Discard, 64)
 	for n := 0; n < b.N; n++ {