incremental
diff --git a/boost-dbus/include/dbus/impl/connection.ipp b/boost-dbus/include/dbus/impl/connection.ipp
new file mode 100644
index 0000000..24a257d
--- /dev/null
+++ b/boost-dbus/include/dbus/impl/connection.ipp
@@ -0,0 +1,102 @@
+// 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_CONNECTION_IPP
+#define DBUS_CONNECTION_IPP
+
+#include <dbus/dbus.h>
+#include <dbus/detail/watch_timeout.hpp>
+
+#include <boost/atomic.hpp>
+
+namespace dbus {
+namespace impl {
+
+class connection {
+ public:
+ boost::atomic<bool> is_paused;
+ DBusConnection* conn;
+
+ connection() : is_paused(true), conn(NULL) {}
+
+ void open(boost::asio::io_service& io, int bus) {
+ error e;
+ conn = dbus_bus_get_private((DBusBusType)bus, e);
+ e.throw_if_set();
+
+ dbus_connection_set_exit_on_disconnect(conn, false);
+
+ detail::set_watch_timeout_dispatch_functions(conn, io);
+ }
+
+ void open(boost::asio::io_service& io, const string& address) {
+ error e;
+ conn = dbus_connection_open_private(address.c_str(), e);
+ e.throw_if_set();
+
+ dbus_bus_register(conn, e);
+ e.throw_if_set();
+
+ dbus_connection_set_exit_on_disconnect(conn, false);
+
+ detail::set_watch_timeout_dispatch_functions(conn, io);
+ }
+
+ ~connection() {
+ if (conn != NULL) {
+ dbus_connection_close(conn);
+ dbus_connection_unref(conn);
+ }
+ }
+
+ operator DBusConnection*() { return conn; }
+ operator const DBusConnection*() const { return conn; }
+
+ message send_with_reply_and_block(message& m,
+ int timeout_in_milliseconds = -1) {
+ error e;
+ DBusMessage* out = dbus_connection_send_with_reply_and_block(
+ conn, m, timeout_in_milliseconds, e);
+ e.throw_if_set();
+ message reply(out);
+
+ return reply;
+ }
+
+ void send(message& m) {
+ // ignoring message serial for now
+ dbus_connection_send(conn, m, NULL);
+ }
+
+ void send_with_reply(message& m, DBusPendingCall** p,
+ int timeout_in_milliseconds = -1) {
+ dbus_connection_send_with_reply(conn, m, p, timeout_in_milliseconds);
+ }
+
+ // begin asynchronous operation
+ // FIXME should not get io from an argument
+ void start(boost::asio::io_service& io) {
+ bool old_value(true);
+ if (is_paused.compare_exchange_strong(old_value, false)) {
+ // If two threads call connection::async_send()
+ // simultaneously on a paused connection, then
+ // only one will pass the CAS instruction and
+ // only one dispatch_handler will be injected.
+ io.post(detail::dispatch_handler(io, conn));
+ }
+ }
+
+ void cancel(boost::asio::io_service& io) {
+ bool old_value(false);
+ if (is_paused.compare_exchange_strong(old_value, true)) {
+ // TODO
+ }
+ }
+};
+
+} // namespace impl
+} // namespace dbus
+
+#endif // DBUS_CONNECTION_IPP
diff --git a/boost-dbus/include/dbus/impl/filter.ipp b/boost-dbus/include/dbus/impl/filter.ipp
new file mode 100644
index 0000000..a64d6fd
--- /dev/null
+++ b/boost-dbus/include/dbus/impl/filter.ipp
@@ -0,0 +1,39 @@
+// 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_FILTER_IPP
+#define DBUS_FILTER_IPP
+
+namespace dbus {
+namespace impl {
+
+inline DBusHandlerResult filter_callback(DBusConnection* c, DBusMessage* m,
+ void* userdata) {
+ try {
+ filter& f = *static_cast<filter*>(userdata);
+ message m_(m);
+ if (f.offer(m_)) {
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ } catch (...) {
+ // do not throw in C callbacks. Just don't.
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+} // namespace impl
+
+void connection_service::new_filter(implementation_type& impl, filter& f) {
+ dbus_connection_add_filter(impl, &impl::filter_callback, &f, NULL);
+}
+
+void connection_service::delete_filter(implementation_type& impl, filter& f) {
+ dbus_connection_remove_filter(impl, &impl::filter_callback, &f);
+}
+
+} // namespace dbus
+
+#endif // DBUS_FILTER_IPP
diff --git a/boost-dbus/include/dbus/impl/match.ipp b/boost-dbus/include/dbus/impl/match.ipp
new file mode 100644
index 0000000..9f6a5da
--- /dev/null
+++ b/boost-dbus/include/dbus/impl/match.ipp
@@ -0,0 +1,26 @@
+// 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_MATCH_IPP
+#define DBUS_MATCH_IPP
+
+namespace dbus {
+void connection_service::new_match(implementation_type& impl, match& m) {
+ error e;
+ dbus_bus_add_match(impl, m.get_expression().c_str(), e);
+ e.throw_if_set();
+ // eventually, for complete asynchronicity, this should connect to
+ // org.freedesktop.DBus and call AddMatch
+}
+
+void connection_service::delete_match(implementation_type& impl, match& m) {
+ error e;
+ dbus_bus_remove_match(impl, m.get_expression().c_str(), e);
+ e.throw_if_set();
+}
+
+} // namespace dbus
+
+#endif // DBUS_MATCH_IPP
diff --git a/boost-dbus/include/dbus/impl/message_iterator.hpp b/boost-dbus/include/dbus/impl/message_iterator.hpp
new file mode 100644
index 0000000..44bcf2e
--- /dev/null
+++ b/boost-dbus/include/dbus/impl/message_iterator.hpp
@@ -0,0 +1,50 @@
+// 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_IMPL_MESSAGE_ITERATOR_HPP
+#define DBUS_IMPL_MESSAGE_ITERATOR_HPP
+
+#include <dbus/dbus.h>
+
+namespace dbus {
+
+class message;
+
+namespace impl {
+
+class message_iterator {
+ DBusMessageIter DBusMessageIter_;
+
+ public:
+ // writing
+ static void init_append(message &m, message_iterator &i);
+
+ void append_basic(int code, const void *value);
+
+ void open_container(int code, const char *signature, message_iterator &);
+ void close_container(message_iterator &);
+ void abandon_container(message_iterator &);
+
+ void append_fixed_array(int code, const void *value, int n_elements);
+
+ // reading
+ static bool init(message &m, message_iterator &i);
+
+ bool next();
+ bool has_next();
+ int get_arg_type();
+
+ void get_basic(void *value);
+
+ void recurse(message_iterator &);
+
+ int get_element_type();
+ void get_fixed_array(void *value, int *n_elements);
+};
+
+} // namespace impl
+} // namespace dbus
+
+#endif // DBUS_IMPL_MESSAGE_ITERATOR_HPP
diff --git a/boost-dbus/include/dbus/impl/message_iterator.ipp b/boost-dbus/include/dbus/impl/message_iterator.ipp
new file mode 100644
index 0000000..eb2584f
--- /dev/null
+++ b/boost-dbus/include/dbus/impl/message_iterator.ipp
@@ -0,0 +1,89 @@
+// 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_IMPL_MESSAGE_ITERATOR_IPP
+#define DBUS_IMPL_MESSAGE_ITERATOR_IPP
+
+#include <dbus/impl/message_iterator.hpp>
+
+namespace dbus {
+namespace impl {
+
+inline void message_iterator::init_append(message& m, message_iterator& i)
+{
+ dbus_message_iter_init_append(m, &i.DBusMessageIter_);
+}
+inline void message_iterator::append_basic(int code, const void *value)
+{
+ // returns false if not enough memory- throw bad_alloc
+ dbus_message_iter_append_basic(&DBusMessageIter_, code, value);
+}
+inline void message_iterator::open_container(int code, const char *signature, message_iterator& sub)
+{
+ // returns false if not enough memory- throw bad_alloc
+ dbus_message_iter_open_container(&DBusMessageIter_, code, signature, &sub.DBusMessageIter_);
+}
+
+inline void message_iterator::close_container(message_iterator& sub)
+{
+ // returns false if not enough memory- throw bad_alloc
+ dbus_message_iter_close_container(&DBusMessageIter_, &sub.DBusMessageIter_);
+}
+
+inline void message_iterator::abandon_container(message_iterator& sub)
+{
+ dbus_message_iter_abandon_container(&DBusMessageIter_, &sub.DBusMessageIter_);
+}
+
+inline void message_iterator::append_fixed_array(int code, const void *value, int n_elements)
+{
+ // returns false if not enough memory- throw bad_alloc
+ dbus_message_iter_append_fixed_array(&DBusMessageIter_, code, value, n_elements);
+}
+
+inline bool message_iterator::init(message& m, message_iterator& i)
+{
+ return dbus_message_iter_init(m, &i.DBusMessageIter_);
+}
+
+inline bool message_iterator::next()
+{
+ return dbus_message_iter_next(&DBusMessageIter_);
+}
+
+inline bool message_iterator::has_next()
+{
+ return dbus_message_iter_has_next(&DBusMessageIter_);
+}
+
+inline int message_iterator::get_arg_type()
+{
+ return dbus_message_iter_get_arg_type(&DBusMessageIter_);
+}
+
+inline void message_iterator::get_basic(void *value)
+{
+ dbus_message_iter_get_basic(&DBusMessageIter_, value);
+}
+
+inline void message_iterator::recurse(message_iterator& sub)
+{
+ dbus_message_iter_recurse(&DBusMessageIter_, &sub.DBusMessageIter_);
+}
+
+inline int message_iterator::get_element_type()
+{
+ return dbus_message_iter_get_element_type(&DBusMessageIter_);
+}
+
+inline void message_iterator::get_fixed_array(void *value, int *n_elements)
+{
+ dbus_message_iter_get_fixed_array(&DBusMessageIter_, value, n_elements);
+}
+
+} // namespace impl
+} // namespace dbus
+
+#endif // DBUS_IMPL_MESSAGE_ITERATOR_IPP