1
0
mirror of https://github.com/json-iterator/go.git synced 2025-02-01 19:14:29 +02:00

# add jsoniter.RawMessage

This commit is contained in:
Tao Wen 2017-06-19 23:10:20 +08:00
parent eecb062c32
commit c6a598e292
5 changed files with 75 additions and 25 deletions

View File

@ -16,6 +16,8 @@ import (
"io" "io"
) )
type RawMessage []byte
// Unmarshal adapts to json/encoding Unmarshal API // Unmarshal adapts to json/encoding Unmarshal API
// //
// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. // Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v.

View File

@ -79,6 +79,7 @@ var fieldEncoders map[string]Encoder
var extensions []ExtensionFunc var extensions []ExtensionFunc
var jsonNumberType reflect.Type var jsonNumberType reflect.Type
var jsonRawMessageType reflect.Type var jsonRawMessageType reflect.Type
var jsoniterRawMessageType reflect.Type
var anyType reflect.Type var anyType reflect.Type
var marshalerType reflect.Type var marshalerType reflect.Type
var unmarshalerType reflect.Type var unmarshalerType reflect.Type
@ -92,6 +93,7 @@ func init() {
extensions = []ExtensionFunc{} extensions = []ExtensionFunc{}
jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem() jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem()
jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem() jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem()
anyType = reflect.TypeOf((*Any)(nil)).Elem() anyType = reflect.TypeOf((*Any)(nil)).Elem()
marshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem() marshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
unmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() unmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
@ -296,6 +298,9 @@ func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (Decoder, error) {
if typ.AssignableTo(jsonRawMessageType) { if typ.AssignableTo(jsonRawMessageType) {
return &jsonRawMessageCodec{}, nil return &jsonRawMessageCodec{}, nil
} }
if typ.AssignableTo(jsoniterRawMessageType) {
return &jsoniterRawMessageCodec{}, nil
}
if typ.AssignableTo(jsonNumberType) { if typ.AssignableTo(jsonNumberType) {
return &jsonNumberCodec{}, nil return &jsonNumberCodec{}, nil
} }
@ -386,6 +391,9 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (Encoder, error) {
if typ.AssignableTo(jsonRawMessageType) { if typ.AssignableTo(jsonRawMessageType) {
return &jsonRawMessageCodec{}, nil return &jsonRawMessageCodec{}, nil
} }
if typ.AssignableTo(jsoniterRawMessageType) {
return &jsoniterRawMessageCodec{}, nil
}
if typ.AssignableTo(jsonNumberType) { if typ.AssignableTo(jsonNumberType) {
return &jsonNumberCodec{}, nil return &jsonNumberCodec{}, nil
} }

View File

@ -384,6 +384,25 @@ func (encoder *jsonRawMessageCodec) isEmpty(ptr unsafe.Pointer) bool {
return len(*((*json.RawMessage)(ptr))) == 0 return len(*((*json.RawMessage)(ptr))) == 0
} }
type jsoniterRawMessageCodec struct {
}
func (codec *jsoniterRawMessageCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
*((*RawMessage)(ptr)) = RawMessage(iter.SkipAndReturnBytes())
}
func (codec *jsoniterRawMessageCodec) encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteRaw(string(*((*RawMessage)(ptr))))
}
func (encoder *jsoniterRawMessageCodec) encodeInterface(val interface{}, stream *Stream) {
stream.WriteRaw(string(val.(RawMessage)))
}
func (encoder *jsoniterRawMessageCodec) isEmpty(ptr unsafe.Pointer) bool {
return len(*((*RawMessage)(ptr))) == 0
}
type base64Codec struct { type base64Codec struct {
} }

View File

@ -121,28 +121,3 @@ func Test_encode_map_with_sorted_keys(t *testing.T) {
should.Equal(string(bytes), output) should.Equal(string(bytes), output)
} }
func Test_decode_map_of_raw_message(t *testing.T) {
should := require.New(t)
type RawMap map[string]*json.RawMessage
b := []byte("{\"test\":[{\"key\":\"value\"}]}")
var rawMap RawMap
should.Nil(Unmarshal(b, &rawMap))
should.Equal(`[{"key":"value"}]`, string(*rawMap["test"]))
type Inner struct {
Key string `json:"key"`
}
var inner []Inner
Unmarshal(*rawMap["test"], &inner)
should.Equal("value", inner[0].Key)
}
func Test_encode_map_of_raw_message(t *testing.T) {
should := require.New(t)
type RawMap map[string]*json.RawMessage
value := json.RawMessage("[]")
rawMap := RawMap{"hello": &value}
output, err := MarshalToString(rawMap)
should.Nil(err)
should.Equal(`{"hello":[]}`, output)
}

View File

@ -16,6 +16,16 @@ func Test_json_RawMessage(t *testing.T) {
should.Equal(`[1,2,3]`, str) should.Equal(`[1,2,3]`, str)
} }
func Test_jsoniter_RawMessage(t *testing.T) {
should := require.New(t)
var data 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 Test_json_RawMessage_in_struct(t *testing.T) { func Test_json_RawMessage_in_struct(t *testing.T) {
type TestObject struct { type TestObject struct {
Field1 string Field1 string
@ -27,3 +37,39 @@ func Test_json_RawMessage_in_struct(t *testing.T) {
should.Equal(` [1,2,3]`, string(data.Field2)) should.Equal(` [1,2,3]`, string(data.Field2))
should.Equal(`hello`, data.Field1) should.Equal(`hello`, data.Field1)
} }
func Test_decode_map_of_raw_message(t *testing.T) {
should := require.New(t)
type RawMap map[string]*json.RawMessage
b := []byte("{\"test\":[{\"key\":\"value\"}]}")
var rawMap RawMap
should.Nil(Unmarshal(b, &rawMap))
should.Equal(`[{"key":"value"}]`, string(*rawMap["test"]))
type Inner struct {
Key string `json:"key"`
}
var inner []Inner
Unmarshal(*rawMap["test"], &inner)
should.Equal("value", inner[0].Key)
}
func Test_encode_map_of_raw_message(t *testing.T) {
should := require.New(t)
type RawMap map[string]*json.RawMessage
value := json.RawMessage("[]")
rawMap := RawMap{"hello": &value}
output, err := MarshalToString(rawMap)
should.Nil(err)
should.Equal(`{"hello":[]}`, output)
}
func Test_encode_map_of_jsoniter_raw_message(t *testing.T) {
should := require.New(t)
type RawMap map[string]*RawMessage
value := RawMessage("[]")
rawMap := RawMap{"hello": &value}
output, err := MarshalToString(rawMap)
should.Nil(err)
should.Equal(`{"hello":[]}`, output)
}