ToArray() публичный Метод

public ToArray ( ) : byte[]
Результат byte[]
Пример #1
0
        public static Message CreateUnknownMethodError(MethodCall method_call)
        {
            if (!method_call.message.ReplyExpected)
            {
                return(null);
            }

            string errMsg = String.Format("Method \"{0}\" with signature \"{1}\" on interface \"{2}\" doesn't exist", method_call.Member, method_call.Signature.Value, method_call.Interface);

            Error error = new Error("org.freedesktop.DBus.Error.UnknownMethod", method_call.message.Header.Serial);

            error.message.Signature = new Signature(DType.String);

            MessageWriter writer = new MessageWriter(Connection.NativeEndianness);

            writer.Write(errMsg);
            error.message.Body = writer.ToArray();

            //TODO: we should be more strict here, but this fallback was added as a quick fix for p2p
            if (method_call.Sender != null)
            {
                error.message.Header.Fields[FieldCode.Destination] = method_call.Sender;
            }

            return(error.message);
        }
Пример #2
0
        //TODO: merge this with the above method
        public static Message ConstructReplyFor(MethodCall method_call, Type retType, object retVal)
        {
            MethodReturn method_return = new MethodReturn(method_call.message.Header.Serial);
            Message      replyMsg      = method_return.message;

            Signature inSig = Signature.GetSig(retType);

            if (inSig != Signature.Empty)
            {
                MessageWriter writer = new MessageWriter(Connection.NativeEndianness);
                writer.Write(retType, retVal);
                replyMsg.Body = writer.ToArray();
            }

            //TODO: we should be more strict here, but this fallback was added as a quick fix for p2p
            if (method_call.Sender != null)
            {
                replyMsg.Header.Fields[FieldCode.Destination] = method_call.Sender;
            }

            replyMsg.Signature = inSig;

            //replyMsg.WriteHeader ();

            return(replyMsg);
        }
Пример #3
0
        //should generalize this method
        //it is duplicated in DProxy
        public static Message ConstructReplyFor(MethodCall method_call, object[] vals)
        {
            MethodReturn method_return = new MethodReturn(method_call.message.Header.Serial);
            Message      replyMsg      = method_return.message;

            Signature inSig = Signature.GetSig(vals);

            if (vals != null && vals.Length != 0)
            {
                MessageWriter writer = new MessageWriter(Connection.NativeEndianness);

                foreach (object arg in vals)
                {
                    writer.Write(arg.GetType(), arg);
                }

                replyMsg.Body = writer.ToArray();
            }

            //TODO: we should be more strict here, but this fallback was added as a quick fix for p2p
            if (method_call.Sender != null)
            {
                replyMsg.Header.Fields[FieldCode.Destination] = method_call.Sender;
            }

            replyMsg.Signature = inSig;

            //replyMsg.WriteHeader ();

            return(replyMsg);
        }
Пример #4
0
        public void SendSignal(MethodInfo mi, string @interface, string member, object[] outValues)
        {
            //TODO: make use of bus_name?

            Type[]    outTypes = Mapper.GetTypes(ArgDirection.In, mi.GetParameters());
            Signature outSig   = Signature.GetSig(outTypes);

            Signal signal = new Signal(object_path, @interface, member);

            signal.message.Signature = outSig;

            if (outValues != null && outValues.Length != 0)
            {
                MessageWriter writer = new MessageWriter(Connection.NativeEndianness);
                writer.connection = conn;

                for (int i = 0; i != outTypes.Length; i++)
                {
                    writer.Write(outTypes[i], outValues[i]);
                }

                signal.message.Body = writer.ToArray();
            }

            conn.Send(signal.message);
        }
		public void HandleMethodCall (MethodCall method_call)
		{
			Type type = obj.GetType ();
			//object retObj = type.InvokeMember (msg.Member, BindingFlags.InvokeMethod, null, obj, MessageHelper.GetDynamicValues (msg));

			//TODO: there is no member name mapping for properties etc. yet
			MethodInfo mi = Mapper.GetMethod (type, method_call);

			if (mi == null) {
				conn.MaybeSendUnknownMethodError (method_call);
				return;
			}

			object retObj = null;
			try {
				object[] inArgs = MessageHelper.GetDynamicValues (method_call.message, mi.GetParameters ());
				retObj = mi.Invoke (obj, inArgs);
			} catch (TargetInvocationException e) {
				if (!method_call.message.ReplyExpected)
					return;

				Exception ie = e.InnerException;
				//TODO: complete exception sending support

				Error error = new Error (Mapper.GetInterfaceName (ie.GetType ()), method_call.message.Header.Serial);
				error.message.Signature = new Signature (DType.String);

				MessageWriter writer = new MessageWriter (Connection.NativeEndianness);
				writer.connection = conn;
				writer.Write (ie.Message);
				error.message.Body = writer.ToArray ();

				//TODO: we should be more strict here, but this fallback was added as a quick fix for p2p
				if (method_call.Sender != null)
					error.message.Header.Fields[FieldCode.Destination] = method_call.Sender;

				conn.Send (error.message);
				return;
			}

			if (method_call.message.ReplyExpected) {
				/*
				object[] retObjs;

				if (retObj == null) {
					retObjs = new object[0];
				} else {
					retObjs = new object[1];
					retObjs[0] = retObj;
				}

				Message reply = ConstructReplyFor (method_call, retObjs);
				*/
				Message reply = MessageHelper.ConstructReplyFor (method_call, mi.ReturnType, retObj);
				conn.Send (reply);
			}
		}
Пример #6
0
        public override void HandleMethodCall(MethodCall method_call)
        {
            //object retVal = obj.GetType ().InvokeMember (method_call.Member, BindingFlags.InvokeMethod, null, obj, new object[0]);
            //IDynamicMetaObjectProvider idyn = obj as IDynamicMetaObjectProvider;

            object retVal = null;

            Exception raisedException = null;

            try {
                object[] args = MessageHelper.GetDynamicValues(method_call.message);
                retVal = ops.InvokeMember(obj, method_call.Member, args);
                //retVal = ops.Call (ops.GetMember (obj, method_call.Member), args);
            } catch (Exception e) {
                raisedException = e;
            }

            if (!method_call.message.ReplyExpected)
            {
                return;
            }

            Message msg      = method_call.message;
            Message replyMsg = null;

            if (raisedException == null)
            {
                MethodReturn method_return = new MethodReturn(msg.Header.Serial);
                replyMsg = method_return.message;
                if (retVal != null)
                {
                    if (retVal.GetType().FullName == "IronRuby.Builtins.MutableString")
                    {
                        retVal = retVal.ToString();
                    }
                    // TODO: Invalid sig handling
                    Signature     outSig    = Signature.GetSig(retVal.GetType());
                    MessageWriter retWriter = new MessageWriter();
                    retWriter.Write(retVal.GetType(), retVal);
                    //retWriter.WriteValueType (retVal, retVal.GetType ());
                    replyMsg.Body      = retWriter.ToArray();
                    replyMsg.Signature = outSig;
                }
            }
            else
            {
                Error error = method_call.CreateError(Mapper.GetInterfaceName(raisedException.GetType()), raisedException.Message);
                replyMsg = error.message;
            }

            if (method_call.Sender != null)
            {
                replyMsg.Header[FieldCode.Destination] = method_call.Sender;
            }

            conn.Send(replyMsg);
        }
Пример #7
0
        public void HandleMethodCall(MethodCall method_call)
        {
            Type type = obj.GetType();
            //object retObj = type.InvokeMember (msg.Member, BindingFlags.InvokeMethod, null, obj, MessageHelper.GetDynamicValues (msg));

            //TODO: there is no member name mapping for properties etc. yet
            MethodInfo mi = Mapper.GetMethod(type, method_call);

            if (mi == null)
            {
                conn.MaybeSendUnknownMethodError(method_call);
                return;
            }

            object retObj = null;

            object[] parmValues = MessageHelper.GetDynamicValues(method_call.message, mi.GetParameters());

            try {
                retObj = mi.Invoke(obj, parmValues);
            } catch (TargetInvocationException e) {
                if (!method_call.message.ReplyExpected)
                {
                    return;
                }

                Exception ie = e.InnerException;
                //TODO: complete exception sending support

                Error error = new Error(Mapper.GetInterfaceName(ie.GetType()), method_call.message.Header.Serial);
                error.message.Signature = new Signature(DType.String);

                MessageWriter writer = new MessageWriter(Connection.NativeEndianness);
                writer.connection = conn;
                writer.Write(ie.Message);
                error.message.Body = writer.ToArray();

                //TODO: we should be more strict here, but this fallback was added as a quick fix for p2p
                if (method_call.Sender != null)
                {
                    error.message.Header.Fields[FieldCode.Destination] = method_call.Sender;
                }

                conn.Send(error.message);
                return;
            }

            if (method_call.message.ReplyExpected)
            {
                Message reply = MessageHelper.ConstructDynamicReply(method_call, mi, retObj, parmValues);
                conn.Send(reply);
            }
        }
Пример #8
0
        void RaiseNameSignal(string memberSuffix, string name)
        {
            // Name* signals on org.freedesktop.DBus are connection-specific.
            // We handle them here as a special case.

            Signal        nameSignal = new Signal(Path, DBusInterface, "Name" + memberSuffix);
            MessageWriter mw         = new MessageWriter();

            mw.Write(name);
            nameSignal.message.Body      = mw.ToArray();
            nameSignal.message.Signature = Signature.StringSig;
            Caller.Send(nameSignal.message);
        }
Пример #9
0
        public byte[] GetHeaderData()
        {
            if (Body != null)
            {
                Header.Length = (uint)Body.Length;
            }

            MessageWriter writer = new MessageWriter(Header.Endianness);

            writer.WriteValueType(Header, typeof(Header));
            writer.CloseWrite();

            return(writer.ToArray());
        }
Пример #10
0
        public void WriteHeader()
        {
            if (Body != null)
            {
                Header.Length = (uint)Body.Length;
            }

            MessageWriter writer = new MessageWriter(Connection.NativeEndianness);

            writer.WriteStruct(typeof(Header), Header);
            //writer.WriteFromDict (typeof (FieldCode), typeof (object), Header.Fields);
            writer.CloseWrite();
            HeaderData = writer.ToArray();
        }
Пример #11
0
        public Error CreateError(string errorName, string errorMessage)
        {
            Error error = new Error(errorName, message.Header.Serial);

            error.message.Signature = Signature.StringSig;

            MessageWriter writer = new MessageWriter(message.Header.Endianness);

            //writer.connection = conn;
            writer.Write(errorMessage);
            error.message.Body = writer.ToArray();

            //if (method_call.Sender != null)
            //	replyMsg.Header[FieldCode.Destination] = method_call.Sender;

            return(error);
        }
Пример #12
0
        public void SendSignal(string iface, string member, string inSigStr, MessageWriter writer, Type retType, out Exception exception)
        {
            exception = null;

            //TODO: don't ignore retVal, exception etc.

            Signature outSig = String.IsNullOrEmpty(inSigStr) ? Signature.Empty : new Signature(inSigStr);

            Signal signal = new Signal(object_path, iface, member);

            signal.message.Signature = outSig;

            Message signalMsg = signal.message;

            signalMsg.Body = writer.ToArray();

            conn.Send(signalMsg);
        }
Пример #13
0
        public static Message ConstructDynamicReply(MethodCall method_call, MethodInfo mi, object retVal, object[] vals)
        {
            Type retType = mi.ReturnType;

            MethodReturn method_return = new MethodReturn(method_call.message.Header.Serial);
            Message      replyMsg      = method_return.message;

            Signature outSig = Signature.GetSig(retType);

            outSig += Signature.GetSig(Mapper.GetTypes(ArgDirection.Out, mi.GetParameters()));

            if (outSig != Signature.Empty)
            {
                MessageWriter writer = new MessageWriter(Connection.NativeEndianness);

                //first write the return value, if any
                if (retType != null && retType != typeof(void))
                {
                    writer.Write(retType, retVal);
                }

                //then write the out args
                WriteDynamicValues(writer, mi.GetParameters(), vals);

                replyMsg.Body = writer.ToArray();
            }

            //TODO: we should be more strict here, but this fallback was added as a quick fix for p2p
            if (method_call.Sender != null)
            {
                replyMsg.Header.Fields[FieldCode.Destination] = method_call.Sender;
            }

            replyMsg.Signature = outSig;

            return(replyMsg);
        }
Пример #14
0
        //public HeaderField[] Fields;

        /*
         * public void SetHeaderData (byte[] data)
         * {
         *      EndianFlag endianness = (EndianFlag)data[0];
         *      MessageReader reader = new MessageReader (endianness, data);
         *
         *      Header = (Header)reader.ReadStruct (typeof (Header));
         * }
         */

        //TypeWriter<Header> headerWriter = TypeImplementer.GetTypeWriter<Header> ();
        public byte[] GetHeaderData()
        {
            if (Body != null)
            {
                Header.Length = (uint)Body.Length;
            }

            MessageWriter writer = new MessageWriter(Header.Endianness);

            //writer.stream.Capacity = 512;
            //headerWriter (writer, Header);

            writer.Write((byte)Header.Endianness);
            writer.Write((byte)Header.MessageType);
            writer.Write((byte)Header.Flags);
            writer.Write(Header.MajorVersion);
            writer.Write(Header.Length);
            writer.Write(Header.Serial);
            writer.WriteHeaderFields(Header.Fields);

            writer.CloseWrite();

            return(writer.ToArray());
        }
Пример #15
0
        public Error CreateError(string errorName, string errorMessage)
        {
            Error error = new Error (errorName, message.Header.Serial);
            error.message.Signature = Signature.StringSig;

            MessageWriter writer = new MessageWriter (message.Header.Endianness);
            //writer.connection = conn;
            writer.Write (errorMessage);
            error.message.Body = writer.ToArray ();

            //if (method_call.Sender != null)
            //	replyMsg.Header[FieldCode.Destination] = method_call.Sender;

            return error;
        }
Пример #16
0
        public object SendMethodCall(string iface, string member, string inSigStr, MessageWriter writer, Type retType, out Exception exception)
        {
            exception = null;

            //TODO: don't ignore retVal, exception etc.

            Signature inSig = String.IsNullOrEmpty(inSigStr) ? Signature.Empty : new Signature(inSigStr);

            MethodCall method_call = new MethodCall(object_path, iface, member, bus_name, inSig);

            Message callMsg = method_call.message;

            callMsg.Body = writer.ToArray();

            //Invoke Code::

            //TODO: complete out parameter support

            /*
             * Type[] outParmTypes = Mapper.GetTypes (ArgDirection.Out, mi.GetParameters ());
             * Signature outParmSig = Signature.GetSig (outParmTypes);
             *
             * if (outParmSig != Signature.Empty)
             *      throw new Exception ("Out parameters not yet supported: out_signature='" + outParmSig.Value + "'");
             */

            Type[] outTypes = new Type[1];
            outTypes[0] = retType;

            //we default to always requiring replies for now, even though unnecessary
            //this is to make sure errors are handled synchronously
            //TODO: don't hard code this
            bool needsReply = true;

            //if (mi.ReturnType == typeof (void))
            //	needsReply = false;

            callMsg.ReplyExpected = needsReply;
            callMsg.Signature     = inSig;

            if (!needsReply)
            {
                conn.Send(callMsg);
                return(null);
            }

#if PROTO_REPLY_SIGNATURE
            if (needsReply)
            {
                Signature outSig = Signature.GetSig(outTypes);
                callMsg.Header.Fields[FieldCode.ReplySignature] = outSig;
            }
#endif

            Message retMsg = conn.SendWithReplyAndBlock(callMsg);

            object retVal = null;

            //handle the reply message
            switch (retMsg.Header.MessageType)
            {
            case MessageType.MethodReturn:
                object[] retVals = MessageHelper.GetDynamicValues(retMsg, outTypes);
                if (retVals.Length != 0)
                {
                    retVal = retVals[retVals.Length - 1];
                }
                break;

            case MessageType.Error:
                //TODO: typed exceptions
                Error  error  = new Error(retMsg);
                string errMsg = String.Empty;
                if (retMsg.Signature.Value.StartsWith("s"))
                {
                    MessageReader reader = new MessageReader(retMsg);
                    errMsg = reader.ReadString();
                }
                exception = new Exception(error.ErrorName + ": " + errMsg);
                break;

            default:
                throw new Exception("Got unexpected message of type " + retMsg.Header.MessageType + " while waiting for a MethodReturn or Error");
            }

            return(retVal);
        }
Пример #17
0
		//TODO: merge this with the above method
		public static Message ConstructReplyFor (MethodCall method_call, Type retType, object retVal)
		{
			MethodReturn method_return = new MethodReturn (method_call.message.Header.Serial);
			Message replyMsg = method_return.message;

			Signature inSig = Signature.GetSig (retType);

			if (inSig != Signature.Empty) {
				MessageWriter writer = new MessageWriter (Connection.NativeEndianness);
				writer.Write (retType, retVal);
				replyMsg.Body = writer.ToArray ();
			}

			//TODO: we should be more strict here, but this fallback was added as a quick fix for p2p
			if (method_call.Sender != null)
				replyMsg.Header.Fields[FieldCode.Destination] = method_call.Sender;

			replyMsg.Signature = inSig;

			//replyMsg.WriteHeader ();

			return replyMsg;
		}
        public virtual void HandleMethodCall(MethodCall method_call)
        {
            Type type = obj.GetType ();

            //object retObj = type.InvokeMember (msg.Member, BindingFlags.InvokeMethod, null, obj, MessageHelper.GetDynamicValues (msg));

            //TODO: there is no member name mapping for properties etc. yet

            // FIXME: Inefficient to do this on every call
            MethodInfo mi = Mapper.GetMethod (type, method_call);

            if (mi == null) {
                conn.MaybeSendUnknownMethodError (method_call);
                return;
            }

            MethodCaller2 mCaller;
            if (!mCallers.TryGetValue (mi, out mCaller)) {
                //mCaller = TypeImplementer.GenCaller (mi, obj);
                mCaller = TypeImplementer.GenCaller2 (mi);
                mCallers[mi] = mCaller;
            }

            Signature inSig, outSig;
            TypeImplementer.SigsForMethod (mi, out inSig, out outSig);

            Message msg = method_call.message;
            MessageReader msgReader = new MessageReader (method_call.message);
            MessageWriter retWriter = new MessageWriter ();

            /*
            MessageWriter retWriter = null;
            if (msg.ReplyExpected)
                retWriter = new MessageWriter ();
            */

            Exception raisedException = null;
            try {
                //mCaller (msgReader, method_call.message, retWriter);
                mCaller (obj, msgReader, method_call.message, retWriter);
            } catch (Exception e) {
                raisedException = e;
            }

            if (!msg.ReplyExpected)
                return;

            Message replyMsg;

            if (raisedException == null) {
                MethodReturn method_return = new MethodReturn (msg.Header.Serial);
                replyMsg = method_return.message;
                replyMsg.Body = retWriter.ToArray ();
                replyMsg.Signature = outSig;
            } else {
                Error error;
                // BusException allows precisely formatted Error messages.
                BusException busException = raisedException as BusException;
                if (busException != null)
                    error = method_call.CreateError (busException.ErrorName, busException.ErrorMessage);
                else if (raisedException is ArgumentException && raisedException.TargetSite.Name == mi.Name) {
                    // Name match trick above is a hack since we don't have the resolved MethodInfo.
                    ArgumentException argException = (ArgumentException)raisedException;
                    using (System.IO.StringReader sr = new System.IO.StringReader (argException.Message)) {
                        error = method_call.CreateError ("org.freedesktop.DBus.Error.InvalidArgs", sr.ReadLine ());
                    }
                } else
                    error = method_call.CreateError (Mapper.GetInterfaceName (raisedException.GetType ()), raisedException.Message);

                replyMsg = error.message;
            }

            if (method_call.Sender != null)
                replyMsg.Header[FieldCode.Destination] = method_call.Sender;

            conn.Send (replyMsg);
        }
Пример #19
0
		public void SendSignal (MethodInfo mi, string @interface, string member, object[] outValues)
		{
			//TODO: make use of bus_name?

			Type[] outTypes = Mapper.GetTypes (ArgDirection.In, mi.GetParameters ());
			Signature outSig = Signature.GetSig (outTypes);

			Signal signal = new Signal (object_path, @interface, member);
			signal.message.Signature = outSig;

			if (outValues != null && outValues.Length != 0) {
				MessageWriter writer = new MessageWriter (Connection.NativeEndianness);
				writer.connection = conn;

				for (int i = 0 ; i != outTypes.Length ; i++)
					writer.Write (outTypes[i], outValues[i]);

				signal.message.Body = writer.ToArray ();
			}

			conn.Send (signal.message);
		}
Пример #20
0
        void RaiseNameSignal(string memberSuffix, string name)
        {
            // Name* signals on org.freedesktop.DBus are connection-specific.
            // We handle them here as a special case.

            Signal nameSignal = new Signal (Path, DBusInterface, "Name" + memberSuffix);
            MessageWriter mw = new MessageWriter ();
            mw.Write (name);
            nameSignal.message.Body = mw.ToArray ();
            nameSignal.message.Signature = Signature.StringSig;
            Caller.Send (nameSignal.message);
        }
Пример #21
0
		public static Message ConstructDynamicReply (MethodCall method_call, MethodInfo mi, object retVal, object[] vals)
		{
			Type retType = mi.ReturnType;

			MethodReturn method_return = new MethodReturn (method_call.message.Header.Serial);
			Message replyMsg = method_return.message;

			Signature outSig = Signature.GetSig (retType);
			outSig += Signature.GetSig (Mapper.GetTypes (ArgDirection.Out, mi.GetParameters ()));

			if (outSig != Signature.Empty) {
				MessageWriter writer = new MessageWriter (Connection.NativeEndianness);

				//first write the return value, if any
				if (retType != null && retType != typeof (void))
					writer.Write (retType, retVal);

				//then write the out args
				WriteDynamicValues (writer, mi.GetParameters (), vals);

				replyMsg.Body = writer.ToArray ();
			}

			//TODO: we should be more strict here, but this fallback was added as a quick fix for p2p
			if (method_call.Sender != null)
				replyMsg.Header.Fields[FieldCode.Destination] = method_call.Sender;

			replyMsg.Signature = outSig;

			return replyMsg;
		}
Пример #22
0
		public static Message ConstructReply (MethodCall method_call, params object[] vals)
		{
			MethodReturn method_return = new MethodReturn (method_call.message.Header.Serial);
			Message replyMsg = method_return.message;

			Signature inSig = Signature.GetSig (vals);

			if (vals != null && vals.Length != 0) {
				MessageWriter writer = new MessageWriter (Connection.NativeEndianness);

				foreach (object arg in vals)
					writer.Write (arg.GetType (), arg);

				replyMsg.Body = writer.ToArray ();
			}

			//TODO: we should be more strict here, but this fallback was added as a quick fix for p2p
			if (method_call.Sender != null)
				replyMsg.Header.Fields[FieldCode.Destination] = method_call.Sender;

			replyMsg.Signature = inSig;

			//replyMsg.WriteHeader ();

			return replyMsg;
		}
Пример #23
0
		public static Message CreateUnknownMethodError (MethodCall method_call)
		{
			if (!method_call.message.ReplyExpected)
				return null;

			string errMsg = String.Format ("Method \"{0}\" with signature \"{1}\" on interface \"{2}\" doesn't exist", method_call.Member, method_call.Signature.Value, method_call.Interface);

			Error error = new Error ("org.freedesktop.DBus.Error.UnknownMethod", method_call.message.Header.Serial);
			error.message.Signature = new Signature (DType.String);

			MessageWriter writer = new MessageWriter (Connection.NativeEndianness);
			writer.Write (errMsg);
			error.message.Body = writer.ToArray ();

			//TODO: we should be more strict here, but this fallback was added as a quick fix for p2p
			if (method_call.Sender != null)
				error.message.Header.Fields[FieldCode.Destination] = method_call.Sender;

			return error.message;
		}
Пример #24
0
		public object SendMethodCall (string iface, string member, string inSigStr, MessageWriter writer, Type retType, out Exception exception)
		{
			exception = null;

			//TODO: don't ignore retVal, exception etc.

			Signature inSig = String.IsNullOrEmpty (inSigStr) ? Signature.Empty : new Signature (inSigStr);

			MethodCall method_call = new MethodCall (object_path, iface, member, bus_name, inSig);

			Message callMsg = method_call.message;
			callMsg.Body = writer.ToArray ();

			//Invoke Code::

			//TODO: complete out parameter support
			/*
			Type[] outParmTypes = Mapper.GetTypes (ArgDirection.Out, mi.GetParameters ());
			Signature outParmSig = Signature.GetSig (outParmTypes);

			if (outParmSig != Signature.Empty)
				throw new Exception ("Out parameters not yet supported: out_signature='" + outParmSig.Value + "'");
			*/

			Type[] outTypes = new Type[1];
			outTypes[0] = retType;

			//we default to always requiring replies for now, even though unnecessary
			//this is to make sure errors are handled synchronously
			//TODO: don't hard code this
			bool needsReply = true;

			//if (mi.ReturnType == typeof (void))
			//	needsReply = false;

			callMsg.ReplyExpected = needsReply;
			callMsg.Signature = inSig;

			if (!needsReply) {
				conn.Send (callMsg);
				return null;
			}

#if PROTO_REPLY_SIGNATURE
			if (needsReply) {
				Signature outSig = Signature.GetSig (outTypes);
				callMsg.Header.Fields[FieldCode.ReplySignature] = outSig;
			}
#endif

			Message retMsg = conn.SendWithReplyAndBlock (callMsg);

			object retVal = null;

			//handle the reply message
			switch (retMsg.Header.MessageType) {
				case MessageType.MethodReturn:
				object[] retVals = MessageHelper.GetDynamicValues (retMsg, outTypes);
				if (retVals.Length != 0)
					retVal = retVals[retVals.Length - 1];
				break;
				case MessageType.Error:
				//TODO: typed exceptions
				Error error = new Error (retMsg);
				string errMsg = String.Empty;
				if (retMsg.Signature.Value.StartsWith ("s")) {
					MessageReader reader = new MessageReader (retMsg);
					errMsg = reader.ReadString ();
				}
				exception = new Exception (error.ErrorName + ": " + errMsg);
				break;
				default:
				throw new Exception ("Got unexpected message of type " + retMsg.Header.MessageType + " while waiting for a MethodReturn or Error");
			}

			return retVal;
		}
Пример #25
0
		public byte[] GetHeaderData ()
		{
			if (Body != null)
				Header.Length = (uint)Body.Length;

			MessageWriter writer = new MessageWriter (Header.Endianness);
			writer.WriteValueType (Header, typeof (Header));
			writer.CloseWrite ();

			return writer.ToArray ();
		}
Пример #26
0
        public void Invoke(MethodBase methodBase, string methodName, object[] inArgs, out object[] outArgs, out object retVal, out Exception exception)
        {
            outArgs   = new object[0];
            retVal    = null;
            exception = null;

            MethodInfo mi = methodBase as MethodInfo;

            if (mi != null && mi.IsSpecialName && (methodName.StartsWith("add_") || methodName.StartsWith("remove_")))
            {
                string[] parts = methodName.Split(new char[] { '_' }, 2);
                string   ename = parts[1];
                Delegate dlg   = (Delegate)inArgs[0];

                MatchRule rule = new MatchRule();
                rule.MessageType = MessageType.Signal;
                rule.Interface   = Mapper.GetInterfaceName(mi);
                rule.Member      = ename;
                rule.Path        = object_path;

                if (parts[0] == "add")
                {
                    if (conn.Handlers.ContainsKey(rule))
                    {
                        conn.Handlers[rule] = Delegate.Combine(conn.Handlers[rule], dlg);
                    }
                    else
                    {
                        conn.Handlers[rule] = dlg;
                        conn.AddMatch(rule.ToString());
                    }
                }
                else if (parts[0] == "remove")
                {
                    conn.Handlers[rule] = Delegate.Remove(conn.Handlers[rule], dlg);
                    if (conn.Handlers[rule] == null)
                    {
                        conn.RemoveMatch(rule.ToString());
                        conn.Handlers.Remove(rule);
                    }
                }
                return;
            }

            Type[]    inTypes = Mapper.GetTypes(ArgDirection.In, mi.GetParameters());
            Signature inSig   = Signature.GetSig(inTypes);

            MethodCall method_call;
            Message    callMsg;

            //build the outbound method call message
            {
                //this bit is error-prone (no null checking) and will need rewriting when DProxy is replaced
                string iface = null;
                if (mi != null)
                {
                    iface = Mapper.GetInterfaceName(mi);
                }

                //map property accessors
                //TODO: this needs to be done properly, not with simple String.Replace
                //note that IsSpecialName is also for event accessors, but we already handled those and returned
                if (mi != null && mi.IsSpecialName)
                {
                    methodName = methodName.Replace("get_", "Get");
                    methodName = methodName.Replace("set_", "Set");
                }

                method_call = new MethodCall(object_path, iface, methodName, bus_name, inSig);

                callMsg = method_call.message;

                if (inArgs != null && inArgs.Length != 0)
                {
                    MessageWriter writer = new MessageWriter(Connection.NativeEndianness);
                    writer.connection = conn;

                    for (int i = 0; i != inTypes.Length; i++)
                    {
                        writer.Write(inTypes[i], inArgs[i]);
                    }

                    callMsg.Body = writer.ToArray();
                }
            }

            //TODO: complete out parameter support
            Type[]    outParmTypes = Mapper.GetTypes(ArgDirection.Out, mi.GetParameters());
            Signature outParmSig   = Signature.GetSig(outParmTypes);

            if (outParmSig != Signature.Empty)
            {
                throw new Exception("Out parameters not yet supported: out_signature='" + outParmSig.Value + "'");
            }

            Type[] outTypes = new Type[1];
            outTypes[0] = mi.ReturnType;

            //we default to always requiring replies for now, even though unnecessary
            //this is to make sure errors are handled synchronously
            //TODO: don't hard code this
            bool needsReply = true;

            //if (mi.ReturnType == typeof (void))
            //	needsReply = false;

            callMsg.ReplyExpected = needsReply;
            callMsg.Signature     = inSig;

            if (!needsReply)
            {
                conn.Send(callMsg);
                return;
            }

#if PROTO_REPLY_SIGNATURE
            if (needsReply)
            {
                Signature outSig = Signature.GetSig(outTypes);
                callMsg.Header.Fields[FieldCode.ReplySignature] = outSig;
            }
#endif

            Message retMsg = conn.SendWithReplyAndBlock(callMsg);

            //handle the reply message
            switch (retMsg.Header.MessageType)
            {
            case MessageType.MethodReturn:
                object[] retVals = MessageHelper.GetDynamicValues(retMsg, outTypes);
                if (retVals.Length != 0)
                {
                    retVal = retVals[retVals.Length - 1];
                }
                break;

            case MessageType.Error:
                //TODO: typed exceptions
                Error  error  = new Error(retMsg);
                string errMsg = String.Empty;
                if (retMsg.Signature.Value.StartsWith("s"))
                {
                    MessageReader reader = new MessageReader(retMsg);
                    reader.GetValue(out errMsg);
                }
                exception = new Exception(error.ErrorName + ": " + errMsg);
                break;

            default:
                throw new Exception("Got unexpected message of type " + retMsg.Header.MessageType + " while waiting for a MethodReturn or Error");
            }

            return;
        }
Пример #27
0
		public void WriteHeader ()
		{
			if (Body != null)
				Header.Length = (uint)Body.Length;

			MessageWriter writer = new MessageWriter (Connection.NativeEndianness);
			writer.WriteStruct (typeof (Header), Header);
			//writer.WriteFromDict (typeof (FieldCode), typeof (object), Header.Fields);
			writer.CloseWrite ();
			HeaderData = writer.ToArray ();
		}
Пример #28
0
		public void Invoke (MethodBase methodBase, string methodName, object[] inArgs, out object[] outArgs, out object retVal, out Exception exception)
		{
			outArgs = new object[0];
			retVal = null;
			exception = null;

			MethodInfo mi = methodBase as MethodInfo;

			if (mi != null && mi.IsSpecialName && (methodName.StartsWith ("add_") || methodName.StartsWith ("remove_"))) {
				string[] parts = methodName.Split (new char[]{'_'}, 2);
				string ename = parts[1];
				Delegate dlg = (Delegate)inArgs[0];

				ToggleSignal (Mapper.GetInterfaceName (mi), ename, dlg, parts[0] == "add");

				return;
			}

			Type[] inTypes = Mapper.GetTypes (ArgDirection.In, mi.GetParameters ());
			Signature inSig = Signature.GetSig (inTypes);

			MethodCall method_call;
			Message callMsg;

			//build the outbound method call message
			{
				//this bit is error-prone (no null checking) and will need rewriting when DProxy is replaced
				string iface = null;
				if (mi != null)
					iface = Mapper.GetInterfaceName (mi);

				//map property accessors
				//TODO: this needs to be done properly, not with simple String.Replace
				//note that IsSpecialName is also for event accessors, but we already handled those and returned
				if (mi != null && mi.IsSpecialName) {
					methodName = methodName.Replace ("get_", "Get");
					methodName = methodName.Replace ("set_", "Set");
				}

				method_call = new MethodCall (object_path, iface, methodName, bus_name, inSig);

				callMsg = method_call.message;

				if (inArgs != null && inArgs.Length != 0) {
					MessageWriter writer = new MessageWriter (Connection.NativeEndianness);
					writer.connection = conn;

					for (int i = 0 ; i != inTypes.Length ; i++)
						writer.Write (inTypes[i], inArgs[i]);

					callMsg.Body = writer.ToArray ();
				}
			}

			//TODO: complete out parameter support
			/*
			Type[] outParmTypes = Mapper.GetTypes (ArgDirection.Out, mi.GetParameters ());
			Signature outParmSig = Signature.GetSig (outParmTypes);

			if (outParmSig != Signature.Empty)
				throw new Exception ("Out parameters not yet supported: out_signature='" + outParmSig.Value + "'");
			*/

			Type[] outTypes = new Type[1];
			outTypes[0] = mi.ReturnType;

			//we default to always requiring replies for now, even though unnecessary
			//this is to make sure errors are handled synchronously
			//TODO: don't hard code this
			bool needsReply = true;

			//if (mi.ReturnType == typeof (void))
			//	needsReply = false;

			callMsg.ReplyExpected = needsReply;
			callMsg.Signature = inSig;

			if (!needsReply) {
				conn.Send (callMsg);
				return;
			}

#if PROTO_REPLY_SIGNATURE
			if (needsReply) {
				Signature outSig = Signature.GetSig (outTypes);
				callMsg.Header.Fields[FieldCode.ReplySignature] = outSig;
			}
#endif

			Message retMsg = conn.SendWithReplyAndBlock (callMsg);

			//handle the reply message
			switch (retMsg.Header.MessageType) {
				case MessageType.MethodReturn:
				object[] retVals = MessageHelper.GetDynamicValues (retMsg, outTypes);
				if (retVals.Length != 0)
					retVal = retVals[retVals.Length - 1];
				break;
				case MessageType.Error:
				//TODO: typed exceptions
				Error error = new Error (retMsg);
				string errMsg = String.Empty;
				if (retMsg.Signature.Value.StartsWith ("s")) {
					MessageReader reader = new MessageReader (retMsg);
					errMsg = reader.ReadString ();
				}
				exception = new Exception (error.ErrorName + ": " + errMsg);
				break;
				default:
				throw new Exception ("Got unexpected message of type " + retMsg.Header.MessageType + " while waiting for a MethodReturn or Error");
			}

			return;
		}
Пример #29
0
        //public HeaderField[] Fields;
        /*
        public void SetHeaderData (byte[] data)
        {
            EndianFlag endianness = (EndianFlag)data[0];
            MessageReader reader = new MessageReader (endianness, data);

            Header = (Header)reader.ReadStruct (typeof (Header));
        }
        */
        //TypeWriter<Header> headerWriter = TypeImplementer.GetTypeWriter<Header> ();
        public byte[] GetHeaderData()
        {
            if (Body != null)
                Header.Length = (uint)Body.Length;

            MessageWriter writer = new MessageWriter (Header.Endianness);

            //writer.stream.Capacity = 512;
            //headerWriter (writer, Header);

            writer.Write ((byte)Header.Endianness);
            writer.Write ((byte)Header.MessageType);
            writer.Write ((byte)Header.Flags);
            writer.Write (Header.MajorVersion);
            writer.Write (Header.Length);
            writer.Write (Header.Serial);
            writer.WriteHeaderFields (Header.Fields);

            writer.CloseWrite ();

            return writer.ToArray ();
        }
Пример #30
0
		public void SendSignal (string iface, string member, string inSigStr, MessageWriter writer, Type retType, out Exception exception)
		{
			exception = null;

			//TODO: don't ignore retVal, exception etc.

			Signature outSig = String.IsNullOrEmpty (inSigStr) ? Signature.Empty : new Signature (inSigStr);

			Signal signal = new Signal (object_path, iface, member);
			signal.message.Signature = outSig;

			Message signalMsg = signal.message;
			signalMsg.Body = writer.ToArray ();

			conn.Send (signalMsg);
		}
Пример #31
0
        public virtual void HandleMethodCall(MethodCall method_call)
        {
            Type type = obj.GetType();

            //object retObj = type.InvokeMember (msg.Member, BindingFlags.InvokeMethod, null, obj, MessageHelper.GetDynamicValues (msg));

            //TODO: there is no member name mapping for properties etc. yet

            // FIXME: Inefficient to do this on every call
            MethodInfo mi = Mapper.GetMethod(type, method_call);

            if (mi == null)
            {
                conn.MaybeSendUnknownMethodError(method_call);
                return;
            }

            MethodCaller2 mCaller;

            if (!mCallers.TryGetValue(mi, out mCaller))
            {
                //mCaller = TypeImplementer.GenCaller (mi, obj);
                mCaller      = TypeImplementer.GenCaller2(mi);
                mCallers[mi] = mCaller;
            }

            Signature inSig, outSig;

            TypeImplementer.SigsForMethod(mi, out inSig, out outSig);

            Message       msg       = method_call.message;
            MessageReader msgReader = new MessageReader(method_call.message);
            MessageWriter retWriter = new MessageWriter();

            /*
             * MessageWriter retWriter = null;
             * if (msg.ReplyExpected)
             *      retWriter = new MessageWriter ();
             */

            Exception raisedException = null;

            try {
                //mCaller (msgReader, method_call.message, retWriter);
                mCaller(obj, msgReader, method_call.message, retWriter);
            } catch (Exception e) {
                raisedException = e;
            }

            if (!msg.ReplyExpected)
            {
                return;
            }

            Message replyMsg;

            if (raisedException == null)
            {
                MethodReturn method_return = new MethodReturn(msg.Header.Serial);
                replyMsg           = method_return.message;
                replyMsg.Body      = retWriter.ToArray();
                replyMsg.Signature = outSig;
            }
            else
            {
                Error error;
                // BusException allows precisely formatted Error messages.
                BusException busException = raisedException as BusException;
                if (busException != null)
                {
                    error = method_call.CreateError(busException.ErrorName, busException.ErrorMessage);
                }
                else if (raisedException is ArgumentException && raisedException.TargetSite.Name == mi.Name)
                {
                    // Name match trick above is a hack since we don't have the resolved MethodInfo.
                    ArgumentException argException = (ArgumentException)raisedException;
                    using (System.IO.StringReader sr = new System.IO.StringReader(argException.Message)) {
                        error = method_call.CreateError("org.freedesktop.DBus.Error.InvalidArgs", sr.ReadLine());
                    }
                }
                else
                {
                    error = method_call.CreateError(Mapper.GetInterfaceName(raisedException.GetType()), raisedException.Message);
                }

                replyMsg = error.message;
            }

            if (method_call.Sender != null)
            {
                replyMsg.Header[FieldCode.Destination] = method_call.Sender;
            }

            conn.Send(replyMsg);
        }