ソースを参照

expose OptionalEncoder&OptionalDecoder; add attachment to Stream&Iterator for customized decoder/encoder

Tao Wen 8 年 前
コミット
b1b003864e

+ 1 - 1
feature_any.go

@@ -1,10 +1,10 @@
 package jsoniter
 
 import (
+	"errors"
 	"fmt"
 	"io"
 	"reflect"
-	"errors"
 )
 
 // Any generic object representation.

+ 1 - 0
feature_iter.go

@@ -77,6 +77,7 @@ type Iterator struct {
 	captureStartedAt int
 	captured         []byte
 	Error            error
+	Attachment       interface{} // open for customized decoder
 }
 
 // NewIterator creates an empty Iterator instance

+ 2 - 0
feature_pool.go

@@ -28,6 +28,7 @@ func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream {
 
 func (cfg *frozenConfig) ReturnStream(stream *Stream) {
 	stream.Error = nil
+	stream.Attachment = nil
 	select {
 	case cfg.streamPool <- stream:
 		return
@@ -48,6 +49,7 @@ func (cfg *frozenConfig) BorrowIterator(data []byte) *Iterator {
 
 func (cfg *frozenConfig) ReturnIterator(iter *Iterator) {
 	iter.Error = nil
+	iter.Attachment = nil
 	select {
 	case cfg.iteratorPool <- iter:
 		return

+ 21 - 21
feature_reflect.go

@@ -72,24 +72,24 @@ func init() {
 	textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
 }
 
-type optionalDecoder struct {
-	valueType    reflect.Type
-	valueDecoder ValDecoder
+type OptionalDecoder struct {
+	ValueType    reflect.Type
+	ValueDecoder ValDecoder
 }
 
-func (decoder *optionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	if iter.ReadNil() {
 		*((*unsafe.Pointer)(ptr)) = nil
 	} else {
 		if *((*unsafe.Pointer)(ptr)) == nil {
 			//pointer to null, we have to allocate memory to hold the value
-			value := reflect.New(decoder.valueType)
+			value := reflect.New(decoder.ValueType)
 			newPtr := extractInterface(value.Interface()).word
-			decoder.valueDecoder.Decode(newPtr, iter)
+			decoder.ValueDecoder.Decode(newPtr, iter)
 			*((*uintptr)(ptr)) = uintptr(newPtr)
 		} else {
 			//reuse existing instance
-			decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
+			decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
 		}
 	}
 }
@@ -113,23 +113,23 @@ func (decoder *deferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	}
 }
 
-type optionalEncoder struct {
-	valueEncoder ValEncoder
+type OptionalEncoder struct {
+	ValueEncoder ValEncoder
 }
 
-func (encoder *optionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	if *((*unsafe.Pointer)(ptr)) == nil {
 		stream.WriteNil()
 	} else {
-		encoder.valueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
+		encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
 	}
 }
 
-func (encoder *optionalEncoder) EncodeInterface(val interface{}, stream *Stream) {
+func (encoder *OptionalEncoder) EncodeInterface(val interface{}, stream *Stream) {
 	WriteToStream(val, stream, encoder)
 }
 
-func (encoder *optionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*unsafe.Pointer)(ptr)) == nil
 }
 
@@ -307,7 +307,7 @@ func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error
 		templateInterface := reflect.New(typ).Elem().Interface()
 		var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)}
 		if typ.Kind() == reflect.Ptr {
-			decoder = &optionalDecoder{typ.Elem(), decoder}
+			decoder = &OptionalDecoder{typ.Elem(), decoder}
 		}
 		return decoder, nil
 	}
@@ -320,7 +320,7 @@ func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error
 		templateInterface := reflect.New(typ).Elem().Interface()
 		var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)}
 		if typ.Kind() == reflect.Ptr {
-			decoder = &optionalDecoder{typ.Elem(), decoder}
+			decoder = &OptionalDecoder{typ.Elem(), decoder}
 		}
 		return decoder, nil
 	}
@@ -480,7 +480,7 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error
 			checkIsEmpty:      checkIsEmpty,
 		}
 		if typ.Kind() == reflect.Ptr {
-			encoder = &optionalEncoder{encoder}
+			encoder = &OptionalEncoder{encoder}
 		}
 		return encoder, nil
 	}
@@ -507,7 +507,7 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error
 			checkIsEmpty:      checkIsEmpty,
 		}
 		if typ.Kind() == reflect.Ptr {
-			encoder = &optionalEncoder{encoder}
+			encoder = &OptionalEncoder{encoder}
 		}
 		return encoder, nil
 	}
@@ -567,7 +567,7 @@ func createCheckIsEmpty(typ reflect.Type) (checkIsEmpty, error) {
 	case reflect.Map:
 		return &mapEncoder{}, nil
 	case reflect.Ptr:
-		return &optionalEncoder{}, nil
+		return &OptionalEncoder{}, nil
 	default:
 		return nil, fmt.Errorf("unsupported type: %v", typ)
 	}
@@ -678,7 +678,7 @@ func decoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error)
 	if err != nil {
 		return nil, err
 	}
-	return &optionalDecoder{elemType, decoder}, nil
+	return &OptionalDecoder{elemType, decoder}, nil
 }
 
 func encoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
@@ -687,9 +687,9 @@ func encoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error)
 	if err != nil {
 		return nil, err
 	}
-	encoder := &optionalEncoder{elemEncoder}
+	encoder := &OptionalEncoder{elemEncoder}
 	if elemType.Kind() == reflect.Map {
-		encoder = &optionalEncoder{encoder}
+		encoder = &OptionalEncoder{encoder}
 	}
 	return encoder, nil
 }

+ 1 - 1
feature_reflect_array.go

@@ -21,7 +21,7 @@ func encoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
 		return nil, err
 	}
 	if typ.Elem().Kind() == reflect.Map {
-		encoder = &optionalEncoder{encoder}
+		encoder = &OptionalEncoder{encoder}
 	}
 	return &arrayEncoder{typ, typ.Elem(), encoder}, nil
 }

+ 3 - 3
feature_reflect_extension.go

@@ -185,7 +185,7 @@ func _getTypeDecoderFromExtension(typ reflect.Type) ValDecoder {
 	if typ.Kind() == reflect.Ptr {
 		decoder := typeDecoders[typ.Elem().String()]
 		if decoder != nil {
-			return &optionalDecoder{typ.Elem(), decoder}
+			return &OptionalDecoder{typ.Elem(), decoder}
 		}
 	}
 	return nil
@@ -216,7 +216,7 @@ func _getTypeEncoderFromExtension(typ reflect.Type) ValEncoder {
 	if typ.Kind() == reflect.Ptr {
 		encoder := typeEncoders[typ.Elem().String()]
 		if encoder != nil {
-			return &optionalEncoder{encoder}
+			return &OptionalEncoder{encoder}
 		}
 	}
 	return nil
@@ -254,7 +254,7 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err
 				for _, binding := range structDescriptor.Fields {
 					binding.levels = append([]int{i}, binding.levels...)
 					omitempty := binding.Encoder.(*structFieldEncoder).omitempty
-					binding.Encoder = &optionalEncoder{binding.Encoder}
+					binding.Encoder = &OptionalEncoder{binding.Encoder}
 					binding.Encoder = &structFieldEncoder{&field, binding.Encoder, omitempty}
 					binding.Decoder = &deferenceDecoder{field.Type.Elem(), binding.Decoder}
 					binding.Decoder = &structFieldDecoder{&field, binding.Decoder}

+ 1 - 1
feature_reflect_slice.go

@@ -21,7 +21,7 @@ func encoderOfSlice(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
 		return nil, err
 	}
 	if typ.Elem().Kind() == reflect.Map {
-		encoder = &optionalEncoder{encoder}
+		encoder = &OptionalEncoder{encoder}
 	}
 	return &sliceEncoder{typ, typ.Elem(), encoder}, nil
 }

+ 8 - 7
feature_stream.go

@@ -4,15 +4,16 @@ import (
 	"io"
 )
 
-// Stream is a io.Writer like object, with JSON specific write functions.
+// stream is a io.Writer like object, with JSON specific write functions.
 // Error is not returned as return value, but stored as Error member on this stream instance.
 type Stream struct {
-	cfg       *frozenConfig
-	out       io.Writer
-	buf       []byte
-	n         int
-	Error     error
-	indention int
+	cfg        *frozenConfig
+	out        io.Writer
+	buf        []byte
+	n          int
+	Error      error
+	indention  int
+	Attachment interface{} // open for customized encoder
 }
 
 // NewStream create new stream instance.