/// <summary> /// <para>Calls function via this DCOP connection.</para> /// </summary> /// /// <param name="remoteApp"> /// <para>Remote application that will be called.</para> /// </param> /// /// <param name="remoteObject"> /// <para>Remote object in application, whose method will be called.</para> /// </param> /// /// <param name="remoteFunction"> /// <para>Remote function to call. See DcopFunction class for syntax.</para> /// </param> /// /// <param name="parameters"> /// <para>Parameters to pass to function. Keep them in sync with function definition.</para> /// </param> /// /// <value> /// <para>Object, received from remote app. Its type depends on remote app not function name.</para> /// </value> /// /// <exception cref="T:Xsharp.DcopException"> /// <para>Exception raised if there are problems either with connection or naming.</para> /// </exception> public Object Call(String remoteApp, String remoteObject, String remoteFunction, params Object[] parameters) { byte[] header; DcopReply reply; QDataStream ds; DcopFunction fun = new DcopFunction(remoteFunction); MemoryStream mem = new MemoryStream(); try { ds = QDataStream.Marshal(mem, fun, parameters); } catch (Exception) { throw new DcopNamingException("Failed to marshal parameters"); } byte[] data = mem.ToArray(); mem = new MemoryStream(); ds = new QDataStream(mem); ds.Write(appId); ds.Write(remoteApp); ds.Write(remoteObject); ds.Write(fun.Function); ds.Write(data.Length); header = mem.ToArray(); // A *LOT* nicely, isn't? try { BeginMessage((int)DcopMinorOpcode.DcopCall); SendHeader(key, header.Length + data.Length); SendData(header); SendData(data); FinishMessage(); reply = new DcopReply(fun, replyId++); ProcessResponces(reply); // TODO: This is a hack. Do we need message queues? while (reply.status == DcopReply.ReplyStatus.Pending) { ProcessResponces(reply); } } catch (XException xe) { throw new DcopConnectionException("Failed to send message", xe); } if (reply.status == DcopReply.ReplyStatus.Failed) { throw new DcopNamingException("Dcop reply failed, likely that called function does not exists"); } return(reply.replyObject); }
// Factory public static QDataStream Marshal(Stream stream, DcopFunction fun, Object[] parameters) { if (stream == null) { throw new ArgumentNullException("stream", "Argument cannot be null"); } if (fun == null) { throw new ArgumentNullException("fun", "Argument cannot be null"); } QDataStream s = new QDataStream(stream); try { for (int i = 0; i < fun.Length; i++) { switch (fun[i]) { case "bool": s.Write((bool)parameters[i]); break; // FIXME: this assumes that sizeof(our int) == sizeof(dcop client int) // ASSUME makes ASS of yoU and ME :( case "int": s.Write((int)parameters[i]); break; case "Q_UINT32": s.Write((uint)parameters[i]); break; // Much better here! 32 bit is already 32 bit. case "QString": s.WriteUnicode(parameters[i] as string); break; // FIXME: is this correct? case "QStringList": s.WriteUnicode(parameters[i] as string[]); break; case "QCString": s.Write(parameters[i] as string); break; // FIXME: this again requires testing case "QCStringList": s.Write(parameters[i] as string[]); break; // case "QValueList<QCString>": s.WriteStringList(parameters[i] as string[]); break; // case "QValueList<DCOPRef>": s.WriteDcopRefList(parameters[i] as DcopRef[]); break; } } } catch (InvalidCastException ice) { throw new DcopNamingException("Failed to cast parameters", ice); } return(s); }
// Factory public static QDataStream Marshal(Stream stream, DcopFunction fun, Object[] parameters) { if(stream == null) { throw new ArgumentNullException("stream", "Argument cannot be null"); } if(fun == null) { throw new ArgumentNullException("fun", "Argument cannot be null"); } QDataStream s = new QDataStream(stream); try { for(int i = 0; i < fun.Length; i++) { switch (fun[i]) { case "bool": s.Write((bool)parameters[i]); break; // FIXME: this assumes that sizeof(our int) == sizeof(dcop client int) // ASSUME makes ASS of yoU and ME :( case "int": s.Write((int)parameters[i]); break; case "Q_UINT32": s.Write((uint)parameters[i]); break; // Much better here! 32 bit is already 32 bit. case "QString": s.WriteUnicode(parameters[i] as string); break; // FIXME: is this correct? case "QStringList": s.WriteUnicode(parameters[i] as string[]); break; case "QCString": s.Write(parameters[i] as string); break; // FIXME: this again requires testing case "QCStringList": s.Write(parameters[i] as string[]); break; // case "QValueList<QCString>": s.WriteStringList(parameters[i] as string[]); break; // case "QValueList<DCOPRef>": s.WriteDcopRefList(parameters[i] as DcopRef[]); break; } } } catch (InvalidCastException ice) { throw new DcopNamingException("Failed to cast parameters", ice); } return s; }
/// <summary> /// <para>Calls function via this DCOP connection.</para> /// </summary> /// /// <param name="remoteApp"> /// <para>Remote application that will be called.</para> /// </param> /// /// <param name="remoteObject"> /// <para>Remote object in application, whose method will be called.</para> /// </param> /// /// <param name="remoteFunction"> /// <para>Remote function to call. See DcopFunction class for syntax.</para> /// </param> /// /// <param name="parameters"> /// <para>Parameters to pass to function. Keep them in sync with function definition.</para> /// </param> /// /// <value> /// <para>Object, received from remote app. Its type depends on remote app not function name.</para> /// </value> /// /// <exception cref="T:Xsharp.DcopException"> /// <para>Exception raised if there are problems either with connection or naming.</para> /// </exception> public Object Call(String remoteApp, String remoteObject, String remoteFunction, params Object[] parameters) { byte[] header; DcopReply reply; QDataStream ds; DcopFunction fun = new DcopFunction(remoteFunction); MemoryStream mem = new MemoryStream(); try { ds = QDataStream.Marshal(mem, fun, parameters); } catch (Exception) { throw new DcopNamingException("Failed to marshal parameters"); } byte[] data = mem.ToArray(); mem = new MemoryStream(); ds = new QDataStream(mem); ds.Write(appId); ds.Write(remoteApp); ds.Write(remoteObject); ds.Write(fun.Function); ds.Write(data.Length); header = mem.ToArray(); // A *LOT* nicely, isn't? try { BeginMessage((int)DcopMinorOpcode.DcopCall); SendHeader(key, header.Length + data.Length); SendData(header); SendData(data); FinishMessage(); reply = new DcopReply(fun, replyId++); ProcessResponces(reply); // TODO: This is a hack. Do we need message queues? while(reply.status == DcopReply.ReplyStatus.Pending) { ProcessResponces(reply); } } catch (XException xe) { throw new DcopConnectionException("Failed to send message", xe); } if(reply.status == DcopReply.ReplyStatus.Failed) { throw new DcopNamingException("Dcop reply failed, likely that called function does not exists"); } return reply.replyObject; }