From 5a696808d6ec7eb828fbd7a11643c2003e76ca55 Mon Sep 17 00:00:00 2001 From: Tao Wen Date: Sun, 18 Feb 2018 22:57:01 +0800 Subject: [PATCH] fix any codec --- feature_reflect.go | 12 ++++++++++-- feature_reflect_native.go | 29 +++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/feature_reflect.go b/feature_reflect.go index 56f77e0..94d8c29 100644 --- a/feature_reflect.go +++ b/feature_reflect.go @@ -79,7 +79,7 @@ func (stream *Stream) WriteVal(val interface{}) { } typ := reflect.TypeOf(val) encoder := stream.cfg.EncoderOf(typ) - encoder.Encode((*emptyInterface)(unsafe.Pointer(&val)).word, stream) + encoder.Encode(reflect2.PtrOf(val), stream) } func decoderOfType(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder { @@ -150,6 +150,9 @@ func createDecoderOfType(cfg *frozenConfig, prefix string, typ reflect.Type) Val sliceDecoder := decoderOfSlice(cfg, prefix, typ) return &base64Codec{sliceDecoder: sliceDecoder} } + if typ == anyType { + return &directAnyCodec{} + } if typ.Implements(anyType) { return &anyCodec{} } @@ -383,8 +386,13 @@ func createEncoderOfType(cfg *frozenConfig, prefix string, typ reflect.Type) Val if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 { return &base64Codec{} } + if typ == anyType { + return &directAnyCodec{} + } if typ.Implements(anyType) { - return &anyCodec{} + return &anyCodec{ + valType: reflect2.Type2(typ), + } } return createEncoderOfSimpleType(cfg, prefix, typ) } diff --git a/feature_reflect_native.go b/feature_reflect_native.go index c47ee76..b0cefc5 100644 --- a/feature_reflect_native.go +++ b/feature_reflect_native.go @@ -369,20 +369,41 @@ func (encoder *dynamicEncoder) IsEmpty(ptr unsafe.Pointer) bool { return encoder.valType.UnsafeIndirect(ptr) == nil } - type anyCodec struct { + valType reflect2.Type } func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*Any)(ptr)) = iter.ReadAny() + panic("not implemented") } func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - (*((*Any)(ptr))).WriteTo(stream) + obj := codec.valType.UnsafeIndirect(ptr) + any := obj.(Any) + any.WriteTo(stream) } func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool { - return (*((*Any)(ptr))).Size() == 0 + obj := codec.valType.UnsafeIndirect(ptr) + any := obj.(Any) + return any.Size() == 0 +} + +type directAnyCodec struct { +} + +func (codec *directAnyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *(*Any)(ptr) = iter.readAny() +} + +func (codec *directAnyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + any := *(*Any)(ptr) + any.WriteTo(stream) +} + +func (codec *directAnyCodec) IsEmpty(ptr unsafe.Pointer) bool { + any := *(*Any)(ptr) + return any.Size() == 0 } type jsonNumberCodec struct {