// Copyright (c) Benjamin Kietzman (github.com/bkietz) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef DBUS_MESSAGE_HPP #define DBUS_MESSAGE_HPP #include #include #include #include #include #include #include inline void intrusive_ptr_add_ref(DBusMessage* m) { dbus_message_ref(m); } inline void intrusive_ptr_release(DBusMessage* m) { dbus_message_unref(m); } namespace dbus { class message { boost::intrusive_ptr message_; public: /// Create a method call message static message new_call(const endpoint& destination, const string& method_name) { return dbus_message_new_method_call( destination.get_process_name().c_str(), destination.get_path().c_str(), destination.get_interface().c_str(), method_name.c_str()); } /// Create a method return message static message new_return(message& call) { return dbus_message_new_method_return(call); } /// Create an error message static message new_error(message& call, const string& error_name, const string& error_message) { return dbus_message_new_error(call, error_name.c_str(), error_message.c_str()); } /// Create a signal message static message new_signal(const endpoint& origin, const string& signal_name) { return dbus_message_new_signal(origin.get_path().c_str(), origin.get_interface().c_str(), signal_name.c_str()); } message() {} message(DBusMessage* m) : message_(dbus_message_ref(m)) {} operator DBusMessage*() { return message_.get(); } operator const DBusMessage*() const { return message_.get(); } string get_path() const { return sanitize(dbus_message_get_path(message_.get())); } string get_interface() const { return sanitize(dbus_message_get_interface(message_.get())); } string get_member() const { return sanitize(dbus_message_get_member(message_.get())); } string get_type() const { return sanitize( dbus_message_type_to_string(dbus_message_get_type(message_.get()))); } string get_sender() const { return sanitize(dbus_message_get_sender(message_.get())); } string get_destination() const { return sanitize(dbus_message_get_destination(message_.get())); } uint32 get_serial() { return dbus_message_get_serial(message_.get()); } message& set_serial(uint32 serial) { dbus_message_set_serial(message_.get(), serial); return *this; } uint32 get_reply_serial() { return dbus_message_get_reply_serial(message_.get()); } message& set_reply_serial(uint32 reply_serial) { dbus_message_set_reply_serial(message_.get(), reply_serial); return *this; } struct packer { impl::message_iterator iter_; packer(message& m) { impl::message_iterator::init_append(m, iter_); } template packer& pack(const Element& e) { return *this << e; } }; struct unpacker { impl::message_iterator iter_; unpacker(message& m) { impl::message_iterator::init(m, iter_); } template unpacker& unpack(Element& e) { return *this >> e; } }; template packer pack(const Element& e) { return packer(*this).pack(e); } template unpacker unpack(Element& e) { return unpacker(*this).unpack(e); } private: static std::string sanitize(const char* str) { return (str == NULL) ? "(null)" : str; } }; template message::packer operator<<(message m, const Element& e) { return message::packer(m).pack(e); } template typename boost::enable_if, message::packer&>::type operator<<(message::packer& p, const Element& e) { p.iter_.append_basic(element::code, &e); return p; } inline message::packer& operator<<(message::packer& p, const char* c) { p.iter_.append_basic(element::code, &c); return p; } inline message::packer& operator<<(message::packer& p, const string& e) { const char* c = e.c_str(); return p << c; } template message::unpacker operator>>(message m, Element& e) { return message::unpacker(m).unpack(e); } template typename boost::enable_if, message::unpacker&>::type operator>>(message::unpacker& u, Element& e) { u.iter_.get_basic(&e); u.iter_.next(); return u; } inline message::unpacker& operator>>(message::unpacker& u, string& s) { const char* c; u.iter_.get_basic(&c); s.assign(c); u.iter_.next(); return u; } inline std::ostream& operator<<(std::ostream& os, const message& m) { os << "type='" << m.get_type() << "'," << "sender='" << m.get_sender() << "'," << "interface='" << m.get_interface() << "'," << "member='" << m.get_member() << "'," << "path='" << m.get_path() << "'," << "destination='" << m.get_destination() << "'"; return os; } } // namespace dbus #include #endif // DBUS_MESSAGE_HPP