Пример #1
0
 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));
 }
Пример #2
0
        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);
        }
Пример #3
0
 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);
 }
Пример #4
0
 public TcpServerQbservableProvider(
     QbservableProtocol protocol,
     QbservableServiceOptions options,
     Func <object, IQbservable <TSource> > sourceSelector)
 {
     this.protocol       = protocol;
     this.options        = options;
     this.sourceSelector = sourceSelector;
 }
Пример #5
0
        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));
        }
Пример #6
0
        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));
        }
Пример #7
0
        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
        }
Пример #8
0
        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);
        }
Пример #9
0
        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);
            }
        }
Пример #10
0
        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);
        }
Пример #11
0
        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);
            }
        }
Пример #12
0
        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);
        }
Пример #13
0
        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);
        }
Пример #14
0
 public static DuplexQbservableMessage CreateOnCompleted(DuplexCallbackId id, QbservableProtocol protocol)
 {
     return(CreateWithoutValue(QbservableProtocolMessageKind.DuplexOnCompleted, id, protocol));
 }
Пример #15
0
 public static DuplexQbservableMessage CreateOnNext(DuplexCallbackId id, object value, QbservableProtocol protocol)
 {
     return(new DuplexQbservableMessage(QbservableProtocolMessageKind.DuplexOnNext, id, value, Serialize(id, value, protocol)));
 }
Пример #16
0
 public static DuplexQbservableMessage CreateSubscribeResponse(DuplexCallbackId id, int clientSubscriptionId, QbservableProtocol protocol)
 {
     return(new DuplexQbservableMessage(QbservableProtocolMessageKind.DuplexSubscribeResponse, id, clientSubscriptionId, Serialize(id, clientSubscriptionId, protocol)));
 }
Пример #17
0
 public static DuplexQbservableMessage CreateDisposeEnumerator(int clientId, QbservableProtocol protocol)
 {
     return(CreateWithoutValue(QbservableProtocolMessageKind.DuplexDisposeEnumerator, clientId, protocol));
 }
Пример #18
0
 public static DuplexQbservableMessage CreateResetEnumerator(DuplexCallbackId id, QbservableProtocol protocol)
 {
     return(CreateWithoutValue(QbservableProtocolMessageKind.DuplexResetEnumerator, id, protocol));
 }
Пример #19
0
 public override Task InitializeAsync(QbservableProtocol <TSource, TMessage> protocol, CancellationToken cancel)
 {
     Contract.Requires(protocol != null);
     return(null);
 }
Пример #20
0
 public static DuplexQbservableMessage CreateSubscribe(DuplexCallbackId id, QbservableProtocol protocol)
 {
     return(CreateWithoutValue(QbservableProtocolMessageKind.DuplexSubscribe, id, protocol));
 }
Пример #21
0
 public static DuplexQbservableMessage CreateInvoke(DuplexCallbackId id, object[] arguments, QbservableProtocol protocol)
 {
     return(new DuplexQbservableMessage(QbservableProtocolMessageKind.DuplexInvoke, id, arguments, Serialize(id, arguments, protocol)));
 }
Пример #22
0
        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);
        }
Пример #23
0
        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)));
        }
Пример #24
0
        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));
        }
Пример #25
0
 public static DuplexQbservableMessage CreateOnError(DuplexCallbackId id, Exception error, QbservableProtocol protocol)
 {
     return(new DuplexQbservableMessage(QbservableProtocolMessageKind.DuplexOnError, id, error, Serialize(id, error, protocol)));
 }
Пример #26
0
 public static DuplexQbservableMessage CreateDisposeSubscription(int subscriptionId, QbservableProtocol protocol)
 {
     return(CreateWithoutValue(QbservableProtocolMessageKind.DuplexDisposeSubscription, subscriptionId, protocol));
 }
Пример #27
0
 private static DuplexQbservableMessage CreateWithoutValue(QbservableProtocolMessageKind kind, DuplexCallbackId id, QbservableProtocol protocol)
 {
     return(new DuplexQbservableMessage(kind, id, value: null, data: Serialize(id, null, protocol)));
 }
Пример #28
0
 public static DuplexQbservableMessage CreateMoveNext(DuplexCallbackId id, QbservableProtocol protocol)
 {
     return(CreateWithoutValue(QbservableProtocolMessageKind.DuplexMoveNext, id, protocol));
 }
Пример #29
0
        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));
        }
Пример #30
0
 public abstract Task InitializeAsync(QbservableProtocol <TSource, TMessage> protocol, CancellationToken cancel);