public RdCall(CtxReadDelegate <TReq> readRequest, CtxWriteDelegate <TReq> writeRequest, CtxReadDelegate <TRes> readResponse, CtxWriteDelegate <TRes> writeResponse) { ReadRequestDelegate = readRequest; WriteRequestDelegate = writeRequest; ReadResponseDelegate = readResponse; WriteResponseDelegate = writeResponse; }
public static RdList <V> Read(SerializationCtx ctx, UnsafeReader reader, CtxReadDelegate <V> readValue, CtxWriteDelegate <V> writeValue) { var nextVersion = reader.ReadLong(); var id = reader.ReadRdId(); return(new RdList <V>(readValue, writeValue, nextVersion).WithId(id)); }
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); } }
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)); }
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);
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); } } }
/// <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 T ReadInterned <T>(UnsafeReader stream, string internKey, CtxReadDelegate <T> readValueDelegate) { if (!InternRoots.TryGetValue(internKey, out var interningRoot)) { return(readValueDelegate(this, stream)); } return(interningRoot.UnIntern <T>(stream.ReadInt() ^ 1)); }
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 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 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 T ReadInterned <T>(UnsafeReader stream, string internKey, CtxReadDelegate <T> readValueDelegate) { if (!InternRoots.TryGetValue(internKey, out var interningRoot)) { return(readValueDelegate(this, stream)); } var id = InternId.Read(stream); if (id.IsValid) { return(interningRoot.UnIntern <T>(id)); } return(readValueDelegate(this, stream)); }
public static RdTaskResult <T> Read(CtxReadDelegate <T> readDelegate, SerializationCtx ctx, UnsafeReader reader) { var status = (RdTaskStatus)reader.ReadInt(); switch (status) { case RdTaskStatus.Success: return(Success(readDelegate(ctx, reader))); case RdTaskStatus.Canceled: return(Cancelled()); case RdTaskStatus.Faulted: return(Faulted(RdFault.Read(ctx, reader))); default: throw new ArgumentOutOfRangeException($"Unknown status of {nameof(RdTaskStatus)}: {status}"); } }
public static T[] ReadArray <T>(this UnsafeReader reader, CtxReadDelegate <T> itemReader, SerializationCtx ctx) { int count = reader.ReadInt32(); if (count < 0) { return(null); } var res = new T[count]; for (var i = 0; i < count; i++) { res[i] = itemReader(ctx, reader); } return(res); }
public static List <T> ReadList <T>(this UnsafeReader reader, CtxReadDelegate <T> itemReader, SerializationCtx ctx) { int count = reader.ReadInt32(); if (count < 0) { return(null); } var res = new List <T>(count); for (var i = 0; i < count; i++) { res.Add(itemReader(ctx, reader)); } return(res); }
public T Read <T>(SerializationCtx ctx, UnsafeReader reader, [CanBeNull] CtxReadDelegate <T> unknownInstanceReader = null) { bool TryGetReader(RdId rdId, out CtxReadDelegate <object> readDelegate) { lock (myLock) return(myReaders.TryGetValue(rdId, out readDelegate)); } #if !NET35 myBackgroundRegistrar.WaitForEmpty(); #endif var typeId = RdId.Read(reader); if (typeId.IsNil) { return(default(T)); } var size = reader.ReadInt(); if (!TryGetReader(typeId, out var ctxReadDelegate)) { if (unknownInstanceReader == null) { myRegistrar?.TryRegister(typeId, this); myRegistrar?.TryRegister(typeof(T), this); if (!TryGetReader(typeId, out ctxReadDelegate)) { var realType = myTypeMapping.SingleOrDefault(c => Equals(c.Value, typeId)); //ok because it's rarely needed throw new KeyNotFoundException(string.Format("There is no readers found. Requested type '{0}'. Real type {1}", typeof(T).FullName, realType)); } } else { var objectStart = reader.Position; var result = unknownInstanceReader(ctx, reader); var bytesRead = reader.Position - objectStart; reader.Skip(size - bytesRead); return(result); } } var uncasted = ctxReadDelegate(ctx, reader); Assertion.Assert(uncasted is T, "Bad cast for id {0}. Expected: {1}, actual: {2}", typeId, typeof(T).Name, uncasted.GetType().Name); return((T)uncasted); }
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 RdProperty(CtxReadDelegate <T> readValue, CtxWriteDelegate <T> writeValue, T defaultValue) : this(readValue, writeValue) { Value = defaultValue; }
public static CtxReadDelegate <T> Interned <T>(this CtxReadDelegate <T> inner, string internKey) { return((ctx, reader) => ctx.ReadInterned(reader, internKey, inner)); }
public static CtxReadDelegate <T?> NullableStruct <T>(this CtxReadDelegate <T> inner) where T : struct { return((ctx, reader) => reader.ReadNullableStruct(inner, ctx)); }
public static CtxReadDelegate <T> NullableClass <T>(this CtxReadDelegate <T> inner) where T : class { return((ctx, reader) => reader.ReadNullableClass(inner, ctx)); }
public static CtxReadDelegate <List <T> > List <T>(this CtxReadDelegate <T> inner) { return((ctx, reader) => reader.ReadList(inner, ctx)); }
// Composition functors //Readers public static CtxReadDelegate <T[]> Array <T>(this CtxReadDelegate <T> inner) { return((ctx, reader) => reader.ReadArray(inner, ctx)); }
public static T?ReadNullableStruct <T>(this UnsafeReader reader, CtxReadDelegate <T> itemReader, SerializationCtx ctx) where T : struct { return(reader.ReadNullness() ? itemReader(ctx, reader).ToNullable() : null); }
public static T ReadNullableClass <T>(this UnsafeReader reader, CtxReadDelegate <T> itemReader, SerializationCtx ctx) where T : class { return(reader.ReadNullness() ? itemReader(ctx, reader) : null); }
public void Register <T>(CtxReadDelegate <T> reader, CtxWriteDelegate <T> writer, int?predefinedType = null) { myStore[typeof(T)] = new SerializerPair(reader, writer); }