public void ReadBooleanArrayBigEndian ()
		{
			byte[] data = new byte[] { 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1 };
			MessageReader reader = new MessageReader (EndianFlag.Big, data);
			
			bool[] array = (bool[])reader.ReadArray (typeof (bool));
			Assert.IsNotNull (array);
			Assert.AreEqual (4, array.Length, "length");
			CollectionAssert.AreEqual (new bool[] { true, false, true, true}, array, "elements");
			Assert.IsFalse (reader.DataAvailable);
		}
		public void ReadIntArrayBigEndian ()
		{
			byte[] data = new byte[] { 0, 0, 0, 16, 0, 0, 8, 8, 0, 0, 8, 8, 0, 0, 8, 8, 0, 0, 8, 8 };
			MessageReader reader = new MessageReader (EndianFlag.Big, data);
			
			int[] array = (int[])reader.ReadArray (typeof (int));
			Assert.IsNotNull (array);
			Assert.AreEqual (4, array.Length, "length");
			CollectionAssert.AreEqual (new int[] { 0x808, 0x808, 0x808, 0x808}, array, "elements");
			Assert.IsFalse (reader.DataAvailable);
		}
示例#3
0
        public virtual void HandleMethodCall(MessageContainer method_call)
        {
            MethodInfo mi;
            if (!methodInfoCache.TryGetValue(method_call.Member, out mi))
                methodInfoCache[method_call.Member] = mi = Mapper.GetMethod(Object.GetType(), method_call);

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

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

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

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

            Exception raisedException = null;
            try
            {
                mCaller(Object, msgReader, msg, retWriter);
            }
            catch (Exception e)
            {
                raisedException = e;
            }

            if (!msg.ReplyExpected)
                return;

            Message replyMsg;

            if (raisedException == null)
            {
                MessageContainer method_return = new MessageContainer
                {
                    Type = MessageType.MethodReturn,
                    ReplySerial = msg.Header.Serial
                };
                replyMsg = method_return.Message;
                replyMsg.AttachBodyTo(retWriter);
                replyMsg.Signature = outSig;
            }
            else
            {
                // BusException allows precisely formatted Error messages.
                BusException busException = raisedException as BusException;
                if (busException != null)
                    replyMsg = 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))
                    {
                        replyMsg = method_call.CreateError("org.freedesktop.DBus.Error.InvalidArgs", sr.ReadLine());
                    }
                }
                else
                    replyMsg = method_call.CreateError(Mapper.GetInterfaceName(raisedException.GetType()), raisedException.Message);
            }

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

            conn.Send(replyMsg);
        }
示例#4
0
        public void SetHeaderData(byte[] data)
        {
            EndianFlag endianness = (EndianFlag)data[0];
            MessageReader reader = new MessageReader (endianness, data);

            MethodCaller2 mCaller = ExportObject.GetMCaller (hHandler);
            mCaller (this, reader, null, new MessageWriter ());
        }
示例#5
0
        public object ToType(Type conversionType, IFormatProvider provider)
        {
            Signature typeSig = Signature.GetSig (conversionType);
            if (typeSig != signature)
                throw new InvalidCastException ();

            MessageReader reader = new MessageReader (endianness, data);
            return reader.ReadValue (conversionType);
        }
		public void ReadIntLongIntStructLittleEndian ()
		{
			// (ixi) and (1, 2, 3)
			byte[] data = new byte[] { 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0 };
			MessageReader reader = new MessageReader (EndianFlag.Little, data);

			TestStruct stct = (TestStruct)reader.ReadStruct (typeof (TestStruct));
			Assert.AreEqual (1, stct.Item1);
			Assert.AreEqual (2, stct.Item2);
			Assert.AreEqual (3, stct.Item3);
		}
示例#7
0
        public static object[] GetDynamicValues(Message msg, ParameterInfo[] parms)
        {
            //TODO: this validation check should provide better information, eg. message dump or a stack trace, or at least the interface/member
            /*
            if (Protocol.Verbose) {
                Signature expected = Signature.GetSig (types);
                Signature actual = msg.Signature;
                if (actual != expected)
                    Console.Error.WriteLine ("Warning: The signature of the message does not match that of the handler: " + "Expected '" + expected + "', got '" + actual + "'");
            }
            */

            object[] vals = new object[parms.Length];

            if (msg.Body != null) {
                MessageReader reader = new MessageReader (msg);
                foreach (ParameterInfo parm in parms) {
                    if (parm.IsOut)
                        continue;

                    vals[parm.Position] = reader.ReadValue (parm.ParameterType);
                }
            }

            return vals;
        }
		public void ReadSameAlignementStructNativeEndian ()
		{
			// Will test the fast path with mixed types but same alignement
			byte[] data = new byte[8 * 3];
			Array.Copy (BitConverter.GetBytes ((long)1), 0, data, 0, 8);
			Array.Copy (BitConverter.GetBytes (ulong.MaxValue), 0, data, 8, 8);
			Array.Copy (BitConverter.GetBytes ((double)3.3), 0, data, 16, 8);

			MessageReader reader = new MessageReader (BitConverter.IsLittleEndian ? EndianFlag.Little : EndianFlag.Big, data);

			TestStruct3 stct = (TestStruct3)reader.ReadStruct (typeof (TestStruct3));
			Assert.AreEqual (1, stct.Item1);
			Assert.AreEqual (ulong.MaxValue, stct.Item2);
			Assert.AreEqual (3.3, stct.Item3);
		}
		public void ReadSameAlignementStructNonNativeEndian ()
		{
			// Will test the fast path with mixed types but same alignement
			byte[] data = new byte[8 * 3];
			Array.Copy (BitConverter.GetBytes ((long)1), 0, data, 0, 8);
			Array.Copy (BitConverter.GetBytes (ulong.MaxValue), 0, data, 8, 8);
			Array.Copy (BitConverter.GetBytes ((double)3.3), 0, data, 16, 8);
			// Swap value to simulate other endianess
			for (int i = 0; i < data.Length; i += 8) {
				for (int j = 0; j < 4; j++) {
					data[i + j] = (byte)(data[i + j] ^ data[i + 7 - j]);
					data[i + 7 - j] = (byte)(data[i + j] ^ data[i + 7 - j]);
					data[i + j] = (byte)(data[i + j] ^ data[i + 7 - j]);
				}
			}

			MessageReader reader = new MessageReader (!BitConverter.IsLittleEndian ? EndianFlag.Little : EndianFlag.Big, data);

			TestStruct3 stct = (TestStruct3)reader.ReadStruct (typeof (TestStruct3));
			Assert.AreEqual (1, stct.Item1);
			Assert.AreEqual (ulong.MaxValue, stct.Item2);
			Assert.AreEqual (3.3, stct.Item3);
		}
示例#10
0
		public void ReadIntLittleEndian ()
		{
			MessageReader reader = new MessageReader (EndianFlag.Little, new byte[] { 8, 8, 0, 0});
			Assert.AreEqual (0x808, reader.ReadInt32 ());
			Assert.IsFalse (reader.DataAvailable);
		}
示例#11
0
		public void ReadIntIntIntStructLittleEndianGeneric ()
		{
			// Will test the fast path
			byte[] data = new byte[] { 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0 };
			MessageReader reader = new MessageReader (EndianFlag.Little, data);

			TestStruct2 stct = reader.ReadStruct<TestStruct2> ();
			Assert.AreEqual (1, stct.Item1);
			Assert.AreEqual (2, stct.Item2);
			Assert.AreEqual (3, stct.Item3);
		}
示例#12
0
		public void ReadIntLongIntStructNonAlignedLittleEndian ()
		{
			// (ixi) and (1, 2, 3)
			byte[] data = new byte[] { 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0 };
			MessageReader reader = new MessageReader (EndianFlag.Little, data);

			TestStruct stct = (TestStruct)reader.ReadStruct (typeof (TestStruct));
		}
示例#13
0
        public MessageReader SendMethodCall(string iface, string member, string inSigStr, MessageWriter writer, Type retType, out Exception exception)
        {
            if (string.IsNullOrEmpty (bus_name))
                throw new ArgumentNullException ("bus_name");
            if (object_path == null)
                throw new ArgumentNullException ("object_path");

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

            MessageContainer method_call = new MessageContainer {
                Path = object_path,
                Interface = iface,
                Member = member,
                Destination = bus_name,
                Signature = inSig
            };

            Message callMsg = method_call.Message;
            callMsg.AttachBodyTo (writer);

            bool needsReply = true;

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

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

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

            Message retMsg = conn.SendWithReplyAndBlock (callMsg);

            MessageReader retVal = null;

            //handle the reply message
            switch (retMsg.Header.MessageType) {
            case MessageType.MethodReturn:
                retVal = new MessageReader (retMsg);
                break;
            case MessageType.Error:
                MessageContainer error = MessageContainer.FromMessage (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;
        }
示例#14
0
        public static object[] GetDynamicValues(Message msg, Type[] types)
        {
            //TODO: this validation check should provide better information, eg. message dump or a stack trace, or at least the interface/member
            if (Protocol.Verbose) {
                Signature expected = Signature.GetSig (types);
                Signature actual = msg.Signature;
                if (actual != expected)
                    Console.Error.WriteLine ("Warning: The signature of the message does not match that of the handler: " + "Expected '" + expected + "', got '" + actual + "'");
            }

            object[] vals = new object[types.Length];

            if (msg.Body != null) {
                MessageReader reader = new MessageReader (msg);

                for (int i = 0 ; i != types.Length ; i++)
                    vals[i] = reader.ReadValue (types[i]);
            }

            return vals;
        }
示例#15
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[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;
        }
示例#16
0
		public void ReadIntBigEndian ()
		{
			MessageReader reader = new MessageReader (EndianFlag.Big, new byte[] { 0, 0, 8, 8});
			Assert.AreEqual (0x808, reader.ReadInt32 ());
			Assert.IsFalse (reader.DataAvailable);
		}
示例#17
0
        public object SendMethodCallOld(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[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;
        }
示例#18
0
        public static void Test(HashSet<ArgMatchTest> a, Message msg)
        {
            List<Signature> sigs = new List<Signature> ();
            sigs.AddRange (msg.Signature.GetParts ());

            if (sigs.Count == 0) {
                a.Clear ();
                return;
            }

            a.RemoveWhere ( delegate (ArgMatchTest t) { return t.ArgNum >= sigs.Count || t.Signature != sigs[t.ArgNum]; } );

            // Sorting the list here is not ideal
            List<ArgMatchTest> tests = new List<ArgMatchTest> (a);
            tests.Sort ( delegate (ArgMatchTest aa, ArgMatchTest bb) { return aa.ArgNum - bb.ArgNum; } );

            if (tests.Count == 0) {
                a.Clear ();
                return;
            }

            MessageReader reader = new MessageReader (msg);

            int argNum = 0;
            foreach (ArgMatchTest test in tests) {
                if (argNum > test.ArgNum) {
                    // This test cannot pass because a previous test already did.
                    // So we already know it will fail without even trying.
                    // This logic will need to be changed to support wildcards.
                    a.Remove (test);
                    continue;
                }

                while (argNum != test.ArgNum) {
                    Signature sig = sigs[argNum];
                    if (!reader.StepOver (sig))
                        throw new Exception ();
                    argNum++;
                }

                // TODO: Avoid re-reading values
                int savedPos = reader.pos;
                if (!reader.ReadValue (test.Signature[0]).Equals (test.Value)) {
                    a.Remove (test);
                    reader.pos = savedPos;
                    continue;
                }

                argNum++;
            }
        }