public static Expression Create(QbservableProtocol protocol, object instance, MethodInfo method, IEnumerable <Expression> argExpressions) { return(CreateInvoke( new DuplexCallback(protocol, (_, arguments) => ConvertIfSequence(protocol, method.Invoke(instance, arguments))), method.ReturnType, argExpressions)); }
private static object ConvertIfSequence(QbservableProtocol protocol, object instance) { if (instance != null) { var type = instance.GetType(); if (!type.IsSerializable) { var observableType = type.GetGenericInterfaceFromDefinition(typeof(IObservable <>)); if (observableType != null) { return(CreateRemoteObservable(protocol, instance, observableType.GetGenericArguments()[0])); } var enumerableType = type.GetGenericInterfaceFromDefinition(typeof(IEnumerable <>)); var enumerable = instance as IEnumerable; if (enumerableType != null) { return(CreateRemoteEnumerable(protocol, enumerable, enumerableType.GetGenericArguments()[0])); } else if (enumerable != null) { return(CreateRemoteEnumerable(protocol, enumerable.Cast <object>(), typeof(object))); } } } return(instance); }
private IObservable <TResult> ReadObservable(NetworkStream stream, CancellationToken cancel) { return(from protocol in QbservableProtocol.NegotiateClientAsync(stream, Provider.Formatter, cancel).ToObservable() from result in protocol .ExecuteClient <TResult>(PrepareExpression(protocol), argument) .Finally(protocol.Dispose) select result); }
public TcpServerQbservableProvider( QbservableProtocol protocol, QbservableServiceOptions options, Func <object, IQbservable <TSource> > sourceSelector) { this.protocol = protocol; this.options = options; this.sourceSelector = sourceSelector; }
private static object CreateRemoteObservable(QbservableProtocol protocol, object instance, Type dataType) { var sink = protocol.GetOrAddSink(protocol.CreateClientDuplexSinkInternal); int id = 0; id = sink.RegisterObservableCallback(serverId => Subscribe(sink, new DuplexCallbackId(id, serverId), instance, dataType)); return(Activator.CreateInstance(typeof(DuplexCallbackObservable <>).MakeGenericType(dataType), id)); }
private static object CreateRemoteEnumerable(QbservableProtocol protocol, IEnumerable instance, Type dataType) { var sink = protocol.GetOrAddSink(protocol.CreateClientDuplexSinkInternal); int id = 0; id = sink.RegisterEnumerableCallback(instance.GetEnumerator); return(Activator.CreateInstance(typeof(DuplexCallbackEnumerable <>).MakeGenericType(dataType), id)); }
public override Task InitializeAsync(QbservableProtocol <Stream, StreamMessage> protocol, CancellationToken cancel) { Contract.Assume(this.protocol == protocol); #if ASYNCAWAIT return(Task.FromResult(true)); #else return(TaskEx.FromResult(true)); #endif }
protected override Expression TryEvaluateObservable(object value, Type type, QbservableProtocol protocol) { var observableType = value.GetType().GetGenericInterfaceFromDefinition(typeof(IObservable <>)); if (observableType != null) { return(DuplexCallback.CreateObservable(protocol, value, observableType.GetGenericArguments()[0], type)); } return(null); }
public void SetServerProtocol(QbservableProtocol protocol) { Contract.Requires(protocol != null); this.protocol = protocol; this.sink = protocol.FindSink <IServerDuplexQbservableProtocolSink>(); if (sink == null) { throw new InvalidOperationException(Errors.ProtocolDuplexSinkUnavailableForClientCallback); } }
private static byte[] Serialize(DuplexCallbackId id, object value, QbservableProtocol protocol) { var idData = BitConverter.GetBytes(id); long serializedDataLength; var serializedData = protocol.Serialize(value, out serializedDataLength); var data = new byte[idData.Length + serializedDataLength]; Array.Copy(idData, data, idData.Length); Array.Copy(serializedData, 0, data, idData.Length, serializedDataLength); return(data); }
public static bool TryParse(QbservableMessage message, QbservableProtocol protocol, out DuplexQbservableMessage duplexMessage) { switch (message.Kind) { case QbservableProtocolMessageKind.DuplexInvoke: case QbservableProtocolMessageKind.DuplexResponse: case QbservableProtocolMessageKind.DuplexSubscribeResponse: case QbservableProtocolMessageKind.DuplexGetEnumeratorResponse: case QbservableProtocolMessageKind.DuplexEnumeratorResponse: case QbservableProtocolMessageKind.DuplexOnNext: // The following cases are handled the same as the above cases to ensure that extra data is read, though it's unexpected. case QbservableProtocolMessageKind.DuplexOnCompleted: case QbservableProtocolMessageKind.DuplexSubscribe: case QbservableProtocolMessageKind.DuplexDisposeSubscription: case QbservableProtocolMessageKind.DuplexGetEnumerator: case QbservableProtocolMessageKind.DuplexMoveNext: case QbservableProtocolMessageKind.DuplexResetEnumerator: case QbservableProtocolMessageKind.DuplexDisposeEnumerator: duplexMessage = new DuplexQbservableMessage( message.Kind, BitConverter.ToInt64(message.Data, 0), protocol.Deserialize <object>(message.Data, offset: DuplexCallbackId.Size), message.Data, message.Length); return(true); case QbservableProtocolMessageKind.DuplexErrorResponse: case QbservableProtocolMessageKind.DuplexGetEnumeratorErrorResponse: case QbservableProtocolMessageKind.DuplexEnumeratorErrorResponse: case QbservableProtocolMessageKind.DuplexOnError: duplexMessage = new DuplexQbservableMessage( message.Kind, BitConverter.ToInt64(message.Data, 0), protocol.Deserialize <Exception>(message.Data, offset: DuplexCallbackId.Size), message.Data, message.Length); return(true); default: duplexMessage = null; return(false); } }
public Expression PrepareExpression(QbservableProtocol protocol) { QbservableProviderDiagnostics.DebugPrint(Expression, "TcpClientQuery Original Expression"); if (!Expression.Type.IsGenericType || (Expression.Type.GetGenericTypeDefinition() != typeof(IQbservable <>) && Expression.Type.GetGenericTypeDefinition() != typeof(TcpClientQuery <>))) { throw new InvalidOperationException("The query must end as an IQbservable<T>."); } var visitor = ReplaceConstantsVisitor.CreateForGenericTypeByDefinition( typeof(TcpClientQuery <>), (_, actualType) => Activator.CreateInstance(typeof(QbservableSourcePlaceholder <>).MakeGenericType(actualType.GetGenericArguments()[0]), true), type => typeof(IQbservable <>).MakeGenericType(type.GetGenericArguments()[0])); var result = visitor.Visit(Expression); if (visitor.ReplacedConstants == 0) { throw new InvalidOperationException("A queryable observable service was not found in the query."); } var evaluator = Provider.LocalEvaluator; if (!evaluator.IsKnownType(Provider.SourceType)) { evaluator.AddKnownType(Provider.SourceType); } var evaluationVisitor = new LocalEvaluationVisitor(evaluator, protocol); var preparedExpression = evaluationVisitor.Visit(result); QbservableProviderDiagnostics.DebugPrint(preparedExpression, "TcpClientQuery Rewritten Expression"); return(preparedExpression); }
public Expression EvaluateCompilerGenerated(MemberExpression member, QbservableProtocol protocol) { var closure = member.Expression as ConstantExpression; if (closure == null) { return(null); } var instance = closure.Value; object value; Type type; var field = member.Member as FieldInfo; if (field != null) { type = field.FieldType; value = field.GetValue(instance); } else { var property = (PropertyInfo)member.Member; type = property.PropertyType; value = property.GetValue(instance); } var result = TryEvaluateSequences(value, type, protocol); return(result == null ? Expression.Constant(value, type) : result.IsLeft ? Expression.Constant(result.Left, type) : result.Right); }
public static DuplexQbservableMessage CreateOnCompleted(DuplexCallbackId id, QbservableProtocol protocol) { return(CreateWithoutValue(QbservableProtocolMessageKind.DuplexOnCompleted, id, protocol)); }
public static DuplexQbservableMessage CreateOnNext(DuplexCallbackId id, object value, QbservableProtocol protocol) { return(new DuplexQbservableMessage(QbservableProtocolMessageKind.DuplexOnNext, id, value, Serialize(id, value, protocol))); }
public static DuplexQbservableMessage CreateSubscribeResponse(DuplexCallbackId id, int clientSubscriptionId, QbservableProtocol protocol) { return(new DuplexQbservableMessage(QbservableProtocolMessageKind.DuplexSubscribeResponse, id, clientSubscriptionId, Serialize(id, clientSubscriptionId, protocol))); }
public static DuplexQbservableMessage CreateDisposeEnumerator(int clientId, QbservableProtocol protocol) { return(CreateWithoutValue(QbservableProtocolMessageKind.DuplexDisposeEnumerator, clientId, protocol)); }
public static DuplexQbservableMessage CreateResetEnumerator(DuplexCallbackId id, QbservableProtocol protocol) { return(CreateWithoutValue(QbservableProtocolMessageKind.DuplexResetEnumerator, id, protocol)); }
public override Task InitializeAsync(QbservableProtocol <TSource, TMessage> protocol, CancellationToken cancel) { Contract.Requires(protocol != null); return(null); }
public static DuplexQbservableMessage CreateSubscribe(DuplexCallbackId id, QbservableProtocol protocol) { return(CreateWithoutValue(QbservableProtocolMessageKind.DuplexSubscribe, id, protocol)); }
public static DuplexQbservableMessage CreateInvoke(DuplexCallbackId id, object[] arguments, QbservableProtocol protocol) { return(new DuplexQbservableMessage(QbservableProtocolMessageKind.DuplexInvoke, id, arguments, Serialize(id, arguments, protocol))); }
protected override Either <object, Expression> TryEvaluateEnumerable(object value, Type type, QbservableProtocol protocol) { var iterator = value as IEnumerable; if (iterator != null) { var iteratorType = iterator.GetType(); if (iteratorType.GetCustomAttribute <CompilerGeneratedAttribute>(true) != null || (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable <>)) || type == typeof(IEnumerable)) { value = EvaluateIterator(iterator); return(Either.Left <object, Expression>(value)); } } return(null); }
public override Expression Invoke(MethodCallExpression call, ExpressionVisitor visitor, QbservableProtocol protocol) { object instance; if (call.Method.ReturnType == typeof(void)) { instance = null; } else { instance = Evaluate(call.Object, visitor, Errors.ExpressionCallMissingLocalInstanceFormat, call.Method); } return(DuplexCallback.Create(protocol, instance, call.Method, visitor.Visit(call.Arguments))); }
public override Expression GetValue(FieldInfo field, MemberExpression member, ExpressionVisitor visitor, QbservableProtocol protocol) { object instance = Evaluate(member.Expression, visitor, Errors.ExpressionMemberMissingLocalInstanceFormat, member.Member); return(DuplexCallback.Create(protocol, instance, field)); }
public static DuplexQbservableMessage CreateOnError(DuplexCallbackId id, Exception error, QbservableProtocol protocol) { return(new DuplexQbservableMessage(QbservableProtocolMessageKind.DuplexOnError, id, error, Serialize(id, error, protocol))); }
public static DuplexQbservableMessage CreateDisposeSubscription(int subscriptionId, QbservableProtocol protocol) { return(CreateWithoutValue(QbservableProtocolMessageKind.DuplexDisposeSubscription, subscriptionId, protocol)); }
private static DuplexQbservableMessage CreateWithoutValue(QbservableProtocolMessageKind kind, DuplexCallbackId id, QbservableProtocol protocol) { return(new DuplexQbservableMessage(kind, id, value: null, data: Serialize(id, null, protocol))); }
public static DuplexQbservableMessage CreateMoveNext(DuplexCallbackId id, QbservableProtocol protocol) { return(CreateWithoutValue(QbservableProtocolMessageKind.DuplexMoveNext, id, protocol)); }
protected override Either <object, Expression> TryEvaluateEnumerable(object value, Type type, QbservableProtocol protocol) { Expression expression = null; if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { expression = DuplexCallback.CreateEnumerable(protocol, value, type.GetGenericArguments()[0], type); } else if (type == typeof(IEnumerable)) { var enumerable = (IEnumerable)value; expression = DuplexCallback.CreateEnumerable(protocol, enumerable.Cast <object>(), typeof(object), type); } return(expression == null ? null : Either.Right <object, Expression>(expression)); }
public abstract Task InitializeAsync(QbservableProtocol <TSource, TMessage> protocol, CancellationToken cancel);