mirror of
https://github.com/json-iterator/go.git
synced 2025-04-20 11:28:49 +02:00
move json raw message
This commit is contained in:
parent
6327145300
commit
895a19f2dc
20
reflect.go
20
reflect.go
@ -106,13 +106,11 @@ func decoderOfType(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecode
|
|||||||
|
|
||||||
func createDecoderOfType(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
func createDecoderOfType(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
||||||
typeName := typ.String()
|
typeName := typ.String()
|
||||||
if typ == jsonRawMessageType {
|
decoder := createDecoderOfJsonRawMessage(cfg, prefix, typ)
|
||||||
return &jsonRawMessageCodec{}
|
if decoder != nil {
|
||||||
|
return decoder
|
||||||
}
|
}
|
||||||
if typ == jsoniterRawMessageType {
|
decoder = createDecoderOfJsonNumber(cfg, prefix, typ)
|
||||||
return &jsoniterRawMessageCodec{}
|
|
||||||
}
|
|
||||||
decoder := createDecoderOfJsonNumber(cfg, prefix, typ)
|
|
||||||
if decoder != nil {
|
if decoder != nil {
|
||||||
return decoder
|
return decoder
|
||||||
}
|
}
|
||||||
@ -295,13 +293,11 @@ func encoderOfType(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncode
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createEncoderOfType(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
|
func createEncoderOfType(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
|
||||||
if typ == jsonRawMessageType {
|
encoder := createEncoderOfJsonRawMessage(cfg, prefix, typ)
|
||||||
return &jsonRawMessageCodec{}
|
if encoder != nil {
|
||||||
|
return encoder
|
||||||
}
|
}
|
||||||
if typ == jsoniterRawMessageType {
|
encoder = createEncoderOfJsonNumber(cfg, prefix, typ)
|
||||||
return &jsoniterRawMessageCodec{}
|
|
||||||
}
|
|
||||||
encoder := createEncoderOfJsonNumber(cfg, prefix, typ)
|
|
||||||
if encoder != nil {
|
if encoder != nil {
|
||||||
return encoder
|
return encoder
|
||||||
}
|
}
|
||||||
|
57
reflect_json_raw_message.go
Normal file
57
reflect_json_raw_message.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
"encoding/json"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createEncoderOfJsonRawMessage(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
|
||||||
|
if typ == jsonRawMessageType {
|
||||||
|
return &jsonRawMessageCodec{}
|
||||||
|
}
|
||||||
|
if typ == jsoniterRawMessageType {
|
||||||
|
return &jsoniterRawMessageCodec{}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createDecoderOfJsonRawMessage(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
||||||
|
if typ == jsonRawMessageType {
|
||||||
|
return &jsonRawMessageCodec{}
|
||||||
|
}
|
||||||
|
if typ == jsoniterRawMessageType {
|
||||||
|
return &jsoniterRawMessageCodec{}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (codec *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 (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return len(*((*RawMessage)(ptr))) == 0
|
||||||
|
}
|
@ -369,36 +369,6 @@ func (encoder *dynamicEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|||||||
return encoder.valType.UnsafeIndirect(ptr) == nil
|
return encoder.valType.UnsafeIndirect(ptr) == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
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 (codec *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 (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
|
||||||
return len(*((*RawMessage)(ptr))) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type base64Codec struct {
|
type base64Codec struct {
|
||||||
sliceType *reflect2.UnsafeSliceType
|
sliceType *reflect2.UnsafeSliceType
|
||||||
sliceDecoder ValDecoder
|
sliceDecoder ValDecoder
|
||||||
@ -448,67 +418,3 @@ func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool {
|
func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
return len(*((*[]byte)(ptr))) == 0
|
return len(*((*[]byte)(ptr))) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
type stringModeNumberDecoder struct {
|
|
||||||
elemDecoder ValDecoder
|
|
||||||
}
|
|
||||||
|
|
||||||
func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
||||||
c := iter.nextToken()
|
|
||||||
if c != '"' {
|
|
||||||
iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c}))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
decoder.elemDecoder.Decode(ptr, iter)
|
|
||||||
if iter.Error != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c = iter.readByte()
|
|
||||||
if c != '"' {
|
|
||||||
iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c}))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type stringModeStringDecoder struct {
|
|
||||||
elemDecoder ValDecoder
|
|
||||||
cfg *frozenConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
||||||
decoder.elemDecoder.Decode(ptr, iter)
|
|
||||||
str := *((*string)(ptr))
|
|
||||||
tempIter := decoder.cfg.BorrowIterator([]byte(str))
|
|
||||||
defer decoder.cfg.ReturnIterator(tempIter)
|
|
||||||
*((*string)(ptr)) = tempIter.ReadString()
|
|
||||||
}
|
|
||||||
|
|
||||||
type stringModeNumberEncoder struct {
|
|
||||||
elemEncoder ValEncoder
|
|
||||||
}
|
|
||||||
|
|
||||||
func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
||||||
stream.writeByte('"')
|
|
||||||
encoder.elemEncoder.Encode(ptr, stream)
|
|
||||||
stream.writeByte('"')
|
|
||||||
}
|
|
||||||
|
|
||||||
func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|
||||||
return encoder.elemEncoder.IsEmpty(ptr)
|
|
||||||
}
|
|
||||||
|
|
||||||
type stringModeStringEncoder struct {
|
|
||||||
elemEncoder ValEncoder
|
|
||||||
cfg *frozenConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
||||||
tempStream := encoder.cfg.BorrowStream(nil)
|
|
||||||
defer encoder.cfg.ReturnStream(tempStream)
|
|
||||||
encoder.elemEncoder.Encode(ptr, tempStream)
|
|
||||||
stream.WriteString(string(tempStream.Buffer()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|
||||||
return encoder.elemEncoder.IsEmpty(ptr)
|
|
||||||
}
|
|
||||||
|
@ -8,6 +8,32 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func decoderOfStruct(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
||||||
|
bindings := map[string]*Binding{}
|
||||||
|
structDescriptor := describeStruct(cfg, prefix, typ)
|
||||||
|
for _, binding := range structDescriptor.Fields {
|
||||||
|
for _, fromName := range binding.FromNames {
|
||||||
|
old := bindings[fromName]
|
||||||
|
if old == nil {
|
||||||
|
bindings[fromName] = binding
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ignoreOld, ignoreNew := resolveConflictBinding(cfg, old, binding)
|
||||||
|
if ignoreOld {
|
||||||
|
delete(bindings, fromName)
|
||||||
|
}
|
||||||
|
if !ignoreNew {
|
||||||
|
bindings[fromName] = binding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fields := map[string]*structFieldDecoder{}
|
||||||
|
for k, binding := range bindings {
|
||||||
|
fields[k] = binding.Decoder.(*structFieldDecoder)
|
||||||
|
}
|
||||||
|
return createStructDecoder(cfg, typ, fields)
|
||||||
|
}
|
||||||
|
|
||||||
func createStructDecoder(cfg *frozenConfig, typ reflect.Type, fields map[string]*structFieldDecoder) ValDecoder {
|
func createStructDecoder(cfg *frozenConfig, typ reflect.Type, fields map[string]*structFieldDecoder) ValDecoder {
|
||||||
if cfg.disallowUnknownFields {
|
if cfg.disallowUnknownFields {
|
||||||
return &generalStructDecoder{typ: typ, fields: fields, disallowUnknownFields: true}
|
return &generalStructDecoder{typ: typ, fields: fields, disallowUnknownFields: true}
|
||||||
@ -972,3 +998,37 @@ func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|||||||
iter.Error = fmt.Errorf("%s: %s", decoder.field.Name, iter.Error.Error())
|
iter.Error = fmt.Errorf("%s: %s", decoder.field.Name, iter.Error.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type stringModeStringDecoder struct {
|
||||||
|
elemDecoder ValDecoder
|
||||||
|
cfg *frozenConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
|
decoder.elemDecoder.Decode(ptr, iter)
|
||||||
|
str := *((*string)(ptr))
|
||||||
|
tempIter := decoder.cfg.BorrowIterator([]byte(str))
|
||||||
|
defer decoder.cfg.ReturnIterator(tempIter)
|
||||||
|
*((*string)(ptr)) = tempIter.ReadString()
|
||||||
|
}
|
||||||
|
|
||||||
|
type stringModeNumberDecoder struct {
|
||||||
|
elemDecoder ValDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
|
c := iter.nextToken()
|
||||||
|
if c != '"' {
|
||||||
|
iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
decoder.elemDecoder.Decode(ptr, iter)
|
||||||
|
if iter.Error != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c = iter.readByte()
|
||||||
|
if c != '"' {
|
||||||
|
iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
@ -74,32 +74,6 @@ func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ig
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func decoderOfStruct(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
|
||||||
bindings := map[string]*Binding{}
|
|
||||||
structDescriptor := describeStruct(cfg, prefix, typ)
|
|
||||||
for _, binding := range structDescriptor.Fields {
|
|
||||||
for _, fromName := range binding.FromNames {
|
|
||||||
old := bindings[fromName]
|
|
||||||
if old == nil {
|
|
||||||
bindings[fromName] = binding
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ignoreOld, ignoreNew := resolveConflictBinding(cfg, old, binding)
|
|
||||||
if ignoreOld {
|
|
||||||
delete(bindings, fromName)
|
|
||||||
}
|
|
||||||
if !ignoreNew {
|
|
||||||
bindings[fromName] = binding
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fields := map[string]*structFieldDecoder{}
|
|
||||||
for k, binding := range bindings {
|
|
||||||
fields[k] = binding.Decoder.(*structFieldDecoder)
|
|
||||||
}
|
|
||||||
return createStructDecoder(cfg, typ, fields)
|
|
||||||
}
|
|
||||||
|
|
||||||
type structFieldEncoder struct {
|
type structFieldEncoder struct {
|
||||||
field *reflect.StructField
|
field *reflect.StructField
|
||||||
fieldEncoder ValEncoder
|
fieldEncoder ValEncoder
|
||||||
@ -179,3 +153,33 @@ func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type stringModeNumberEncoder struct {
|
||||||
|
elemEncoder ValEncoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||||
|
stream.writeByte('"')
|
||||||
|
encoder.elemEncoder.Encode(ptr, stream)
|
||||||
|
stream.writeByte('"')
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return encoder.elemEncoder.IsEmpty(ptr)
|
||||||
|
}
|
||||||
|
|
||||||
|
type stringModeStringEncoder struct {
|
||||||
|
elemEncoder ValEncoder
|
||||||
|
cfg *frozenConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||||
|
tempStream := encoder.cfg.BorrowStream(nil)
|
||||||
|
defer encoder.cfg.ReturnStream(tempStream)
|
||||||
|
encoder.elemEncoder.Encode(ptr, tempStream)
|
||||||
|
stream.WriteString(string(tempStream.Buffer()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return encoder.elemEncoder.IsEmpty(ptr)
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user