示例#1
0
        /// <summary>
        /// Register serializer for ValueTuples
        /// </summary>
        private SerializerPair CreateValueTupleSerializer <T>()
        {
            TypeInfo typeInfo = typeof(T).GetTypeInfo();

            ReflectionSerializerVerifier.AssertRoot(typeInfo);

            var argumentTypes = typeInfo.GetGenericArguments();

            var memberGetters = typeInfo.GetFields().Select(ReflectionUtil.GetGetter).ToArray();

            var memberDeserializers = new CtxReadDelegate <object> [argumentTypes.Length];
            var memberSerializers   = new CtxWriteDelegate <object> [argumentTypes.Length];

            for (var index = 0; index < argumentTypes.Length; index++)
            {
                var argumentType = argumentTypes[index];
                var serPair      = GetOrRegisterSerializerInternal(argumentType);
                memberDeserializers[index] = ConvertReader(argumentType, serPair.Reader);
                memberSerializers[index]   = ConvertWriter(argumentType, serPair.Writer);
            }

            var type = typeInfo.AsType();
            CtxReadDelegate <T> readerDelegate = (ctx, unsafeReader) =>
            {
                // todo: consider using IL emit
                var activatorArgs = new object[argumentTypes.Length];
                for (var index = 0; index < argumentTypes.Length; index++)
                {
                    var value = memberDeserializers[index](ctx, unsafeReader);
                    activatorArgs[index] = value;
                }

                var instance = Activator.CreateInstance(type, activatorArgs);
                return((T)instance);
            };

            CtxWriteDelegate <T> writerDelegate = (ctx, unsafeWriter, value) =>
            {
                for (var i = 0; i < argumentTypes.Length; i++)
                {
                    var memberValue = memberGetters[i](value);
                    memberSerializers[i](ctx, unsafeWriter, memberValue);
                }
            };

            return(new SerializerPair(readerDelegate, writerDelegate));
        }
示例#2
0
        /// <summary>
        /// Register serializers for either <see cref="RdExtAttribute"/> or <see cref="RdModelAttribute"/>
        /// </summary>
        private void RegisterModelSerializer <T>()
        {
            Assertion.Assert(!ReflectionSerializerVerifier.IsScalar(typeof(T)), "Type {0} should be either RdModel or RdExt.", typeof(T));
            // place null marker to detect circular dependencies
            mySerializers.Add(typeof(T), null);

            TypeInfo typeInfo = typeof(T).GetTypeInfo();

            ReflectionSerializerVerifier.AssertRoot(typeInfo);
            var  isScalar      = ReflectionSerializerVerifier.IsScalar(typeInfo);
            bool allowNullable = ReflectionSerializerVerifier.HasRdModelAttribute(typeInfo) || (isScalar && ReflectionSerializerVerifier.CanBeNull(typeInfo));

/*      var intrinsicSerializer = TryGetIntrinsicSerializer(typeInfo);
 *    if (intrinsicSerializer != null)
 *    {
 *      mySerializers[typeof(T)] = intrinsicSerializer;
 *      return;
 *    }*/

            var memberInfos   = SerializerReflectionUtil.GetBindableMembers(typeInfo);
            var memberSetters = memberInfos.Select(ReflectionUtil.GetSetter).ToArray();
            var memberGetters = memberInfos.Select(ReflectionUtil.GetGetter).ToArray();

            // todo: consider using IL emit
            var memberDeserializers = new CtxReadDelegate <object> [memberInfos.Length];
            var memberSerializers   = new CtxWriteDelegate <object> [memberInfos.Length];

            for (var index = 0; index < memberInfos.Length; index++)
            {
                var mi         = memberInfos[index];
                var returnType = ReflectionUtil.GetReturnType(mi);
                var serPair    = GetOrCreateMemberSerializer(mi, serializerType: returnType, allowNullable: allowNullable);
                memberDeserializers[index] = SerializerReflectionUtil.ConvertReader(returnType, serPair.Reader);
                memberSerializers[index]   = SerializerReflectionUtil.ConvertWriter(returnType, serPair.Writer);
            }

            var type = typeInfo.AsType();

            CtxReadDelegate <T> readerDelegate = (ctx, unsafeReader) =>
            {
                if (allowNullable && !unsafeReader.ReadNullness())
                {
                    return(default);
示例#3
0
        /// <summary>
        /// Register serializers for either <see cref="RdExtAttribute"/> or <see cref="RdModelAttribute"/>
        /// </summary>
        private void RegisterModelSerializer <T>()
        {
            // place null marker to detect circular dependencies
            mySerializers.Add(typeof(T), null);

            TypeInfo typeInfo = typeof(T).GetTypeInfo();

            ReflectionSerializerVerifier.AssertRoot(typeInfo);
            bool allowNullable = ReflectionSerializerVerifier.HasRdModelAttribute(typeInfo);

            var intrinsicSerializer = TryGetIntrinsicSerializer(typeInfo);

            if (intrinsicSerializer != null)
            {
                mySerializers[typeof(T)] = intrinsicSerializer;
                return;
            }

            var memberInfos   = GetBindableMembers(typeInfo);
            var memberSetters = memberInfos.Select(ReflectionUtil.GetSetter).ToArray();
            var memberGetters = memberInfos.Select(ReflectionUtil.GetGetter).ToArray();

            // todo: consider using IL emit
            var memberDeserializers = new CtxReadDelegate <object> [memberInfos.Length];
            var memberSerializers   = new CtxWriteDelegate <object> [memberInfos.Length];

            for (var index = 0; index < memberInfos.Length; index++)
            {
                var mi         = memberInfos[index];
                var returnType = ReflectionUtil.GetReturnType(mi);
                var serPair    = GetOrCreateMemberSerializer(mi, serializerType: returnType, allowNullable: allowNullable);
                memberDeserializers[index] = ConvertReader(returnType, serPair.Reader);
                memberSerializers[index]   = ConvertWriter(returnType, serPair.Writer);
            }

            var type = typeInfo.AsType();
            CtxReadDelegate <T> readerDelegate = (ctx, unsafeReader) =>
            {
                // todo: support non-default constructors
                var instance = Activator.CreateInstance(type);

                var  bindableInstance = instance as IRdBindable;
                RdId id = default(RdId);
                if (bindableInstance != null)
                {
                    id = unsafeReader.ReadRdId();
                }

                for (var index = 0; index < memberDeserializers.Length; index++)
                {
                    var value = memberDeserializers[index](ctx, unsafeReader);
                    memberSetters[index](instance, value);
                }

                bindableInstance?.WithId(id);

                return((T)instance);
            };

            CtxWriteDelegate <T> writerDelegate = (ctx, unsafeWriter, value) =>
            {
                if (value is IRdBindable bindableInstance)
                {
                    unsafeWriter.Write(bindableInstance.RdId);
                }

                for (var i = 0; i < memberDeserializers.Length; i++)
                {
                    var memberValue = memberGetters[i](value);
                    memberSerializers[i](ctx, unsafeWriter, memberValue);
                }
            };

            mySerializers[type] = new SerializerPair(readerDelegate, writerDelegate);
        }