Exemple #1
0
        public MethodCaller GetPropertyAllCall(string iface)
        {
            PropertyDictionary calls;

            if (!Properties.TryGetValue(iface, out calls))
            {
                Properties [iface] = calls = new PropertyDictionary();
            }

            if (null == calls.All)
            {
                Type it = Mapper.GetInterfaceType(ObjectType, iface);
                calls.All = TypeImplementer.GenGetAllCall(it);
            }

            return(calls.All);
        }
Exemple #2
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);
        }
Exemple #3
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);
        }
Exemple #4
0
        public void WriteStructure <T> (T value)
        {
            TypeWriter <T> tWriter = TypeImplementer.GetTypeWriter <T> ();

            tWriter(this, value);
        }
Exemple #5
0
        public void WriteValueType(object val, Type type)
        {
            MethodInfo mi = TypeImplementer.GetWriteMethod(type);

            mi.Invoke(null, new object[] { this, val });
        }
Exemple #6
0
        //this requires a seekable stream for now
        public unsafe void WriteArray <T> (T[] val)
        {
            Type elemType = typeof(T);

            if (elemType == typeof(byte))
            {
                if (val.Length > Protocol.MaxArrayLength)
                {
                    throw new Exception("Array length " + val.Length + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes");
                }

                Write((uint)val.Length);
                stream.Write((byte[])(object)val, 0, val.Length);
                return;
            }

            if (elemType.IsEnum)
            {
                elemType = Enum.GetUnderlyingType(elemType);
            }

            Signature sigElem   = Signature.GetSig(elemType);
            int       fixedSize = 0;

            if (endianness == Connection.NativeEndianness && elemType.IsValueType && !sigElem.IsStruct && sigElem.GetFixedSize(ref fixedSize))
            {
                int byteLength = fixedSize * val.Length;
                if (byteLength > Protocol.MaxArrayLength)
                {
                    throw new Exception("Array length " + byteLength + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes");
                }
                Write((uint)byteLength);
                WritePad(sigElem.Alignment);

                GCHandle valHandle = GCHandle.Alloc(val, GCHandleType.Pinned);
                IntPtr   p         = valHandle.AddrOfPinnedObject();
                byte[]   data      = new byte[byteLength];
                byte *   bp        = (byte *)p;
                for (int i = 0; i != byteLength; i++)
                {
                    data[i] = bp[i];
                }
                stream.Write(data, 0, data.Length);
                valHandle.Free();
                return;
            }

            long origPos = stream.Position;

            Write((uint)0);

            //advance to the alignment of the element
            WritePad(sigElem.Alignment);

            long startPos = stream.Position;

            TypeWriter <T> tWriter = TypeImplementer.GetTypeWriter <T> ();

            foreach (T elem in val)
            {
                tWriter(this, elem);
            }

            long endPos = stream.Position;
            uint ln     = (uint)(endPos - startPos);

            stream.Position = origPos;

            if (ln > Protocol.MaxArrayLength)
            {
                throw new Exception("Array length " + ln + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes");
            }

            Write(ln);
            stream.Position = endPos;
        }
Exemple #7
0
        //this might need reworking with MulticastDelegate
        internal void HandleSignal(Message msg)
        {
            var signal = MessageContainer.FromMessage(msg);

            //TODO: this is a hack, not necessary when MatchRule is complete
            MatchRule[] rules = new MatchRule[2];
            rules[0]             = new MatchRule();
            rules[0].MessageType = MessageType.Signal;
            rules[0].Fields.Add(FieldCode.Interface, new MatchTest(signal.Interface));
            rules[0].Fields.Add(FieldCode.Member, new MatchTest(signal.Member));
            //rules[0].Fields.Add (FieldCode.Sender, new MatchTest (signal.Sender));
            rules[0].Fields.Add(FieldCode.Path, new MatchTest(signal.Path));
            rules[1]             = new MatchRule();
            rules[1].MessageType = MessageType.Signal;
            rules[1].Fields.Add(FieldCode.Interface, new MatchTest(signal.Interface));
            rules[1].Fields.Add(FieldCode.Member, new MatchTest(signal.Member));
            rules[1].Fields.Add(FieldCode.Sender, new MatchTest(signal.Sender));
            rules[1].Fields.Add(FieldCode.Path, new MatchTest(signal.Path));

            bool handlerFound = false;

            foreach (var rule in rules)
            {
                Delegate dlg;
                if (Handlers.TryGetValue(rule, out dlg) && dlg != null)
                {
                    MethodInfo mi = dlg.GetType().GetMethod("Invoke");

                    bool      compatible = false;
                    Signature inSig, outSig;
                    bool      hasDisposableList;

                    if (TypeImplementer.SigsForMethod(mi, out inSig, out outSig, out hasDisposableList))
                    {
                        if (outSig == Signature.Empty && inSig == msg.Signature && !hasDisposableList)
                        {
                            compatible = true;
                        }
                    }

                    if (!compatible)
                    {
                        if (ProtocolInformation.Verbose)
                        {
                            Console.Error.WriteLine("Signal argument mismatch: " + signal.Interface + '.' + signal.Member);
                        }
                        return;
                    }

                    //signals have no return value
                    dlg.DynamicInvoke(MessageHelper.GetDynamicValues(msg, mi.GetParameters()));
                    handlerFound = true;
                }
            }
            if (!handlerFound)
            {
                //TODO: how should we handle this condition? sending an Error may not be appropriate in this case
                if (ProtocolInformation.Verbose)
                {
                    Console.Error.WriteLine("Warning: No signal handler for " + signal.Member);
                }
            }
        }