示例#1
0
        /// <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);
        }
示例#2
0
        // 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;
			}