1
0
mirror of https://github.com/json-iterator/go.git synced 2025-01-20 18:48:32 +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"
)
type RawMessage []byte
// Unmarshal adapts to json/encoding Unmarshal API
//
// 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 jsonNumberType reflect.Type
var jsonRawMessageType reflect.Type
var jsoniterRawMessageType reflect.Type
var anyType reflect.Type
var marshalerType reflect.Type
var unmarshalerType reflect.Type
@ -92,6 +93,7 @@ func init() {
extensions = []ExtensionFunc{}
jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem()
jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem()
anyType = reflect.TypeOf((*Any)(nil)).Elem()
marshalerType = reflect.TypeOf((*json.Marshaler)(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) {
return &jsonRawMessageCodec{}, nil
}
if typ.AssignableTo(jsoniterRawMessageType) {
return &jsoniterRawMessageCodec{}, nil
}
if typ.AssignableTo(jsonNumberType) {
return &jsonNumberCodec{}, nil
}
@ -386,6 +391,9 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (Encoder, error) {
if typ.AssignableTo(jsonRawMessageType) {
return &jsonRawMessageCodec{}, nil
}
if typ.AssignableTo(jsoniterRawMessageType) {
return &jsoniterRawMessageCodec{}, nil
}
if typ.AssignableTo(jsonNumberType) {
return &jsonNumberCodec{}, nil
}

View File

@ -384,6 +384,25 @@ func (encoder *jsonRawMessageCodec) isEmpty(ptr unsafe.Pointer) bool {
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 {
}

View File

@ -121,28 +121,3 @@ func Test_encode_map_with_sorted_keys(t *testing.T) {
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)
}
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) {
type TestObject struct {
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(`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)
}