예제 #1
0
 public RdCall(CtxReadDelegate <TReq> readRequest, CtxWriteDelegate <TReq> writeRequest, CtxReadDelegate <TRes> readResponse, CtxWriteDelegate <TRes> writeResponse)
 {
     ReadRequestDelegate   = readRequest;
     WriteRequestDelegate  = writeRequest;
     ReadResponseDelegate  = readResponse;
     WriteResponseDelegate = writeResponse;
 }
예제 #2
0
 public static void WriteNullableClass <T>(this UnsafeWriter writer, CtxWriteDelegate <T> itemWriter, SerializationCtx ctx, T value) where T : class
 {
     if (writer.WriteNullness(value))
     {
         itemWriter(ctx, writer, value);
     }
 }
예제 #3
0
        public static SerializerPair CreateListSerializerPair <T>(SerializerPair itemSerializer)
        {
            CtxReadDelegate <IList <T> >        readListSerializer  = (ctx, reader) => reader.ReadList(itemSerializer.GetReader <T>(), ctx);
            CtxWriteDelegate <ICollection <T> > writeListSerializer = (ctx, writer, value) => writer.WriteCollection(itemSerializer.GetWriter <T>(), ctx, value);

            return(new SerializerPair(readListSerializer, writeListSerializer));
        }
예제 #4
0
 public static void WriteNullableStruct <T>(this UnsafeWriter writer, CtxWriteDelegate <T> itemWriter, SerializationCtx ctx, T?value) where T : struct
 {
     if (writer.WriteNullness(value))
     {
         itemWriter(ctx, writer, value.Value);
     }
 }
예제 #5
0
        public void Register <T>(CtxReadDelegate <T> reader, CtxWriteDelegate <T> writer, long?predefinedId = null)
        {
            lock (myLock)
            {
                var  typeId = RdId.Define <T>(predefinedId);
                RdId existing;
                if (myTypeMapping.TryGetValue(typeof(T), out existing))
                {
                    Assertion.Require(existing == typeId, "Type {0} already present with id={1}, but now is set with {2}", typeof(T).FullName, existing, typeId);
                }
                else
                {
                    if (myReaders.ContainsKey(typeId))
                    {
                        Type existingType;
                        lock (myLock)
                            existingType = myTypeMapping.First(p => p.Value == typeId).Key;
                        throw new ArgumentException(string.Format("Can't register {0} with id {1}. Already registered {2}", typeof(T).FullName, typeId, existingType));
                    }
                    Protocol.InitTrace?.Log($"Registering type {typeof(T).Name}, id={typeId}");

                    myTypeMapping[typeof(T)] = typeId;
                    myReaders[typeId]        = (ctx, unsafeReader) => reader(ctx, unsafeReader);
                    myWriters[typeId]        = (ctx, unsafeWriter, value) => writer(ctx, unsafeWriter, (T)value);
                }
            }
        }
예제 #6
0
        public void Register <T>(CtxReadDelegate <T> reader, CtxWriteDelegate <T> writer, int?predefinedId = null)
        {
      #if !NET35
            if (!myBackgroundRegistrar.IsInsideProcessing)
            {
                myBackgroundRegistrar.SendBlocking(new ToplevelRegistration(typeof(T), szr => szr.Register(reader, writer, predefinedId)));
                myBackgroundRegistrar.WaitForEmpty();
            }
      #endif

            var  typeId = RdId.Define <T>(predefinedId);
            RdId existing;
            if (myTypeMapping.TryGetValue(typeof(T), out existing))
            {
                Assertion.Require(existing == typeId, "Type {0} already present with id={1}, but now is set with {2}", typeof(T).FullName, existing, typeId);
            }
            else
            {
                if (myReaders.ContainsKey(typeId))
                {
                    var existingType = myTypeMapping.First(p => p.Value == typeId).Key;
                    throw new ArgumentException(string.Format("Can't register {0} with id {1}. Already registered {2}", typeof(T).FullName, typeId, existingType));
                }
                Protocol.InitializationLogger.Trace("Registering type {0}, id={1}", typeof(T).Name, typeId);

                myTypeMapping[typeof(T)] = typeId;
                myReaders[typeId]        = (ctx, unsafeReader) => reader(ctx, unsafeReader);
                myWriters[typeId]        = (ctx, unsafeWriter, value) => writer(ctx, unsafeWriter, (T)value);
            }
        }
예제 #7
0
        private SerializerPair CreateCustomScalar <T>()
        {
            if (typeof(IRdBindable).IsAssignableFrom(typeof(T)))
            {
                Assertion.Fail($"Invalid scalar type: {typeof(T).ToString(true)}. Scalar types cannot be IRdBindable.");
            }
            if (typeof(T).IsInterface || typeof(T).IsAbstract)
            {
                Assertion.Fail($"Invalid scalar type: {typeof(T).ToString(true)}. Scalar types should be concrete types.");
            }

            TypeInfo typeInfo      = typeof(T).GetTypeInfo();
            var      allowNullable = ReflectionSerializerVerifier.CanBeNull(typeInfo);

            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];

            CtxReadDelegate <T> readerDelegate = (ctx, unsafeReader) =>
            {
                if (allowNullable && !unsafeReader.ReadNullness())
                {
                    return(default);
예제 #8
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));
        }
예제 #9
0
파일: RdSet.cs 프로젝트: yvvan/rd
        public RdSet(CtxReadDelegate <T> readValue, CtxWriteDelegate <T> writeValue, IViewableSet <T> backingSet)
        {
            ValueCanBeNull     = false;
            ReadValueDelegate  = readValue;
            WriteValueDelegate = writeValue;

            mySet = backingSet ?? new ViewableSet <T>();
        }
예제 #10
0
파일: RdMap.cs 프로젝트: yvvan/rd
        public RdMap(CtxReadDelegate <K> readKey, CtxWriteDelegate <K> writeKey, CtxReadDelegate <V> readValue, CtxWriteDelegate <V> writeValue)
        {
            ValueCanBeNull = false;

            ReadKeyDelegate  = readKey;
            WriteKeyDelegate = writeKey;

            ReadValueDelegate  = readValue;
            WriteValueDelegate = writeValue;
        }
예제 #11
0
        public RdProperty(CtxReadDelegate <T> readValue, CtxWriteDelegate <T> writeValue)
        {
            ReadValueDelegate  = readValue;
            WriteValueDelegate = writeValue;

            Advise(Lifetime.Eternal, _ =>
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Value"));
            });
        }
예제 #12
0
        private SerializerPair CreateArraySerializer <T>()
        {
            var primitiveSerializer = GetPrimitiveSerializer <T>();
            var valueReader         = primitiveSerializer.GetReader <T>();
            var valueWriter         = primitiveSerializer.GetWriter <T>();

            CtxReadDelegate <T[]>  reader = (ctx, unsafeReader) => unsafeReader.ReadArray(valueReader, ctx);
            CtxWriteDelegate <T[]> writer = (ctx, unsafeWriter, value) => unsafeWriter.WriteArray(valueWriter, ctx, value);

            return(new SerializerPair(reader, writer));
        }
예제 #13
0
            public static SerializerPair CreateFromMethods(MethodInfo readMethod, MethodInfo writeMethod, SerializerPair argumentSerializer)
            {
                void WriterDelegate(SerializationCtx ctx, UnsafeWriter writer, object value) =>
                writeMethod.Invoke(null, new[] { ctx, writer, value, });

                object ReaderDelegate(SerializationCtx ctx, UnsafeReader reader) =>
                readMethod.Invoke(null, new[] { ctx, reader, argumentSerializer.Reader, argumentSerializer.Writer });

                CtxReadDelegate <object>  ctxReadDelegate  = ReaderDelegate;
                CtxWriteDelegate <object> ctxWriteDelegate = WriterDelegate;

                return(new SerializerPair(ctxReadDelegate, ctxWriteDelegate));
            }
예제 #14
0
        public static void WriteCollection <T>(this UnsafeWriter writer, CtxWriteDelegate <T> itemWriter, SerializationCtx ctx, ICollection <T> value)
        {
            if (value == null)
            {
                writer.Write(-1);
                return;
            }

            writer.Write(value.Count);
            foreach (var item in value)
            {
                itemWriter(ctx, writer, item);
            }
        }
예제 #15
0
        public static void WriteArray <T>(this UnsafeWriter writer, CtxWriteDelegate <T> itemWriter, SerializationCtx ctx, T[] value)
        {
            if (value == null)
            {
                writer.Write(-1);
                return;
            }

            writer.Write(value.Length);
            // ReSharper disable once ForCanBeConvertedToForeach
            for (var i = 0; i < value.Length; i++)
            {
                itemWriter(ctx, writer, value[i]);
            }
        }
예제 #16
0
파일: RdList.cs 프로젝트: epeshk/rd
        public RdList(CtxReadDelegate <V> readValue, CtxWriteDelegate <V> writeValue, long nextVersion = 1L)
        {
            myNextVersion  = nextVersion;
            ValueCanBeNull = false;

            ReadValueDelegate  = readValue;
            WriteValueDelegate = writeValue;

            //WPF integration
            this.AdviseAddRemove(Lifetime.Eternal, (kind, idx, v) =>
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Item[]"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Count"));
#if !NET35
                CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(kind == AddRemove.Add ? NotifyCollectionChangedAction.Add : NotifyCollectionChangedAction.Remove, v, idx));
  #endif
            });
        }
예제 #17
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);
예제 #18
0
파일: RdTaskResult.cs 프로젝트: yvvan/rd
        public static void Write(CtxWriteDelegate <T> writeDelegate, SerializationCtx ctx, UnsafeWriter writer, RdTaskResult <T> value)
        {
            writer.Write((int)value.Status);

            switch (value.Status)
            {
            case RdTaskStatus.Success:
                writeDelegate(ctx, writer, value.Result);
                break;

            case RdTaskStatus.Canceled:
                break;

            case RdTaskStatus.Faulted:
                RdFault.Write(ctx, writer, value.Error);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
예제 #19
0
        public static void WriteEnumerable <T>(this UnsafeWriter writer, CtxWriteDelegate <T> itemWriter, SerializationCtx ctx, IEnumerable <T> value)
        {
            if (value == null)
            {
                writer.Write(-1);
                return;
            }

            var cookie = new UnsafeWriter.Bookmark(writer);

            writer.Write(-1); // length
            int i = 0;

            foreach (var item in value)
            {
                ++i;
                itemWriter(ctx, writer, item);
            }

            cookie.WriteIntLength(i);
        }
예제 #20
0
파일: SerializersEx.cs 프로젝트: yvvan/rd
        public static void WriteEnumerable <T>(this UnsafeWriter writer, CtxWriteDelegate <T> itemWriter, SerializationCtx ctx, IEnumerable <T> value)
        {
            if (value == null)
            {
                writer.Write(-1);
                return;
            }

            // // Don't dispose this cookie, otherwise it will delete all written data
            var cookie = new UnsafeWriter.Cookie(writer);

            cookie.Writer.Write(-1); // length
            int i = 0;

            foreach (var item in value)
            {
                ++i;
                itemWriter(ctx, writer, item);
            }

            cookie.WriteIntLengthToCookieStart(i);
        }
예제 #21
0
 public static SerializerPair CreateDictionarySerializerPair <TKey, TValue>(SerializerPair keySerializer, SerializerPair valueSerializer)
 {
     var read = CreateReadDictionary <TKey, TValue>(keySerializer, valueSerializer);
     CtxWriteDelegate <IDictionary <TKey, TValue> > write = (ctx, writer, value) =>
     {
         if (value is Dictionary <TKey, TValue> val && !Equals(val.Comparer, EqualityComparer <TKey> .Default))
         {
             throw new Exception($"Unable to serialize {value.GetType().ToString(true)}. Custom equality comparers are not supported");
         }
         if (value == null)
         {
             writer.Write(-1);
             return;
         }
         writer.Write(value.Count);
         var keyw   = keySerializer.GetWriter <TKey>();
         var valuew = valueSerializer.GetWriter <TValue>();
         foreach (var kvp in value)
         {
             keyw(ctx, writer, kvp.Key);
             valuew(ctx, writer, kvp.Value);
         }
     };
예제 #22
0
        public static RdProperty <T> Read(SerializationCtx ctx, UnsafeReader reader, CtxReadDelegate <T> readValue, CtxWriteDelegate <T> writeValue)
        {
            var id  = reader.ReadRdId();
            var res = new RdProperty <T>(readValue, writeValue).WithId(id);

            if (reader.ReadBool())
            {
                res.myProperty.Value = readValue(ctx, reader);
            }
            return(res);
        }
예제 #23
0
 public RdProperty(CtxReadDelegate <T> readValue, CtxWriteDelegate <T> writeValue, T defaultValue) : this(readValue, writeValue)
 {
     Value = defaultValue;
 }
예제 #24
0
 public static CtxWriteDelegate <T> Interned <T>(this CtxWriteDelegate <T> inner, string internKey)
 {
     return((ctx, reader, value) => ctx.WriteInterned(reader, value, internKey, inner));
 }
예제 #25
0
 public static CtxWriteDelegate <T?> NullableStruct <T>(this CtxWriteDelegate <T> inner) where T : struct
 {
     return((ctx, reader, value) => reader.WriteNullableStruct(inner, ctx, value));
 }
예제 #26
0
 public static CtxWriteDelegate <T> NullableClass <T>(this CtxWriteDelegate <T> inner) where T : class
 {
     return((ctx, reader, value) => reader.WriteNullableClass(inner, ctx, value));
 }
예제 #27
0
 public static CtxWriteDelegate <List <T> > List <T>(this CtxWriteDelegate <T> inner)
 {
     return((ctx, reader, value) => reader.WriteList(inner, ctx, value));
 }
예제 #28
0
 //Writers
 public static CtxWriteDelegate <T[]> Array <T>(this CtxWriteDelegate <T> inner)
 {
     return((ctx, reader, value) => reader.WriteArray(inner, ctx, value));
 }
예제 #29
0
 private static CtxWriteDelegate <object> CtxWriteTypedToObject <T>(CtxWriteDelegate <T> typedDelegate)
 {
     return((ctx, unsafeWriter, value) => typedDelegate(ctx, unsafeWriter, (T)value));
 }
예제 #30
0
 public void Register <T>(CtxReadDelegate <T> reader, CtxWriteDelegate <T> writer, int?predefinedType = null)
 {
     myStore[typeof(T)] = new SerializerPair(reader, writer);
 }