mirror of
https://github.com/json-iterator/go.git
synced 2025-02-01 19:14:29 +02:00
#31 support json.RawMessage
This commit is contained in:
parent
ad3a7fde32
commit
fe9fa8900e
@ -145,6 +145,9 @@ func (iter *Iterator) readNumberAsString() (ret string) {
|
||||
if iter.Error != nil && iter.Error != io.EOF {
|
||||
return
|
||||
}
|
||||
if len(str) == 0 {
|
||||
iter.reportError("readNumberAsString", "invalid number")
|
||||
}
|
||||
return *(*string)(unsafe.Pointer(&str))
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,7 @@ var typeEncoders map[string]Encoder
|
||||
var fieldEncoders map[string]Encoder
|
||||
var extensions []ExtensionFunc
|
||||
var jsonNumberType reflect.Type
|
||||
var jsonRawMessageType reflect.Type
|
||||
var anyType reflect.Type
|
||||
var marshalerType reflect.Type
|
||||
var unmarshalerType reflect.Type
|
||||
@ -86,6 +87,7 @@ func init() {
|
||||
atomic.StorePointer(&DECODERS, unsafe.Pointer(&map[string]Decoder{}))
|
||||
atomic.StorePointer(&ENCODERS, unsafe.Pointer(&map[string]Encoder{}))
|
||||
jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem()
|
||||
jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
|
||||
anyType = reflect.TypeOf((*Any)(nil)).Elem()
|
||||
marshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
|
||||
unmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
|
||||
@ -335,16 +337,19 @@ func decoderOfType(typ reflect.Type) (Decoder, error) {
|
||||
}
|
||||
|
||||
func createDecoderOfType(typ reflect.Type) (Decoder, error) {
|
||||
if typ.ConvertibleTo(jsonRawMessageType) {
|
||||
return &jsonRawMessageCodec{}, nil
|
||||
}
|
||||
if typ.ConvertibleTo(jsonNumberType) {
|
||||
return &jsonNumberCodec{}, nil
|
||||
}
|
||||
if typ.ConvertibleTo(anyType) {
|
||||
return &anyCodec{}, nil
|
||||
}
|
||||
if typ.ConvertibleTo(unmarshalerType) {
|
||||
templateInterface := reflect.New(typ).Elem().Interface()
|
||||
return &optionalDecoder{typ, &unmarshalerDecoder{extractInterface(templateInterface)}}, nil
|
||||
}
|
||||
if typ.ConvertibleTo(anyType) {
|
||||
return &anyCodec{}, nil
|
||||
}
|
||||
switch typ.Kind() {
|
||||
case reflect.String:
|
||||
return &stringCodec{}, nil
|
||||
@ -419,16 +424,19 @@ func encoderOfType(typ reflect.Type) (Encoder, error) {
|
||||
}
|
||||
|
||||
func createEncoderOfType(typ reflect.Type) (Encoder, error) {
|
||||
if typ.ConvertibleTo(jsonRawMessageType) {
|
||||
return &jsonRawMessageCodec{}, nil
|
||||
}
|
||||
if typ.ConvertibleTo(jsonNumberType) {
|
||||
return &jsonNumberCodec{}, nil
|
||||
}
|
||||
if typ.ConvertibleTo(anyType) {
|
||||
return &anyCodec{}, nil
|
||||
}
|
||||
if typ.ConvertibleTo(marshalerType) {
|
||||
templateInterface := reflect.New(typ).Elem().Interface()
|
||||
return &marshalerEncoder{extractInterface(templateInterface)}, nil
|
||||
}
|
||||
if typ.ConvertibleTo(anyType) {
|
||||
return &anyCodec{}, nil
|
||||
}
|
||||
kind := typ.Kind()
|
||||
switch kind {
|
||||
case reflect.String:
|
||||
|
@ -360,6 +360,25 @@ func (encoder *jsonNumberCodec) isEmpty(ptr unsafe.Pointer) bool {
|
||||
return len(*((*json.Number)(ptr))) == 0
|
||||
}
|
||||
|
||||
type jsonRawMessageCodec struct {
|
||||
}
|
||||
|
||||
func (codec *jsonRawMessageCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
*((*json.RawMessage)(ptr)) = json.RawMessage(iter.SkipAndReturnBytes())
|
||||
}
|
||||
|
||||
func (codec *jsonRawMessageCodec) encode(ptr unsafe.Pointer, stream *Stream) {
|
||||
stream.WriteRaw(string(*((*json.RawMessage)(ptr))))
|
||||
}
|
||||
|
||||
func (encoder *jsonRawMessageCodec) encodeInterface(val interface{}, stream *Stream) {
|
||||
stream.WriteRaw(string(val.(json.RawMessage)))
|
||||
}
|
||||
|
||||
func (encoder *jsonRawMessageCodec) isEmpty(ptr unsafe.Pointer) bool {
|
||||
return len(*((*json.RawMessage)(ptr))) == 0
|
||||
}
|
||||
|
||||
type stringNumberDecoder struct {
|
||||
elemDecoder Decoder
|
||||
}
|
||||
|
@ -253,6 +253,16 @@ func Test_write_array_of_interface_in_struct(t *testing.T) {
|
||||
should.Equal(`{"Field":[1,2],"Field2":""}`, str)
|
||||
}
|
||||
|
||||
func Test_json_RawMessage(t *testing.T) {
|
||||
should := require.New(t)
|
||||
var data json.RawMessage
|
||||
should.Nil(Unmarshal([]byte(`[1,2,3]`), &data))
|
||||
should.Equal(`[1,2,3]`, string(data))
|
||||
str, err := MarshalToString(data)
|
||||
should.Nil(err)
|
||||
should.Equal(`[1,2,3]`, str)
|
||||
}
|
||||
|
||||
func Benchmark_jsoniter_array(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
input := []byte(`[1,2,3,4,5,6,7,8,9]`)
|
||||
|
Loading…
x
Reference in New Issue
Block a user