Procházet zdrojové kódy

move json raw message

Tao Wen před 7 roky
rodič
revize
895a19f2dc
5 změnil soubory, kde provedl 155 přidání a 132 odebrání
  1. 8 12
      reflect.go
  2. 57 0
      reflect_json_raw_message.go
  3. 0 94
      reflect_native.go
  4. 60 0
      reflect_struct_decoder.go
  5. 30 26
      reflect_struct_encoder.go

+ 8 - 12
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 {
 	typeName := typ.String()
-	if typ == jsonRawMessageType {
-		return &jsonRawMessageCodec{}
-	}
-	if typ == jsoniterRawMessageType {
-		return &jsoniterRawMessageCodec{}
+	decoder := createDecoderOfJsonRawMessage(cfg, prefix, typ)
+	if decoder != nil {
+		return decoder
 	}
-	decoder := createDecoderOfJsonNumber(cfg, prefix, typ)
+	decoder = createDecoderOfJsonNumber(cfg, prefix, typ)
 	if decoder != nil {
 		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 {
-	if typ == jsonRawMessageType {
-		return &jsonRawMessageCodec{}
-	}
-	if typ == jsoniterRawMessageType {
-		return &jsoniterRawMessageCodec{}
+	encoder := createEncoderOfJsonRawMessage(cfg, prefix, typ)
+	if encoder != nil {
+		return encoder
 	}
-	encoder := createEncoderOfJsonNumber(cfg, prefix, typ)
+	encoder = createEncoderOfJsonNumber(cfg, prefix, typ)
 	if encoder != nil {
 		return encoder
 	}

+ 57 - 0
reflect_json_raw_message.go

@@ -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
+}

+ 0 - 94
reflect_native.go

@@ -369,36 +369,6 @@ func (encoder *dynamicEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 	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 {
 	sliceType *reflect2.UnsafeSliceType
 	sliceDecoder ValDecoder
@@ -448,67 +418,3 @@ func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool {
 	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)
-}

+ 60 - 0
reflect_struct_decoder.go

@@ -8,6 +8,32 @@ import (
 	"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 {
 	if cfg.disallowUnknownFields {
 		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())
 	}
 }
+
+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
+	}
+}

+ 30 - 26
reflect_struct_encoder.go

@@ -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 {
 	field        *reflect.StructField
 	fieldEncoder ValEncoder
@@ -179,3 +153,33 @@ func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 	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)
+}