public RdCall(CtxReadDelegate <TReq> readRequest, CtxWriteDelegate <TReq> writeRequest, CtxReadDelegate <TRes> readResponse, CtxWriteDelegate <TRes> writeResponse) { ReadRequestDelegate = readRequest; WriteRequestDelegate = writeRequest; ReadResponseDelegate = readResponse; WriteResponseDelegate = writeResponse; }
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); } }
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)); }
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); } }
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); } } }
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); } }
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);
/// <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)); }
public RdSet(CtxReadDelegate <T> readValue, CtxWriteDelegate <T> writeValue, IViewableSet <T> backingSet) { ValueCanBeNull = false; ReadValueDelegate = readValue; WriteValueDelegate = writeValue; mySet = backingSet ?? new ViewableSet <T>(); }
public RdMap(CtxReadDelegate <K> readKey, CtxWriteDelegate <K> writeKey, CtxReadDelegate <V> readValue, CtxWriteDelegate <V> writeValue) { ValueCanBeNull = false; ReadKeyDelegate = readKey; WriteKeyDelegate = writeKey; ReadValueDelegate = readValue; WriteValueDelegate = writeValue; }
public RdProperty(CtxReadDelegate <T> readValue, CtxWriteDelegate <T> writeValue) { ReadValueDelegate = readValue; WriteValueDelegate = writeValue; Advise(Lifetime.Eternal, _ => { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Value")); }); }
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)); }
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)); }
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); } }
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]); } }
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 }); }
/// <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);
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(); } }
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); }
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); }
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); } };
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); }
public RdProperty(CtxReadDelegate <T> readValue, CtxWriteDelegate <T> writeValue, T defaultValue) : this(readValue, writeValue) { Value = defaultValue; }
public static CtxWriteDelegate <T> Interned <T>(this CtxWriteDelegate <T> inner, string internKey) { return((ctx, reader, value) => ctx.WriteInterned(reader, value, internKey, inner)); }
public static CtxWriteDelegate <T?> NullableStruct <T>(this CtxWriteDelegate <T> inner) where T : struct { return((ctx, reader, value) => reader.WriteNullableStruct(inner, ctx, value)); }
public static CtxWriteDelegate <T> NullableClass <T>(this CtxWriteDelegate <T> inner) where T : class { return((ctx, reader, value) => reader.WriteNullableClass(inner, ctx, value)); }
public static CtxWriteDelegate <List <T> > List <T>(this CtxWriteDelegate <T> inner) { return((ctx, reader, value) => reader.WriteList(inner, ctx, value)); }
//Writers public static CtxWriteDelegate <T[]> Array <T>(this CtxWriteDelegate <T> inner) { return((ctx, reader, value) => reader.WriteArray(inner, ctx, value)); }
private static CtxWriteDelegate <object> CtxWriteTypedToObject <T>(CtxWriteDelegate <T> typedDelegate) { return((ctx, unsafeWriter, value) => typedDelegate(ctx, unsafeWriter, (T)value)); }
public void Register <T>(CtxReadDelegate <T> reader, CtxWriteDelegate <T> writer, int?predefinedType = null) { myStore[typeof(T)] = new SerializerPair(reader, writer); }