Beispiel #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);
        }
Beispiel #2
0
        // Process reply message
        protected override bool ProcessMessage
            (int opcode, Object oReply)
        {
            byte[]       data;
            MemoryStream mem;
            QDataStream  ds;
            DcopReply    reply = oReply as DcopReply;

            key = ReceiveHeader(4);               // Read 4-byte DCOP key

            data = Receive();                     // Read all data
            mem  = new MemoryStream(data);
            ds   = new QDataStream(mem);

            switch ((DcopMinorOpcode)opcode)
            {
            case DcopMinorOpcode.DcopReply:
                reply.status        = DcopReply.ReplyStatus.Ok;
                reply.transactionId = 0;
                reply.calledApp     = ds.ReadString();
                ds.ReadString();                                // That's our app.
                reply.replyType = ds.ReadString();
                ds.ReadInt32();                                 // Reply length, throw it!
                reply.replyObject = ds.ReadObject(reply.replyType);
                return(true);

            case DcopMinorOpcode.DcopReplyFailed:
                reply.status        = DcopReply.ReplyStatus.Failed;
                reply.transactionId = 0;
                return(true);

            // Following are just temporally solution, but for now it's good.
            case DcopMinorOpcode.DcopReplyWait:
                reply.status    = DcopReply.ReplyStatus.Pending;
                reply.calledApp = ds.ReadString();
                ds.ReadString();
                reply.transactionId = ds.ReadInt32();
                return(true);

            case DcopMinorOpcode.DcopReplyDelayed:
                string ca = ds.ReadString();
                ds.ReadString();
                int ti = ds.ReadInt32();
                if (ca != reply.calledApp || ti != reply.transactionId)
                {
                    return(false);                                    // Got not that reply what was looking for
                }
                reply.status        = DcopReply.ReplyStatus.Ok;
                reply.transactionId = 0;
                reply.replyType     = ds.ReadString();
                ds.ReadInt32();                                 // Reply length, throw it!
                reply.replyObject = ds.ReadObject(reply.replyType);
                return(true);

            default:
                return(false);                                // TODO
            }
        }
Beispiel #3
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;
			}
	// Process reply message
	protected override bool ProcessMessage
				(int opcode, Object oReply)
			{
				byte[] data;
				MemoryStream mem;
				QDataStream ds;
				DcopReply reply = oReply as DcopReply;
				key = ReceiveHeader(4); // Read 4-byte DCOP key

				data = Receive(); // Read all data
				mem = new MemoryStream(data);
				ds = new QDataStream(mem);

				switch((DcopMinorOpcode)opcode)
				{
					case DcopMinorOpcode.DcopReply:
						reply.status = DcopReply.ReplyStatus.Ok;
						reply.transactionId = 0;
						reply.calledApp = ds.ReadString();
						ds.ReadString(); // That's our app.
						reply.replyType = ds.ReadString();
						ds.ReadInt32(); // Reply length, throw it!
						reply.replyObject = ds.ReadObject(reply.replyType);
						return true;
					case DcopMinorOpcode.DcopReplyFailed:
						reply.status = DcopReply.ReplyStatus.Failed;
						reply.transactionId = 0;
						return true;
					// Following are just temporally solution, but for now it's good.
					case DcopMinorOpcode.DcopReplyWait:
						reply.status = DcopReply.ReplyStatus.Pending;
						reply.calledApp = ds.ReadString();
						ds.ReadString();
						reply.transactionId = ds.ReadInt32();
						return true;
					case DcopMinorOpcode.DcopReplyDelayed:
						string ca = ds.ReadString();
						ds.ReadString();
						int ti = ds.ReadInt32();
						if( ca != reply.calledApp || ti != reply.transactionId)
						{
							return false; // Got not that reply what was looking for
						}
						reply.status = DcopReply.ReplyStatus.Ok;
						reply.transactionId = 0;
						reply.replyType = ds.ReadString();
						ds.ReadInt32(); // Reply length, throw it!
						reply.replyObject = ds.ReadObject(reply.replyType);
						return true;
					default:
						return false; // TODO
				}
			}