public static Expression Create(QbservableProtocol protocol, object instance, MethodInfo method, IEnumerable <Expression> argExpressions)
 {
     return(CreateInvoke(
                new DuplexCallback(protocol, (id, arguments) => ConvertIfSequence(protocol, id, method.Invoke(instance, arguments))),
                method.ReturnType,
                argExpressions));
 }
        private static object ConvertIfSequence(QbservableProtocol protocol, int id, 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 <>));

                    if (enumerableType != null)
                    {
                        return(CreateRemoteEnumerable(protocol, (IEnumerable)instance, enumerableType.GetGenericArguments()[0]));
                    }
                    else if (instance is IEnumerable)
                    {
                        var enumerable = (IEnumerable)instance;

                        return(CreateRemoteEnumerable(protocol, enumerable.Cast <object>(), typeof(object)));
                    }
                }
            }

            return(instance);
        }
Пример #3
0
 private IObservable <TResult> ReadObservable(Stream 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));
        }
Пример #7
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);
        }
        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);
            }
        }
Пример #11
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);
        }
        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);
        }
Пример #13
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));
        }
Пример #14
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)));
        }
 public static Expression Create(QbservableProtocol protocol, object instance, PropertyInfo property)
 {
     return(CreateInvoke(
                new DuplexCallback(protocol, (id, __) => ConvertIfSequence(protocol, id, property.GetValue(instance))),
                property.PropertyType));
 }
 public abstract Expression Invoke(MethodCallExpression call, ExpressionVisitor visitor, QbservableProtocol protocol);
 public abstract Expression GetValue(FieldInfo field, MemberExpression member, ExpressionVisitor visitor, QbservableProtocol protocol);
 public abstract Expression GetValue(PropertyInfo property, MemberExpression member, ExpressionVisitor visitor, QbservableProtocol protocol);
        internal Expression GetValue(MemberExpression member, ExpressionVisitor visitor, QbservableProtocol protocol)
        {
            var property = member.Member as PropertyInfo;

            if (property != null)
            {
                return(GetValue(property, member, visitor, protocol));
            }
            else
            {
                return(GetValue((FieldInfo)member.Member, member, visitor, protocol));
            }
        }
 protected abstract Either <object, Expression> TryEvaluateEnumerable(object value, Type type, QbservableProtocol protocol);
        protected Either <object, Expression> TryEvaluateSequences(object value, Type type, QbservableProtocol protocol)
        {
            if (value != null)
            {
                var isSequence = type == typeof(IEnumerable) ||
                                 type.IsGenericType &&
                                 (type.GetGenericTypeDefinition() == typeof(IEnumerable <>) ||
                                  type.GetGenericTypeDefinition() == typeof(IObservable <>));

                if (isSequence || !IsTypeKnown(value))
                {
                    var result = TryEvaluateEnumerable(value, type, protocol);

                    if (result != null)
                    {
                        return(result);
                    }
                    else
                    {
                        var expression = TryEvaluateObservable(value, type, protocol);

                        if (expression != null)
                        {
                            return(Either.Right <object, Expression>(expression));
                        }
                    }
                }
            }

            return(null);
        }
 protected abstract Expression TryEvaluateObservable(object value, Type type, QbservableProtocol protocol);
 private DuplexCallback(QbservableProtocol protocol, Func <int, object[], object> callback)
 {
     this.id = protocol
               .GetOrAddSink(protocol.CreateClientDuplexSinkInternal)
               .RegisterInvokeCallback(arguments => callback(this.id, 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);

            var value = field.GetValue(instance);

            var either = TryEvaluateSequences(value, field.FieldType, protocol);

            return(either == null
                                ? Expression.Constant(value, field.FieldType)
                                : either.IsLeft
                                        ? Expression.Constant(either.Left, field.FieldType)
                                        : either.Right);
        }
 public static Expression Create(QbservableProtocol protocol, object instance, FieldInfo field)
 {
     return(CreateInvoke(
                new DuplexCallback(protocol, (id, __) => ConvertIfSequence(protocol, id, field.GetValue(instance))),
                field.FieldType));
 }
Пример #26
0
        public override Expression Invoke(MethodCallExpression call, ExpressionVisitor visitor, QbservableProtocol protocol)
        {
            if (call.Method.ReturnType == typeof(void))
            {
                throw new InvalidOperationException(Errors.ExpressionCallLocalVoidFormat);
            }

            object instance = Evaluate(call.Object, visitor, Errors.ExpressionCallMissingLocalInstanceFormat, call.Method);

            var result = call.Method.Invoke(instance, EvaluateArguments(call, visitor).ToArray());

            var either = TryEvaluateSequences(result, call.Type, protocol);

            return(either == null
                                        ? Expression.Constant(result, call.Type)
                                        : either.IsLeft
                                                ? Expression.Constant(either.Left, call.Type)
                                                : either.Right);
        }
 public static Expression CreateObservable(QbservableProtocol protocol, object instance, Type dataType, Type type)
 {
     return(Expression.Constant(
                CreateRemoteObservable(protocol, instance, dataType),
                type));
 }
Пример #28
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);
        }
 public override Task InitializeAsync(QbservableProtocol <QbservableMessage> protocol, CancellationToken cancel)
 {
     return(Task.FromResult(false));
 }
Пример #30
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));
        }