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); }
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)); }
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); }
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 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)); }
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)); }
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)); }
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)); }
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)); }