diff --git a/feature_any.go b/feature_any.go index 0f6931d..87716d1 100644 --- a/feature_any.go +++ b/feature_any.go @@ -1,10 +1,10 @@ package jsoniter import ( + "errors" "fmt" "io" "reflect" - "errors" ) // Any generic object representation. diff --git a/feature_iter.go b/feature_iter.go index 54a3a0f..702d224 100644 --- a/feature_iter.go +++ b/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 diff --git a/feature_pool.go b/feature_pool.go index 73962bc..52d38e6 100644 --- a/feature_pool.go +++ b/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 diff --git a/feature_reflect.go b/feature_reflect.go index bdd7e18..ebd3755 100644 --- a/feature_reflect.go +++ b/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 } diff --git a/feature_reflect_array.go b/feature_reflect_array.go index e23f187..d661fb6 100644 --- a/feature_reflect_array.go +++ b/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 } diff --git a/feature_reflect_extension.go b/feature_reflect_extension.go index b535624..177df2c 100644 --- a/feature_reflect_extension.go +++ b/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} diff --git a/feature_reflect_slice.go b/feature_reflect_slice.go index 7377eec..a07f9e1 100644 --- a/feature_reflect_slice.go +++ b/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 } diff --git a/feature_stream.go b/feature_stream.go index 9323848..97355eb 100644 --- a/feature_stream.go +++ b/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.