1
0
mirror of https://github.com/json-iterator/go.git synced 2025-04-23 11:37:32 +02:00

#166 support ValidateJsonRawMessage in ConfigCompatibleWithStandardLibrary

This commit is contained in:
Tao Wen 2017-09-14 23:54:40 +08:00
parent 6a4ba7bfa9
commit 90574c5ca3
4 changed files with 41 additions and 4 deletions

View File

@ -18,6 +18,7 @@ type Config struct {
SortMapKeys bool SortMapKeys bool
UseNumber bool UseNumber bool
TagKey string TagKey string
ValidateJsonRawMessage bool
} }
type frozenConfig struct { type frozenConfig struct {
@ -55,6 +56,7 @@ var ConfigDefault = Config{
var ConfigCompatibleWithStandardLibrary = Config{ var ConfigCompatibleWithStandardLibrary = Config{
EscapeHTML: true, EscapeHTML: true,
SortMapKeys: true, SortMapKeys: true,
ValidateJsonRawMessage: true,
}.Froze() }.Froze()
// ConfigFastest marshals float with only 6 digits precision // ConfigFastest marshals float with only 6 digits precision
@ -83,10 +85,31 @@ func (cfg Config) Froze() API {
if cfg.UseNumber { if cfg.UseNumber {
frozenConfig.useNumber() frozenConfig.useNumber()
} }
if cfg.ValidateJsonRawMessage {
frozenConfig.validateJsonRawMessage()
}
frozenConfig.configBeforeFrozen = cfg frozenConfig.configBeforeFrozen = cfg
return frozenConfig return frozenConfig
} }
func (cfg *frozenConfig) validateJsonRawMessage() {
encoder := &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) {
rawMessage := *(*json.RawMessage)(ptr)
iter := cfg.BorrowIterator([]byte(rawMessage))
iter.Read()
if iter.Error != nil {
stream.WriteRaw("null")
} else {
cfg.ReturnIterator(iter)
stream.WriteRaw(string(rawMessage))
}
}, func(ptr unsafe.Pointer) bool {
return false
}}
cfg.addEncoderToCache(reflect.TypeOf((*json.RawMessage)(nil)).Elem(), encoder)
cfg.addEncoderToCache(reflect.TypeOf((*RawMessage)(nil)).Elem(), encoder)
}
func (cfg *frozenConfig) useNumber() { func (cfg *frozenConfig) useNumber() {
cfg.addDecoderToCache(reflect.TypeOf((*interface{})(nil)).Elem(), &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) { cfg.addDecoderToCache(reflect.TypeOf((*interface{})(nil)).Elem(), &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) {
if iter.WhatIsNext() == NumberValue { if iter.WhatIsNext() == NumberValue {

View File

@ -4,8 +4,8 @@ import (
"encoding" "encoding"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"unsafe"
"reflect" "reflect"
"unsafe"
) )
type stringCodec struct { type stringCodec struct {

View File

@ -2,10 +2,10 @@ package jsoniter
import ( import (
"encoding/json" "encoding/json"
"fmt"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"testing" "testing"
"unsafe" "unsafe"
"fmt"
) )
func Test_write_array_of_interface(t *testing.T) { func Test_write_array_of_interface(t *testing.T) {

View File

@ -72,3 +72,17 @@ func Test_encode_map_of_jsoniter_raw_message(t *testing.T) {
should.Nil(err) should.Nil(err)
should.Equal(`{"hello":[]}`, output) should.Equal(`{"hello":[]}`, output)
} }
func Test_marshal_invalid_json_raw_message(t *testing.T) {
type A struct {
Raw json.RawMessage `json:"raw"`
}
message := []byte(`{}`)
a := A{}
should := require.New(t)
should.Nil(ConfigCompatibleWithStandardLibrary.Unmarshal(message, &a))
aout, aouterr := ConfigCompatibleWithStandardLibrary.Marshal(&a)
should.Equal(`{"raw":null}`, string(aout))
should.Nil(aouterr)
}