From 4764f5cedf913fde6b8e193dad1356fd420d965e Mon Sep 17 00:00:00 2001 From: Martin Haefner Date: Sat, 23 Dec 2017 17:17:41 +0100 Subject: [PATCH] new serialization --- examples/echo/main.cpp | 1 + examples/mixed/mixed.cpp | 111 +++---- include/simppl/bool.h | 61 +++- include/simppl/buffer.h | 39 +-- include/simppl/clientside.h | 23 +- include/simppl/detail/callinterface.h | 21 +- .../simppl/detail/deserialize_and_return.h | 15 +- include/simppl/detail/holders.h | 17 +- include/simppl/detail/parameter_deduction.h | 4 +- include/simppl/detail/serialization.h | 281 ------------------ include/simppl/detail/serverresponseholder.h | 8 +- include/simppl/detail/validation.h | 4 + include/simppl/map.h | 46 +-- include/simppl/objectpath.h | 35 +-- include/simppl/pair.h | 45 ++- include/simppl/pod.h | 122 +++++--- include/simppl/property.h | 4 +- include/simppl/serialization.h | 111 ++++++- include/simppl/serverside.h | 35 ++- include/simppl/skeletonbase.h | 4 +- include/simppl/string.h | 72 +---- include/simppl/struct.h | 215 ++++++-------- include/simppl/stubbase.h | 18 +- include/simppl/tuple.h | 112 +++---- include/simppl/variant.h | 108 +++---- include/simppl/vector.h | 47 ++- src/CMakeLists.txt | 8 +- src/dispatcher.cpp | 30 +- src/error.cpp | 9 +- src/serialization.cpp | 130 +------- src/serverresponseholder.cpp | 4 +- src/serverside.cpp | 1 - src/skeletonbase.cpp | 67 +++-- src/stubbase.cpp | 65 ++-- tests/CMakeLists.txt | 12 +- tests/buffer.cpp | 1 + tests/introserver.cpp | 5 + tests/properties.cpp | 3 + tests/simple.cpp | 18 +- tests/variant.cpp | 3 + 40 files changed, 808 insertions(+), 1107 deletions(-) delete mode 100644 include/simppl/detail/serialization.h diff --git a/examples/echo/main.cpp b/examples/echo/main.cpp index b7dfde7..40423b8 100644 --- a/examples/echo/main.cpp +++ b/examples/echo/main.cpp @@ -5,6 +5,7 @@ #include "simppl/stub.h" #include "simppl/skeleton.h" #include "simppl/dispatcher.h" +#include "simppl/string.h" class MyEchoClient : public simppl::dbus::Stub diff --git a/examples/mixed/mixed.cpp b/examples/mixed/mixed.cpp index 1bb4180..5bcc72f 100644 --- a/examples/mixed/mixed.cpp +++ b/examples/mixed/mixed.cpp @@ -14,6 +14,7 @@ #include "simppl/stub.h" #include "simppl/skeleton.h" +#include "simppl/string.h" namespace test @@ -25,7 +26,7 @@ namespace test INTERFACE(clock) { Signal tick; - + clock() : INIT(tick) { @@ -49,75 +50,75 @@ namespace test void the_client() { - simppl::dbus::Dispatcher d; - simppl::dbus::Stub clock(d, "clock"); - simppl::dbus::Stub op(d, "op"); - - clock.connected = [&clock, &op](simppl::dbus::ConnectionState st){ - clock.tick.attach() >> [&op](int count){ - std::cout << "tick: " << count << std::endl; - - if (count == 4) - { - // mixing blocking and non-blocking calls is not really a good - // idea, but this is for demonstration that it works only - std::string rc = op.do_it("Hello"); - std::cout << "Response: " << rc << std::endl; - } - }; - }; - - d.run(); + simppl::dbus::Dispatcher d; + simppl::dbus::Stub clock(d, "clock"); + simppl::dbus::Stub op(d, "op"); + + clock.connected = [&clock, &op](simppl::dbus::ConnectionState st){ + clock.tick.attach() >> [&op](int count){ + std::cout << "tick: " << count << std::endl; + + if (count == 4) + { + // mixing blocking and non-blocking calls is not really a good + // idea, but this is for demonstration that it works only + std::string rc = op.do_it("Hello"); + std::cout << "Response: " << rc << std::endl; + } + }; + }; + + d.run(); } void the_clock() { - simppl::dbus::Dispatcher d; - simppl::dbus::Skeleton skel(d, "clock"); - - std::thread t([&skel](){ - int i=0; - - while(true) - { - skel.tick.notify(i++); - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - }); - - d.run(); + simppl::dbus::Dispatcher d; + simppl::dbus::Skeleton skel(d, "clock"); + + std::thread t([&skel](){ + int i=0; + + while(true) + { + skel.tick.notify(i++); + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + }); + + d.run(); } void the_long_op() { - simppl::dbus::Dispatcher d; - simppl::dbus::Skeleton skel(d, "op"); - - // just echo with some waiting time - skel.do_it >> [&skel](const std::string& str){ - std::this_thread::sleep_for(std::chrono::seconds(5)); - skel.respond_with(skel.do_it(str)); - }; - - d.run(); + simppl::dbus::Dispatcher d; + simppl::dbus::Skeleton skel(d, "op"); + + // just echo with some waiting time + skel.do_it >> [&skel](const std::string& str){ + std::this_thread::sleep_for(std::chrono::seconds(5)); + skel.respond_with(skel.do_it(str)); + }; + + d.run(); } int main() { - simppl::dbus::enable_threads(); - - std::thread t1(the_long_op); - std::thread t2(the_clock); - - std::thread t3(the_client); - - while(true) - std::this_thread::sleep_for(std::chrono::seconds(1)); - - return 0; + simppl::dbus::enable_threads(); + + std::thread t1(the_long_op); + std::thread t2(the_clock); + + std::thread t3(the_client); + + while(true) + std::this_thread::sleep_for(std::chrono::seconds(1)); + + return 0; } diff --git a/include/simppl/bool.h b/include/simppl/bool.h index d424038..2c5b33e 100644 --- a/include/simppl/bool.h +++ b/include/simppl/bool.h @@ -1,25 +1,60 @@ - - - -inline - Serializer& write(bool b) +#ifndef __SIMPPL_DBUS_BOOL_H__ +#define __SIMPPL_DBUS_BOOL_H__ + + +#include "simppl/serialization.h" + + +namespace simppl +{ + +namespace dbus +{ + + +// forward decl +template +struct Codec; + + +template<> +struct Codec +{ + // FIXME can this be removed? + enum { dbus_type_code = DBUS_TYPE_BOOLEAN }; + + + static inline + void encode(DBusMessageIter& iter, bool b) { dbus_bool_t _b = b; - dbus_message_iter_append_basic(iter_, dbus_type_code::value, &_b); - return *this; + dbus_message_iter_append_basic(&iter, dbus_type_code, &_b); } - -Deserializer& read(bool& t) + // FIXME move to impl file + static inline + void decode(DBusMessageIter& iter, bool& t) { dbus_bool_t b; - dbus_message_iter_get_basic(iter_, &b); - dbus_message_iter_next(iter_); + dbus_message_iter_get_basic(&iter, &b); + dbus_message_iter_next(&iter); t = b; - return *this; } + + + static inline + std::ostream& make_type_signature(std::ostream& os) + { + return os << DBUS_TYPE_BOOLEAN_AS_STRING; + } +}; + + +} // namespace dbus + +} // namespace simppl -template<> struct dbus_type_code { enum { value = DBUS_TYPE_BOOLEAN }; }; +#endif // __SIMPPL_DBUS_BOOL_H__ diff --git a/include/simppl/buffer.h b/include/simppl/buffer.h index 8f82aad..d2d7a6f 100644 --- a/include/simppl/buffer.h +++ b/include/simppl/buffer.h @@ -5,6 +5,8 @@ #include #include +#include "simppl/serialization.h" + namespace simppl { @@ -47,6 +49,7 @@ struct FixedSizeBuffer /** * No copy of data. */ + explicit FixedSizeBuffer(void* buf) : buf((unsigned char*)buf) , self(false) @@ -80,57 +83,47 @@ struct FixedSizeBuffer unsigned char* buf; bool self; }; - - -namespace detail -{ template struct Codec> { static - void encode(Serializer& s, const FixedSizeBuffer& b) + void encode(DBusMessageIter& iter, const FixedSizeBuffer& b) { - DBusMessageIter iter; + DBusMessageIter _iter; - dbus_message_iter_open_container(s.iter_, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &iter); - dbus_message_iter_append_fixed_array(&iter, DBUS_TYPE_BYTE, &b.buf, len); - dbus_message_iter_close_container(s.iter_, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &_iter); + dbus_message_iter_append_fixed_array(&_iter, DBUS_TYPE_BYTE, &b.buf, len); + dbus_message_iter_close_container(&iter, &_iter); } static - void decode(Deserializer& s, FixedSizeBuffer& b) + void decode(DBusMessageIter& iter, FixedSizeBuffer& b) { - DBusMessageIter iter; - dbus_message_iter_recurse(s.iter_, &iter); + DBusMessageIter _iter; + dbus_message_iter_recurse(&iter, &_iter); unsigned char* buf; int _len = len; - dbus_message_iter_get_fixed_array(&iter, &buf, &_len); + dbus_message_iter_get_fixed_array(&_iter, &buf, &_len); b.assign(buf); // advance to next element - dbus_message_iter_next(s.iter_); + dbus_message_iter_next(&iter); } -}; - - -template -struct make_type_signature> -{ + + static inline - std::ostream& eval(std::ostream& os) + std::ostream& make_type_signature(std::ostream& os) { return os << DBUS_TYPE_ARRAY_AS_STRING; } }; -} // namespace detail - } // namespace dbus } // namespace simppl diff --git a/include/simppl/clientside.h b/include/simppl/clientside.h index 028f879..8b7470c 100644 --- a/include/simppl/clientside.h +++ b/include/simppl/clientside.h @@ -117,8 +117,10 @@ struct ClientSignal : ClientSignalBase { ClientSignal* that = (ClientSignal*)(obj); - detail::Deserializer d(msg); - detail::GetCaller>::type::template eval(d, that->f_); + DBusMessageIter iter; + dbus_message_iter_init(msg, &iter); + + detail::GetCaller>::type::template eval(iter, that->f_); } }; @@ -142,7 +144,7 @@ struct ClientPropertyWritableMixin Variant vt(t); - that->stub().set_property(that->name(), [&vt](detail::Serializer& s){ + that->stub().set_property(that->name(), [&vt](DBusMessageIter& s){ simppl::dbus::detail::serialize(s, vt); }); } @@ -155,7 +157,7 @@ struct ClientPropertyWritableMixin Variant vt(t); - return detail::InterimCallbackHolder(that->stub().set_property_async(that->name(), [&vt](detail::Serializer& s){ + return detail::InterimCallbackHolder(that->stub().set_property_async(that->name(), [&vt](DBusMessageIter& s){ simppl::dbus::detail::serialize(s, vt); })); } @@ -201,10 +203,11 @@ struct ClientProperty { message_ptr_t msg = stub().get_property(name_); - detail::Deserializer ds(msg.get()); + DBusMessageIter iter; + dbus_message_iter_init(msg.get(), &iter); Variant v; - ds.read(v); + Codec>::decode(iter, v); return std::move(*v.template get()); } @@ -253,10 +256,10 @@ struct ClientProperty template ClientProperty& ClientProperty::attach() { - stub().attach_property(name_, [this](detail::Deserializer& s){ + stub().attach_property(name_, [this](DBusMessageIter& iter){ Variant d; - s.read(d); + Codec>::decode(iter, d); if (this->f_) this->f_(CallState(42), *d.template get()); @@ -321,7 +324,7 @@ struct ClientMethod static_assert(std::is_convertible>::type, args_type>::value, "args mismatch"); - auto msg = parent_->send_request_and_block(method_name_, [&](detail::Serializer& s){ + auto msg = parent_->send_request_and_block(method_name_, [&](DBusMessageIter& s){ serializer_type::eval(s, t...); }, is_oneway); @@ -338,7 +341,7 @@ struct ClientMethod static_assert(std::is_convertible::type...>>::type, args_type>::value, "args mismatch"); - return detail::InterimCallbackHolder(parent_->send_request(method_name_, [&](detail::Serializer& s){ + return detail::InterimCallbackHolder(parent_->send_request(method_name_, [&](DBusMessageIter& s){ serializer_type::eval(s, t...); }, false)); } diff --git a/include/simppl/detail/callinterface.h b/include/simppl/detail/callinterface.h index 9220cee..084a599 100644 --- a/include/simppl/detail/callinterface.h +++ b/include/simppl/detail/callinterface.h @@ -5,6 +5,7 @@ #include "simppl/noninstantiable.h" #include "simppl/typelist.h" #include "simppl/callstate.h" +#include "simppl/tuple.h" namespace simppl @@ -85,22 +86,22 @@ struct DeserializeAndCall : simppl::NonInstantiable { template static - void eval(Deserializer& d, FunctorT& f) + void eval(DBusMessageIter& iter, FunctorT& f) { std::tuple tuple; - d.read_flattened(tuple); + Codec>::decode_flattened(iter, tuple); FunctionCaller<0, std::tuple>::template eval(f, tuple); } template static - void evalResponse(Deserializer& d, FunctorT& f, const simppl::dbus::CallState& cs) + void evalResponse(DBusMessageIter& iter, FunctorT& f, const simppl::dbus::CallState& cs) { std::tuple tuple; if (cs) - d.read_flattened(tuple); + Codec>::decode_flattened(iter, tuple); FunctionCaller<0, std::tuple>::template eval_cs(f, cs, tuple); } @@ -112,22 +113,22 @@ struct DeserializeAndCall> : simppl::NonInstantiable { template static inline - void eval(Deserializer& d, FunctorT& f) + void eval(DBusMessageIter& iter, FunctorT& f) { std::tuple tuple; - d.read_flattened(tuple); + Codec>::decode_flattened(iter, tuple); FunctionCaller<0, std::tuple>::template eval(f, tuple); } template static - void evalResponse(Deserializer& d, FunctorT& f, const simppl::dbus::CallState& cs) + void evalResponse(DBusMessageIter& iter, FunctorT& f, const simppl::dbus::CallState& cs) { std::tuple tuple; if (cs) - d.read_flattened(tuple); + Codec>::decode_flattened(iter, tuple); FunctionCaller<0, std::tuple>::template eval_cs(f, cs, tuple); } @@ -138,14 +139,14 @@ struct DeserializeAndCall0 : simppl::NonInstantiable { template static inline - void eval(Deserializer& /*d*/, FunctorT& f) + void eval(DBusMessageIter& /*iter*/, FunctorT& f) { f(); } template static inline - void evalResponse(Deserializer& /*d*/, FunctorT& f, const simppl::dbus::CallState& cs) + void evalResponse(DBusMessageIter& /*iter*/, FunctorT& f, const simppl::dbus::CallState& cs) { f(cs); } diff --git a/include/simppl/detail/deserialize_and_return.h b/include/simppl/detail/deserialize_and_return.h index f3d2a88..2db998b 100644 --- a/include/simppl/detail/deserialize_and_return.h +++ b/include/simppl/detail/deserialize_and_return.h @@ -2,9 +2,6 @@ #define __SIMPPL_DETAIL_DESERIALIZE_AND_RETURN_H__ -#include "serialization.h" - - namespace simppl { @@ -22,8 +19,10 @@ struct deserialize_and_return { ReturnT rc; - Deserializer d(msg); - Codec::decode(d, rc); + DBusMessageIter iter; + dbus_message_iter_init(msg, &iter); + + Codec::decode(iter, rc); return rc; } @@ -52,8 +51,10 @@ struct deserialize_and_return> { return_type rc; - Deserializer d(msg); - Codec::decode(d, rc); + DBusMessageIter iter; + dbus_message_iter_init(msg, &iter); + + Codec::decode_flattened(iter, rc); return rc; } diff --git a/include/simppl/detail/holders.h b/include/simppl/detail/holders.h index 030167f..f0884a4 100644 --- a/include/simppl/detail/holders.h +++ b/include/simppl/detail/holders.h @@ -22,7 +22,7 @@ struct InterimCallbackHolder InterimCallbackHolder(const InterimCallbackHolder& rhs) : pc_(std::move(rhs.pc_)) { - // NOOP + // NOOP } InterimCallbackHolder& operator=(const InterimCallbackHolder&) = delete; @@ -70,9 +70,11 @@ struct CallbackHolder CallState cs(*msg); // TODO check signature - - Deserializer d(msg.get()); - GetCaller::type::template evalResponse(d, that->f_, cs); + + DBusMessageIter iter; + dbus_message_iter_init(msg.get(), &iter); + + GetCaller::type::template evalResponse(iter, that->f_, cs); } FuncT f_; @@ -103,7 +105,7 @@ struct PropertyCallbackHolder static void pending_notify(DBusPendingCall* pc, void* data) { - auto msg = simppl::dbus::make_message(dbus_pending_call_steal_reply(pc)); + auto msg = simppl::dbus::make_message(dbus_pending_call_steal_reply(pc)); auto that = (PropertyCallbackHolder*)data; assert(that->f_); @@ -111,10 +113,11 @@ struct PropertyCallbackHolder simppl::dbus::CallState cs(*msg); if (cs) { - Deserializer ds(msg.get()); + DBusMessageIter iter; + dbus_message_iter_init(msg.get(), &iter); simppl::Variant v; - ds.read(v); + Codec>::decode(iter, v); that->f_(cs, *v.template get()); } diff --git a/include/simppl/detail/parameter_deduction.h b/include/simppl/detail/parameter_deduction.h index 2766304..feada96 100644 --- a/include/simppl/detail/parameter_deduction.h +++ b/include/simppl/detail/parameter_deduction.h @@ -127,7 +127,7 @@ template struct SerializerGenerator { static inline - void eval(Serializer& s, const T&... t) + void eval(DBusMessageIter& s, const T&... t) { serialize(s, t...); } @@ -367,7 +367,7 @@ struct IntrospectionHelper static inline void eval(std::ostream& os, int i) { os << "::type>::eval(os); + Codec::type>::make_type_signature(os); os << "\" direction=\"" << (is_in::value?"in":"out") << "\"/>\n"; } }; diff --git a/include/simppl/detail/serialization.h b/include/simppl/detail/serialization.h deleted file mode 100644 index 8d4e0cc..0000000 --- a/include/simppl/detail/serialization.h +++ /dev/null @@ -1,281 +0,0 @@ -#ifndef SIMPPL_DETAIL_SERIALIZATION_H -#define SIMPPL_DETAIL_SERIALIZATION_H - - -#include "simppl/noninstantiable.h" -#include "simppl/typelist.h" -#include "simppl/callstate.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef SIMPPL_HAVE_BOOST_FUSION -# include -# include -#endif - - -namespace simppl -{ - -namespace dbus -{ - -namespace detail -{ -template -struct Codec; - -template -struct make_type_signature; - - -// --------------------------------------------------------------------- - - -// generic type switch -template struct dbus_type_code -{ enum { value = std::is_enum::value ? DBUS_TYPE_INT32 : DBUS_TYPE_STRUCT }; }; - - -// --------------------------------------------------------------------- - - -template -struct make_serializer_imp; - -template -struct make_serializer_imp > -{ - typedef SerializerTuple::type> >::type, typename Back::type> type; -}; - -template -struct make_serializer_imp > -{ - typedef SerializerTuple type; -}; - - -// --------------------------------------------------------------------- - - -template -struct make_type_signature -{ - static inline std::ostream& eval(std::ostream& os) - { - make_type_signature::helper(os, bool_constant::value || std::is_enum::value>()); - return os; - } - - -private: - - // pod helper - static inline void helper(std::ostream& os, std::true_type) - { - os << (char)dbus_type_code::value; - } - - // struct helper - static inline void helper(std::ostream& os, std::false_type) - { - T::serializer_type::write_signature(os << DBUS_STRUCT_BEGIN_CHAR_AS_STRING); - os << DBUS_STRUCT_END_CHAR_AS_STRING; - } -}; - - -// --------------------------------------------------------------------- - - -struct Pod {}; -struct Pointer {}; -struct Struct {}; - -template -struct type_deducer -{ - typedef typename std::conditional::value || std::is_enum::value, Pod, - typename std::conditional::value, Pointer, Struct>::type>::type type; -}; - - -// --------------------------------------------------------------------- - - -struct Serializer // : noncopyable -{ - explicit - Serializer(DBusMessage* msg); - - explicit - Serializer(DBusMessageIter* iter); - - template - inline - Serializer& write(const T& t) - { - return write(t, typename type_deducer::type()); - } - - template - inline - Serializer& write(T t, Pointer) - { - return write_ptr(t); - } - - -private: - - DBusMessageIter private_iter_; - - -public: - - DBusMessageIter* iter_; -}; - -} // namespace detail - -} // namespace dbus - -} // namespace simppl - - -// ----------------------------------------------------------------------------- - - -namespace simppl -{ - -namespace dbus -{ - -namespace detail -{ - -struct Deserializer // : noncopyable -{ - static inline - void free(void* ptr) - { - delete[] (char*)ptr; - } - - explicit - Deserializer(DBusMessage* msg); - - explicit - Deserializer(DBusMessageIter* iter); - - template - inline - Deserializer& read(T& t) - { - return read(t, bool_constant::value || std::is_enum::value>()); - } - - - template - Deserializer& read_flattened(std::tuple& t) - { - TupleDeserializer tds(*this, true); - std_tuple_for_each(t, std::ref(tds)); - return *this; - } - - -private: - - static inline - void* allocate(size_t len) - { - return new char[len]; - } - - DBusMessageIter private_iter_; - -public: // FIXME friend? - - DBusMessageIter* iter_; -}; - -} // namespace detail - -} // namespace dbus - -} // namespace simppl - - -// ------------------------------------------------------------------------ - - -namespace simppl -{ - -namespace dbus -{ - -namespace detail -{ - -inline -Serializer& serialize(Serializer& s) -{ - return s; -} - -template -inline -Serializer& serialize(Serializer& s, const T1& t1, const T&... t) -{ - Codec::encode(s, t1); - return serialize(s, t...); -} - - -} // namespace detail - -} // namespace dbus - -} // namespace simppl - - -#include "simppl/string.h" -#include "simppl/buffer.h" -#include "simppl/vector.h" -#include "simppl/map.h" -#include "simppl/tuple.h" -#include "simppl/objectpath.h" -#include "simppl/variant.h" - - -namespace detail { - -namespace dbus { - -namespace simppl { - - -} // namespace detail - -} // namespace dbus - -} // namespace simppl - - -#endif // SIMPPL_DETAIL_SERIALIZATION_H diff --git a/include/simppl/detail/serverresponseholder.h b/include/simppl/detail/serverresponseholder.h index eb08510..d65f646 100644 --- a/include/simppl/detail/serverresponseholder.h +++ b/include/simppl/detail/serverresponseholder.h @@ -10,6 +10,7 @@ // forward decl struct DBusMessage; +struct DBusMessageIter; namespace simppl @@ -18,16 +19,13 @@ namespace simppl namespace dbus { - namespace detail { -struct Serializer; - struct ServerResponseHolder { - ServerResponseHolder(std::function f); + ServerResponseHolder(std::function f); ~ServerResponseHolder(); @@ -37,7 +35,7 @@ struct ServerResponseHolder ServerResponseHolder(const ServerResponseHolder& rhs) = delete; ServerResponseHolder& operator=(const ServerResponseHolder& rhs) = delete; - std::function f_; + std::function f_; }; } // namespace detail diff --git a/include/simppl/detail/validation.h b/include/simppl/detail/validation.h index 1b00b78..28d7628 100644 --- a/include/simppl/detail/validation.h +++ b/include/simppl/detail/validation.h @@ -6,6 +6,10 @@ # include #endif +#include "simppl/struct.h" +#include "simppl/objectpath.h" +#include "simppl/buffer.h" // FIXME buffer is a valid type + namespace simppl { diff --git a/include/simppl/map.h b/include/simppl/map.h index cb04255..5298ef3 100644 --- a/include/simppl/map.h +++ b/include/simppl/map.h @@ -13,70 +13,56 @@ namespace simppl namespace dbus { -namespace detail -{ - template struct Codec> { static - void encode(Serializer& s, const std::map& m) + void encode(DBusMessageIter& iter, const std::map& m) { std::ostringstream buf; - make_type_signature>::eval(buf); - - DBusMessageIter iter; - dbus_message_iter_open_container(s.iter_, DBUS_TYPE_ARRAY, buf.str().c_str(), &iter); + Codec>::make_type_signature(buf); - Serializer s1(&iter); + DBusMessageIter _iter; + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, buf.str().c_str(), &_iter); for (auto& e : m) { - Codec::encode(s1, e); + Codec>::encode(_iter, e); } - dbus_message_iter_close_container(s.iter_, &iter); + dbus_message_iter_close_container(&iter, &_iter); } static - void decode(Deserializer& s, std::map& m) + void decode(DBusMessageIter& iter, std::map& m) { m.clear(); - DBusMessageIter iter; - dbus_message_iter_recurse(s.iter_, &iter); - - Deserializer ds(&iter); + DBusMessageIter _iter; + dbus_message_iter_recurse(&iter, &_iter); - while(dbus_message_iter_get_arg_type(&iter) != 0) + while(dbus_message_iter_get_arg_type(&_iter) != 0) { std::pair p; - Codec::decode(ds, p); + Codec::decode(_iter, p); m.insert(p); } // advance to next element - dbus_message_iter_next(s.iter_); - + dbus_message_iter_next(&iter); } -}; - - -template -struct make_type_signature> -{ + + static inline - std::ostream& eval(std::ostream& os) + std::ostream& make_type_signature(std::ostream& os) { - return make_type_signature::type, ValueT>>::eval(os << DBUS_TYPE_ARRAY_AS_STRING); + return Codec::type, ValueT>>::make_type_signature(os << DBUS_TYPE_ARRAY_AS_STRING); } }; -} // namespace detail - } // namespace dbus } // namespace simppl diff --git a/include/simppl/objectpath.h b/include/simppl/objectpath.h index 84babee..dbdf45f 100644 --- a/include/simppl/objectpath.h +++ b/include/simppl/objectpath.h @@ -4,6 +4,8 @@ #include +#include "simppl/serialization.h" + namespace simppl { @@ -44,43 +46,26 @@ struct ObjectPath }; -namespace detail +struct ObjectPathCodec { + enum { dbus_type_code = DBUS_TYPE_OBJECT_PATH }; - -template<> -struct Codec -{ static - void encode(Serializer& s, const ObjectPath& p) - { - // FIXME - } + void encode(DBusMessageIter& s, const ObjectPath& p); + static + void decode(DBusMessageIter& s, ObjectPath& p); static - void decode(Deserializer& s, ObjectPath& p) - { - // FIXME - } + std::ostream& make_type_signature(std::ostream& os); }; template<> -struct make_type_signature -{ - static inline - std::ostream& eval(std::ostream& os) - { - return os << DBUS_TYPE_OBJECT_PATH_AS_STRING; - } -}; - - -template<> struct dbus_type_code { enum { value = DBUS_TYPE_OBJECT_PATH }; }; +struct Codec : public ObjectPathCodec {}; -} +} // dbus } // simppl diff --git a/include/simppl/pair.h b/include/simppl/pair.h index a437329..acac614 100644 --- a/include/simppl/pair.h +++ b/include/simppl/pair.h @@ -4,66 +4,59 @@ #include +#include "simppl/serialization.h" + namespace simppl { namespace dbus { - -namespace detail -{ template struct Codec> { static - void encode(Serializer& s, const std::pair& p) + void encode(DBusMessageIter& iter, const std::pair& p) { DBusMessageIter item_iterator; - dbus_message_iter_open_container(s.iter_, DBUS_TYPE_DICT_ENTRY, nullptr, &item_iterator); + dbus_message_iter_open_container(&iter, DBUS_TYPE_DICT_ENTRY, nullptr, &item_iterator); - Serializer s1(&item_iterator); - Codec::encode(s1, p.first); - Codec::encode(s1, p.second); + Codec::encode(item_iterator, p.first); + Codec::encode(item_iterator, p.second); - dbus_message_iter_close_container(s.iter_, &item_iterator); + dbus_message_iter_close_container(&iter, &item_iterator); } static - void decode(Deserializer& s, std::pair& p) + void decode(DBusMessageIter& iter, std::pair& p) { DBusMessageIter item_iterator; - dbus_message_iter_recurse(s.iter_, &item_iterator); + dbus_message_iter_recurse(&iter, &item_iterator); - Deserializer s1(&item_iterator); - Codec::decode(s1, p.first); - Codec::decode(s1, p.second); + Codec::decode(item_iterator, p.first); + Codec::decode(item_iterator, p.second); // advance to next element - dbus_message_iter_next(s.iter_); + dbus_message_iter_next(&iter); } -}; - - -template -struct make_type_signature> -{ + + static inline - std::ostream& eval(std::ostream& os) + std::ostream& make_type_signature(std::ostream& os) { os << DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING; - make_type_signature::eval(os); - make_type_signature::eval(os); + + Codec::make_type_signature(os); + Codec::make_type_signature(os); + return os << DBUS_DICT_ENTRY_END_CHAR_AS_STRING; } }; -} // namespace detail - } // namespace dbus } // namespace simppl diff --git a/include/simppl/pod.h b/include/simppl/pod.h index 4bf65e4..361b841 100644 --- a/include/simppl/pod.h +++ b/include/simppl/pod.h @@ -1,58 +1,90 @@ +#ifndef __SIMPPL_DBUS_POD_H__ +#define __SIMPPL_DBUS_POD_H__ +#ifndef SIMPPL_SERIALIZATION_H +# error "Do not include this file manually. Use serialization.h instead." +#endif + + +namespace simppl +{ + +namespace dbus +{ + + +namespace detail +{ template -struct isPod +struct typecode_switch; + +template<> struct typecode_switch { enum { value = DBUS_TYPE_BYTE }; }; +template<> struct typecode_switch { enum { value = DBUS_TYPE_BYTE }; }; +template<> struct typecode_switch { enum { value = DBUS_TYPE_UINT16 }; }; +template<> struct typecode_switch { enum { value = DBUS_TYPE_UINT32 }; }; +//template<> struct dbus_type_code { enum { value = DBUS_TYPE_UINT64 }; }; +template<> struct typecode_switch { enum { value = DBUS_TYPE_UINT32 }; }; +template<> struct typecode_switch { enum { value = DBUS_TYPE_UINT64 }; }; +template<> struct typecode_switch { enum { value = DBUS_TYPE_BYTE }; }; +template<> struct typecode_switch { enum { value = DBUS_TYPE_INT16 }; }; +template<> struct typecode_switch { enum { value = DBUS_TYPE_INT32 }; }; +//template<> struct dbus_type_code { enum { value = DBUS_TYPE_INT64 }; }; +template<> struct typecode_switch { enum { value = DBUS_TYPE_INT32 }; }; +template<> struct typecode_switch { enum { value = DBUS_TYPE_INT64 }; }; +template<> struct typecode_switch { enum { value = DBUS_TYPE_DOUBLE }; }; + + +template +struct EnumTypeCodeHelper { - typedef make_typelist< - bool, - char, - signed char, - unsigned char, - short, - unsigned short, - int, - unsigned int, - long, - unsigned long, - long long, - unsigned long long, - float, - double>::type pod_types; - - enum { value = Find::value >= 0 }; + enum { value = DBUS_TYPE_INT32 }; }; - template - Deserializer& read(T& t, std::true_type) - { - dbus_message_iter_get_basic(iter_, &t); - dbus_message_iter_next(iter_); +struct EnumTypeCodeHelper +{ + enum { value = typecode_switch::value }; +}; - return *this; - } + +} // namespace detail - template - inline - Serializer& write(T t, Pod) +template +struct CodecImpl +{ + enum { dbus_type_code = detail::EnumTypeCodeHelper::value>::value }; + + static_assert(isPod::value || std::is_enum::value, "not a pod type"); + + + static inline + void encode(DBusMessageIter& iter, const T& t) + { + dbus_message_iter_append_basic(&iter, dbus_type_code, &t); + } + + + static inline + void decode(DBusMessageIter& iter, T& t) + { + dbus_message_iter_get_basic(&iter, &t); + dbus_message_iter_next(&iter); + } + + + static inline + std::ostream& make_type_signature(std::ostream& os) { - dbus_message_iter_append_basic(iter_, dbus_type_code::value, &t); - return *this; + return os << (char)dbus_type_code; } - +}; -template<> struct dbus_type_code { enum { value = DBUS_TYPE_BYTE }; }; -template<> struct dbus_type_code { enum { value = DBUS_TYPE_BYTE }; }; -template<> struct dbus_type_code { enum { value = DBUS_TYPE_UINT16 }; }; -template<> struct dbus_type_code { enum { value = DBUS_TYPE_UINT32 }; }; -//template<> struct dbus_type_code { enum { value = DBUS_TYPE_UINT64 }; }; -template<> struct dbus_type_code { enum { value = DBUS_TYPE_UINT32 }; }; -template<> struct dbus_type_code { enum { value = DBUS_TYPE_UINT64 }; }; -template<> struct dbus_type_code { enum { value = DBUS_TYPE_BYTE }; }; -template<> struct dbus_type_code { enum { value = DBUS_TYPE_INT16 }; }; -template<> struct dbus_type_code { enum { value = DBUS_TYPE_INT32 }; }; -//template<> struct dbus_type_code { enum { value = DBUS_TYPE_INT64 }; }; -template<> struct dbus_type_code { enum { value = DBUS_TYPE_INT32 }; }; -template<> struct dbus_type_code { enum { value = DBUS_TYPE_INT64 }; }; -template<> struct dbus_type_code { enum { value = DBUS_TYPE_DOUBLE }; }; + +} // namespace dbus + +} // namespace simppl + + +#endif // __SIMPPL_DBUS_POD_H__ diff --git a/include/simppl/property.h b/include/simppl/property.h index 5b0d7bf..183f8d4 100644 --- a/include/simppl/property.h +++ b/include/simppl/property.h @@ -24,9 +24,9 @@ namespace detail template inline -void serialize_property(Serializer& s, const T& t) +void serialize_property(DBusMessageIter& iter, const T& t) { - VariantSerializer vs(s); + VariantSerializer vs(iter); vs(t); } diff --git a/include/simppl/serialization.h b/include/simppl/serialization.h index da50a01..6c25f10 100644 --- a/include/simppl/serialization.h +++ b/include/simppl/serialization.h @@ -2,25 +2,124 @@ #define SIMPPL_SERIALIZATION_H -#include "simppl/detail/serialization.h" +#include + +#include + +#include "simppl/typelist.h" +#include "simppl/bool.h" namespace simppl { + + +// get const removed from pointer; std::remove_const is not sufficient +template struct remove_all_const : std::remove_const {}; + +template struct remove_all_const { + typedef typename remove_all_const::type *type; +}; + +template struct remove_all_const { + typedef typename remove_all_const::type *type; +}; + namespace dbus { -template -struct make_serializer + +template +struct isPod { - typedef typename make_typelist::type type__; - typedef typename detail::make_serializer_imp::type type; + typedef make_typelist< + char, + signed char, + unsigned char, + short, + unsigned short, + int, + unsigned int, + long, + unsigned long, + long long, + unsigned long long, + float, + double>::type pod_types; + + enum { value = Find::value >= 0 }; }; + +struct Pod; +struct Struct; + +template +struct CodecImpl; + + +// type switch +template +struct Codec +{ + typedef typename std::conditional::value || std::is_enum::value, Pod, Struct>::type deducer_type; + + typedef CodecImpl impl_type; + + enum { dbus_type_code = impl_type::dbus_type_code }; + + + static inline + void encode(DBusMessageIter& s, const T& t) + { + impl_type::encode(s, t); + } + + + static inline + void decode(DBusMessageIter& s, T& t) + { + impl_type::decode(s, t); + } + + + static inline + std::ostream& make_type_signature(std::ostream& os) + { + return impl_type::make_type_signature(os); + } +}; + + +namespace detail +{ + + +inline +void serialize(DBusMessageIter&) +{ + // NOOP +} + + +template +inline +void serialize(DBusMessageIter& iter, const T1& t1, const T&... t) +{ + Codec::type>::encode(iter, t1); + serialize(iter, t...); +} + + +} // namespace detail + } // namespace dbus } // namespace simppl -#endif // SIMPPL_SERIALIZATION_H \ No newline at end of file + +#include "simppl/pod.h" + +#endif // SIMPPL_SERIALIZATION_H diff --git a/include/simppl/serverside.h b/include/simppl/serverside.h index fdbbdb7..dcd808d 100644 --- a/include/simppl/serverside.h +++ b/include/simppl/serverside.h @@ -109,8 +109,8 @@ struct ServerSignal : ServerSignalBase void notify(typename CallTraits::param_type... args) { - parent_->send_signal(this->name_, [&](detail::Serializer& s){ - detail::serialize(s, args...); + parent_->send_signal(this->name_, [&](DBusMessageIter& iter){ + detail::serialize(iter, args...); }); } @@ -196,8 +196,10 @@ struct ServerMethod : ServerMethodBase static void __eval(ServerMethodBase* obj, DBusMessage* msg) { - detail::Deserializer d(msg); - detail::GetCaller::type::template eval(d, ((ServerMethod*)obj)->f_); + DBusMessageIter iter; + dbus_message_iter_init(msg, &iter); + + detail::GetCaller::type::template eval(iter, ((ServerMethod*)obj)->f_); } @@ -205,7 +207,7 @@ struct ServerMethod : ServerMethodBase inline detail::ServerResponseHolder __impl(std::true_type, const T&... t) { - return detail::ServerResponseHolder([&](detail::Serializer& s){ + return detail::ServerResponseHolder([&](DBusMessageIter& s){ serializer_type::eval(s, t...); }); } @@ -214,7 +216,7 @@ struct ServerMethod : ServerMethodBase inline detail::ServerResponseHolder __impl(std::false_type, const T&... t) { - return detail::ServerResponseHolder([](detail::Serializer& s){ /*NOOP*/ }); + return detail::ServerResponseHolder([](DBusMessageIter&){ /*NOOP*/ }); } }; @@ -225,7 +227,7 @@ struct ServerMethod : ServerMethodBase struct ServerPropertyBase { typedef void (*eval_type)(ServerPropertyBase*, DBusMessage*); - typedef void (*eval_set_type)(ServerPropertyBase*, detail::Deserializer&); + typedef void (*eval_set_type)(ServerPropertyBase*, DBusMessageIter&); ServerPropertyBase(const char* name, SkeletonBase* iface); @@ -234,9 +236,9 @@ struct ServerPropertyBase eval_(this, msg); } - void evalSet(detail::Deserializer& ds) + void evalSet(DBusMessageIter& iter) { - eval_set_(this, ds); + eval_set_(this, iter); } #if SIMPPL_HAVE_INTROSPECTION @@ -277,10 +279,11 @@ struct BaseProperty : ServerPropertyBase static void __eval(ServerPropertyBase* obj, DBusMessage* response) { - detail::Serializer s(response); + DBusMessageIter iter; + dbus_message_iter_init_append(response, &iter); Variant v(((BaseProperty*)obj)->t_); // FIXME this copy is overhead, just somehow wrap it... - serialize(s, v); + detail::serialize(iter, v); } protected: @@ -340,8 +343,8 @@ struct ServerProperty : BaseProperty, std::conditionalparent_->send_property_change(this->name_, [this](detail::Serializer& s){ - detail::serialize_property(s, this->t_); + this->parent_->send_property_change(this->name_, [this](DBusMessageIter& iter){ + detail::serialize_property(iter, this->t_); }); } } @@ -353,12 +356,12 @@ struct ServerProperty : BaseProperty, std::conditional v; - detail::Codec::decode(ds, v); + Codec::decode(iter, v); if (that->__set(*v.template get())) *that = *v.template get(); @@ -369,7 +372,7 @@ struct ServerProperty : BaseProperty, std::conditionalname_ << "\" type=\""; - detail::make_type_signature::eval(os); + Codec::make_type_signature(os); os << "\" access=\"" << (Flags & ReadWrite?"readwrite":"read") << "\"/>\n"; } #endif diff --git a/include/simppl/skeletonbase.h b/include/simppl/skeletonbase.h index 5b7113e..5b875db 100644 --- a/include/simppl/skeletonbase.h +++ b/include/simppl/skeletonbase.h @@ -77,9 +77,9 @@ struct SkeletonBase return busname_; } - void send_property_change(const char* prop, std::function&& f); + void send_property_change(const char* prop, std::function&& f); - void send_signal(const char* signame, std::function&& f); + void send_signal(const char* signame, std::function&& f); protected: diff --git a/include/simppl/string.h b/include/simppl/string.h index 346fc4b..9206d6a 100644 --- a/include/simppl/string.h +++ b/include/simppl/string.h @@ -4,82 +4,42 @@ #include +#include "simppl/serialization.h" + namespace simppl { namespace dbus { - -namespace detail -{ - -template<> -struct Codec + +struct StringCodec { static - void encode(Serializer& s, const std::string& str) - { - // FIXME - } + void encode(DBusMessageIter& s, const std::string& str); + static + void decode(DBusMessageIter& s, std::string& str); static - void decode(Deserializer& s, std::string& str) - { - // FIXME - } -}; - - - Serializer& write_ptr(const char* str); - - Serializer& write(const std::wstring& str); - Serializer& write_ptr(const wchar_t* str); - - - Deserializer& read(char*& str); - Deserializer& read(wchar_t*& str); - Deserializer& read(std::wstring& str); + void encode(DBusMessageIter& s, const char* str); - -template<> -struct make_type_signature -{ - static inline - std::ostream& eval(std::ostream& os) - { - return os << DBUS_TYPE_STRING_AS_STRING; - } + static + void decode(DBusMessageIter& s, char*& str); + + static + std::ostream& make_type_signature(std::ostream& os); }; - + template<> -struct make_type_signature -{ - static inline - std::ostream& eval(std::ostream& os) - { - return make_type_signature::eval(os << DBUS_TYPE_ARRAY_AS_STRING); - } -}; - +struct Codec : public StringCodec {}; template<> -struct make_type_signature -{ - static inline - std::ostream& eval(std::ostream& os) - { - return make_type_signature::eval(os << DBUS_TYPE_ARRAY_AS_STRING); - } -}; - +struct Codec : public StringCodec {}; -} // namespace detail - } // namespace dbus } // namespace simppl diff --git a/include/simppl/struct.h b/include/simppl/struct.h index fef95ef..0e04821 100644 --- a/include/simppl/struct.h +++ b/include/simppl/struct.h @@ -1,27 +1,39 @@ +#ifndef __SIMPPL_DBUS_STRUCT_H__ +#define __SIMPPL_DBUS_STRUCT_H__ + + +#include "simppl/serialization.h" + + +namespace simppl +{ + +namespace dbus +{ template struct SerializerTuple : T1 { - template - void write(SerializerT& s) const + void write(DBusMessageIter& iter) const { - T1::write(s); - s.write(data_); + T1::encode(iter); + Codec::encode(iter, data_); } - template - void read(DeserializerT& s) + + void read(DBusMessageIter& iter) { - T1::read(s); - s.read(data_); + T1::decode(iter); + Codec::decode(iter, data_); } + static - void write_signature(std::ostream& os) + void make_type_signature(std::ostream& os) { - T1::write_signature(os); - make_type_signature::eval(os); + T1::make_type_signature(os); + Codec::make_type_signature(os); } T2 data_; @@ -31,167 +43,120 @@ struct SerializerTuple : T1 template struct SerializerTuple { - template - void write(SerializerT& s) const + void encode(DBusMessageIter& iter) const { - s.write(data_); + Codec::encode(iter, data_); } - template - void read(DeserializerT& s) + void decode(DBusMessageIter& iter) { - s.read(data_); + Codec::decode(iter, data_); } + static - void write_signature(std::ostream& os) + void make_type_signature(std::ostream& os) { - make_type_signature::eval(os); + Codec::make_type_signature(os); } T data_; }; -template -struct StructSerializationHelper +template +struct Codec> { - template - static inline - void write(SerializerT& s, const StructT& st) + static + void encode(DBusMessageIter& iter, const SerializerTuple& tuple) { - const typename StructT::serializer_type& tuple = *(const typename StructT::serializer_type*)&st; - s.write(tuple); - } + DBusMessageIter _iter; + dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, nullptr, &_iter); - template - static inline - void read(DeserializerT& s, StructT& st) - { - typename StructT::serializer_type& tuple = *(typename StructT::serializer_type*)&st; - s.read(tuple); + tuple.encode(_iter); + + dbus_message_iter_close_container(&iter, &_iter); } -}; -#ifdef SIMPPL_HAVE_BOOST_FUSION -template -struct FusionWriter -{ - explicit inline - FusionWriter(SerializerT& s) - : s_(s) + // FIXME move this out in order to avoid inlining + static + void decode(DBusMessageIter& iter, SerializerTuple& tuple) { - // NOOP - } + DBusMessageIter _iter; + dbus_message_iter_recurse(&iter, &_iter); - template - inline - void operator()(const T& t) const - { - s_.write(t); - } + tuple.decode(_iter); - SerializerT& s_; + dbus_message_iter_next(&iter); + } }; -template -struct FusionReader +template +struct CodecImpl { - explicit inline - FusionReader(DeserializerT& s) - : s_(s) - { - // NOOP - } - - template - inline - void operator()(T& t) const + // unused! + enum { dbus_type_code = 'X' }; + + typedef typename T::serializer_type s_type; + + static + void encode(DBusMessageIter& iter, const T& st) { - s_.read(t); + const s_type& tuple = *(s_type*)&st; + Codec::encode(iter, tuple); } - DeserializerT& s_; -}; - -template<> -struct StructSerializationHelper -{ - template - static inline - void write(SerializerT& s, const StructT& st) + static + void decode(DBusMessageIter& iter, T& st) { - boost::fusion::for_each(st, FusionWriter(s)); + s_type& tuple = *(s_type*)&st; + Codec::decode(iter, tuple); } - template + static inline - void read(DeserializerT& s, StructT& st) + std::ostream& make_type_signature(std::ostream& os) { - boost::fusion::for_each(st, FusionReader(s)); + T::serializer_type::make_type_signature(os << DBUS_STRUCT_BEGIN_CHAR_AS_STRING); + return os << DBUS_STRUCT_END_CHAR_AS_STRING; } }; -#endif - -template - inline - Serializer& write(const T& t, Struct) - { - StructSerializationHelper< -#ifdef SIMPPL_HAVE_BOOST_FUSION - typename boost::fusion::traits::is_sequence::type -#else - int -#endif - >::template write(*this, t); - - return *this; - } +namespace detail +{ + template + struct make_serializer_imp; - template - Serializer& write(const SerializerTuple& tuple) + template + struct make_serializer_imp > { - DBusMessageIter iter; - dbus_message_iter_open_container(iter_, DBUS_TYPE_STRUCT, nullptr, &iter); + typedef SerializerTuple::type> >::type, typename Back::type> type; + }; - Serializer sub(&iter); - tuple.write(sub); - - dbus_message_iter_close_container(iter_, &iter); - - return *this; - } + template + struct make_serializer_imp > + { + typedef SerializerTuple type; + }; + +} // namespace detail -template - Deserializer& read(T& t, std::false_type) - { - StructSerializationHelper< -#ifdef SIMPPL_HAVE_BOOST_FUSION - typename boost::fusion::traits::is_sequence::type -#else - int -#endif - >::template read(*this, t); - return *this; - } +template +struct make_serializer +{ + typedef typename make_typelist::type type__; + typedef typename detail::make_serializer_imp::type type; +}; - template - Deserializer& read(SerializerTuple& tuple) - { - DBusMessageIter iter; - dbus_message_iter_recurse(iter_, &iter); +} // namespace dbus - Deserializer sub(&iter); - tuple.read(sub); +} // namespace simppl - dbus_message_iter_next(iter_); - return *this; - } +#endif // __SIMPPL_DBUS_STRUCT_H__ diff --git a/include/simppl/stubbase.h b/include/simppl/stubbase.h index 521f44c..eb94d17 100644 --- a/include/simppl/stubbase.h +++ b/include/simppl/stubbase.h @@ -25,12 +25,6 @@ namespace dbus struct Dispatcher; struct ClientSignalBase; -namespace detail -{ - struct Serializer; - struct Deserializer; -} - struct StubBase { @@ -96,14 +90,14 @@ struct StubBase void cleanup(); - PendingCall send_request(const char* method_name, std::function&& f, bool is_oneway); + PendingCall send_request(const char* method_name, std::function&& f, bool is_oneway); - message_ptr_t send_request_and_block(const char* method_name, std::function&& f, bool is_oneway); + message_ptr_t send_request_and_block(const char* method_name, std::function&& f, bool is_oneway); void register_signal(ClientSignalBase& sigbase); void unregister_signal(ClientSignalBase& sigbase); - void attach_property(const char* name, std::function&& f); + void attach_property(const char* name, std::function&& f); void detach_property(const char* name); /** @@ -116,9 +110,9 @@ struct StubBase /** * Blocking call. */ - void set_property(const char* Name, std::function&& f); + void set_property(const char* Name, std::function&& f); - PendingCall set_property_async(const char* Name, std::function&& f); + PendingCall set_property_async(const char* Name, std::function&& f); char* iface_; char* objectpath_; @@ -129,7 +123,7 @@ struct StubBase // FIXME use linked lists instead of map... std::map signals_; - std::map> properties_; + std::map> properties_; }; } // namespace dbus diff --git a/include/simppl/tuple.h b/include/simppl/tuple.h index 6c5e364..588d418 100644 --- a/include/simppl/tuple.h +++ b/include/simppl/tuple.h @@ -4,6 +4,9 @@ #include +#include "simppl/serialization.h" +#include "simppl/for_each.h" + namespace simppl { @@ -16,102 +19,96 @@ namespace detail // FIXME remove this in favour of lambda expression! -template struct TupleSerializer // : noncopable { inline - TupleSerializer(SerializerT& s) - : orig_(s) - , s_(&iter_) + TupleSerializer(DBusMessageIter& iter) + : orig_(iter) { - dbus_message_iter_open_container(orig_.iter_, DBUS_TYPE_STRUCT, nullptr, &iter_); + dbus_message_iter_open_container(&orig_, DBUS_TYPE_STRUCT, nullptr, &iter_); } + inline ~TupleSerializer() { - dbus_message_iter_close_container(orig_.iter_, &iter_); + dbus_message_iter_close_container(&orig_, &iter_); } + template void operator()(const T& t); - SerializerT& orig_; - SerializerT s_; + + DBusMessageIter& orig_; DBusMessageIter iter_; }; -template struct TupleDeserializer // : noncopable { inline - TupleDeserializer(DeserializerT& s, bool flattened = false) - : orig_(s) - , s_(flattened?orig_.iter_:&iter_) + TupleDeserializer(DBusMessageIter& iter, bool flattened = false) + : orig_(iter) + , use_(flattened?&orig_:&iter_) , flattened_(flattened) { if (!flattened) - dbus_message_iter_recurse(orig_.iter_, &iter_); + dbus_message_iter_recurse(&orig_, &iter_); } ~TupleDeserializer() { if (!flattened_) - dbus_message_iter_next(orig_.iter_); + dbus_message_iter_next(&orig_); } template void operator()(T& t); - DeserializerT& orig_; - DeserializerT s_; + + DBusMessageIter& orig_; DBusMessageIter iter_; + + DBusMessageIter* use_; + bool flattened_; }; + +} // namespace detail + template struct Codec> { + enum { dbus_type_code = DBUS_TYPE_STRUCT }; + + static - void encode(Serializer& s, const std::tuple& t) + void encode(DBusMessageIter& iter, const std::tuple& t) { - TupleSerializer ts(s); + detail::TupleSerializer ts(iter); std_tuple_for_each(t, std::ref(ts)); } static - void decode(Deserializer& s, std::tuple& t) + void decode(DBusMessageIter& iter, std::tuple& t) { - TupleDeserializer tds(s); + detail::TupleDeserializer tds(iter); std_tuple_for_each(t, std::ref(tds)); } -}; - - -template -template -inline -void TupleDeserializer::operator()(T& t) -{ - Codec::decode(s_, t); -} - - -template -template -inline -void TupleSerializer::operator()(const T& t) // seems to be already a reference so no copy is done -{ - Codec::encode(s_, t); -} - - -template -struct make_type_signature> -{ + + + static + void decode_flattened(DBusMessageIter& iter, std::tuple& t) + { + detail::TupleDeserializer tds(iter, true); + std_tuple_for_each(t, std::ref(tds)); + } + + // if templated lambdas are available this could be removed! struct helper { @@ -124,18 +121,21 @@ struct make_type_signature> template void operator()(const U&) { - make_type_signature::eval(os_); + Codec::make_type_signature(os_); } std::ostream& os_; }; - static inline - std::ostream& eval(std::ostream& os) + + static + std::ostream& make_type_signature(std::ostream& os) { os << DBUS_STRUCT_BEGIN_CHAR_AS_STRING; + std::tuple t; // FIXME make this a type based version only, no value based iteration std_tuple_for_each(t, helper(os)); + os << DBUS_STRUCT_END_CHAR_AS_STRING; return os; @@ -143,12 +143,22 @@ struct make_type_signature> }; -template -struct dbus_type_code> { enum { value = DBUS_TYPE_STRUCT }; }; +template +inline +void detail::TupleDeserializer::operator()(T& t) +{ + Codec::decode(*use_, t); +} - -} // namespace detail +template +inline +void detail::TupleSerializer::operator()(const T& t) // seems to be already a reference so no copy is done +{ + Codec::encode(iter_, t); +} + + } // namespace dbus } // namespace simppl diff --git a/include/simppl/variant.h b/include/simppl/variant.h index 4fbf7cd..ad2d1ca 100644 --- a/include/simppl/variant.h +++ b/include/simppl/variant.h @@ -3,8 +3,11 @@ #include "simppl/typelist.h" +#include "simppl/serialization.h" #include +#include +#include namespace simppl @@ -366,6 +369,7 @@ Variant& Variant::operator=(const Variant& rhs) return *this; } + namespace dbus { @@ -373,12 +377,11 @@ namespace detail { -template struct VariantSerializer : StaticVisitor<> { inline - VariantSerializer(SerializerT& s) - : orig_(s) + VariantSerializer(DBusMessageIter& iter) + : iter_(iter) { // NOOP } @@ -386,39 +389,32 @@ struct VariantSerializer : StaticVisitor<> template void operator()(const T& t); - SerializerT& orig_; + DBusMessageIter& iter_; }; -// FIXME remove forward decls -template -struct make_type_signature; - -template -struct Codec; - - template struct VariantDeserializer; template struct VariantDeserializer { - template - static bool eval(DeserializerT& s, VariantT& v, const char* sig) + template + static + bool eval(DBusMessageIter& iter, VariantT& v, const char* sig) { std::ostringstream buf; - make_type_signature::eval(buf); + Codec::make_type_signature(buf); if (!strcmp(buf.str().c_str(), sig)) { v = T1(); - s.read(*v.template get()); + Codec::decode(iter, *v.template get()); return true; } else - return VariantDeserializer::eval(s, v, sig); + return VariantDeserializer::eval(iter, v, sig); } }; @@ -426,16 +422,17 @@ struct VariantDeserializer template struct VariantDeserializer { - template - static bool eval(DeserializerT& s, VariantT& v, const char* sig) + template + static + bool eval(DBusMessageIter& iter, VariantT& v, const char* sig) { std::ostringstream buf; - make_type_signature::eval(buf); + Codec::make_type_signature(buf); if (!strcmp(buf.str().c_str(), sig)) { v = T(); - s.read(*v.template get()); + Codec::decode(iter, *v.template get()); return true; } @@ -446,79 +443,72 @@ struct VariantDeserializer }; -template -bool try_deserialize(DeserializerT& d, Variant& v, const char* sig); +template +bool try_deserialize(DBusMessageIter& iter, Variant& v, const char* sig); + + +} // namespace detail template struct Codec> { + enum { dbus_type_code = DBUS_TYPE_VARIANT }; + + static - void encode(Serializer& s, const Variant& v) + void encode(DBusMessageIter& iter, const Variant& v) { - VariantSerializer vs(s); - staticVisit(vs, const_cast&>(v)); // FIXME need const visitor + detail::VariantSerializer vs(iter); + staticVisit(vs, const_cast&>(v)); // TODO need const visitor } static - void decode(Deserializer& s, Variant& v) + void decode(DBusMessageIter& orig, Variant& v) { DBusMessageIter iter; - dbus_message_iter_recurse(s.iter_, &iter); - Deserializer s1(&iter); + dbus_message_iter_recurse(&orig, &iter); - if (!try_deserialize(s1, v, dbus_message_iter_get_signature(&iter))) + if (!detail::try_deserialize(iter, v, dbus_message_iter_get_signature(&iter))) assert(false); - dbus_message_iter_next(s.iter_); + dbus_message_iter_next(&orig); + } + + + static inline + std::ostream& make_type_signature(std::ostream& os) + { + return os << DBUS_TYPE_VARIANT_AS_STRING; } }; -template -bool try_deserialize(DeserializerT& d, Variant& v, const char* sig) +template +bool detail::try_deserialize(DBusMessageIter& iter, Variant& v, const char* sig) { - return VariantDeserializer::eval(d, v, sig); + return VariantDeserializer::eval(iter, v, sig); } -template template inline -void VariantSerializer::operator()(const T& t) // seems to be already a reference so no copy is done +void detail::VariantSerializer::operator()(const T& t) // seems to be already a reference so no copy is done { std::ostringstream buf; - make_type_signature::eval(buf); + Codec::make_type_signature(buf); DBusMessageIter iter; - dbus_message_iter_open_container(orig_.iter_, DBUS_TYPE_VARIANT, buf.str().c_str(), &iter); + dbus_message_iter_open_container(&iter_, DBUS_TYPE_VARIANT, buf.str().c_str(), &iter); - SerializerT s(&iter); - Codec::encode(s, t); + Codec::encode(iter, t); - dbus_message_iter_close_container(orig_.iter_, &iter); + dbus_message_iter_close_container(&iter_, &iter); } -template -struct make_type_signature> -{ - static inline - std::ostream& eval(std::ostream& os) - { - return os << DBUS_TYPE_VARIANT_AS_STRING; - } -}; - - -template -struct dbus_type_code> { enum { value = DBUS_TYPE_VARIANT }; }; - - -} - -} +} // namespace dbus } // namespace simppl diff --git a/include/simppl/vector.h b/include/simppl/vector.h index 2b8717a..4a321e1 100644 --- a/include/simppl/vector.h +++ b/include/simppl/vector.h @@ -4,74 +4,67 @@ #include +#include "simppl/serialization.h" + namespace simppl { namespace dbus { - -namespace detail -{ - + template struct Codec> { static - void encode(Serializer& s, const std::vector& v) + void encode(DBusMessageIter& s, const std::vector& v) { DBusMessageIter iter; + std::ostringstream buf; - make_type_signature::eval(buf); + Codec::make_type_signature(buf); - dbus_message_iter_open_container(s.iter_, DBUS_TYPE_ARRAY, buf.str().c_str(), &iter); + dbus_message_iter_open_container(&s, DBUS_TYPE_ARRAY, buf.str().c_str(), &iter); - Serializer s1(&iter); - for (auto& t : v) { - Codec::encode(s1, t); + for (auto& t : v) + { + Codec::encode(iter, t); } - dbus_message_iter_close_container(s.iter_, &iter); + dbus_message_iter_close_container(&s, &iter); } static - void decode(Deserializer& s, std::vector& v) + void decode(DBusMessageIter& s, std::vector& v) { v.clear(); DBusMessageIter iter; - dbus_message_iter_recurse(s.iter_, &iter); - - Deserializer ds(&iter); + dbus_message_iter_recurse(&s, &iter); while(dbus_message_iter_get_arg_type(&iter) != 0) { T t; - Codec::decode(ds, t); + Codec::decode(iter, t); v.push_back(t); } // advance to next element - dbus_message_iter_next(s.iter_); + dbus_message_iter_next(&s); } -}; - - -template -struct make_type_signature> -{ + + static inline - std::ostream& eval(std::ostream& os) + std::ostream& make_type_signature(std::ostream& os) { - return make_type_signature::eval(os << DBUS_TYPE_ARRAY_AS_STRING); + return Codec::make_type_signature(os << DBUS_TYPE_ARRAY_AS_STRING); } + }; -} // namespace detail - } // namespace dbus } // namespace simppl diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e6030f2..436131c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,11 +6,15 @@ add_library(simppl SHARED skeletonbase.cpp serverside.cpp stubbase.cpp - serialization.cpp + #serialization.cpp timeout.cpp util.cpp serverrequestdescriptor.cpp - pendingcall.cpp) + pendingcall.cpp + string.cpp + wstring.cpp + objectpath.cpp +) target_link_libraries(simppl dbus-1) diff --git a/src/dispatcher.cpp b/src/dispatcher.cpp index 4f58bbc..f3d4b3c 100644 --- a/src/dispatcher.cpp +++ b/src/dispatcher.cpp @@ -13,7 +13,8 @@ #include "simppl/detail/util.h" #include "simppl/timeout.h" #include "simppl/skeletonbase.h" -#include "simppl/serialization.h" +#include "simppl/string.h" +#include "simppl/vector.h" #define SIMPPL_DISPATCHER_CPP #include "simppl/serverside.h" @@ -446,8 +447,9 @@ void Dispatcher::init(int have_introspection, const char* busname) std::vector busnames; - detail::Deserializer ds(reply); - detail::Codec>::decode(ds, busnames); + DBusMessageIter iter; + dbus_message_iter_init(reply, &iter); + Codec>::decode(iter, busnames); for(auto& busname : busnames) { @@ -586,8 +588,10 @@ DBusHandlerResult Dispatcher::try_handle_signal(DBusMessage* msg) { std::string busname; - detail::Deserializer ds(msg); - detail::Codec::decode(ds, busname); + DBusMessageIter iter; + dbus_message_iter_init(msg, &iter); + + Codec::decode(iter, busname); if (d->busnames_.find(busname) != d->busnames_.end()) notify_clients(busname, ConnectionState::Connected); @@ -600,10 +604,12 @@ DBusHandlerResult Dispatcher::try_handle_signal(DBusMessage* msg) std::string old_name; std::string new_name; - detail::Deserializer ds(msg); - detail::Codec::decode(ds, bus_name); - detail::Codec::decode(ds, old_name); - detail::Codec::decode(ds, new_name); + DBusMessageIter iter; + dbus_message_iter_init(msg, &iter); + + Codec::decode(iter, bus_name); + Codec::decode(iter, old_name); + Codec::decode(iter, new_name); if (bus_name[0] != ':') { @@ -677,8 +683,10 @@ void Dispatcher::add_client(StubBase& clnt) DBusMessage* msg = dbus_message_new_signal(objpath.str().c_str(), "org.simppl.dispatcher", "notify_client"); - detail::Serializer s(msg); - serialize(s, clnt.busname()); + DBusMessageIter iter; + dbus_message_iter_init_append(msg, &iter); + + detail::serialize(iter, clnt.busname()); dbus_connection_send(conn_, msg, nullptr); dbus_message_unref(msg); diff --git a/src/error.cpp b/src/error.cpp index 262e117..ca43799 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -3,7 +3,7 @@ #include #include -#include "simppl/serialization.h" +#include "simppl/string.h" namespace simppl @@ -23,11 +23,12 @@ std::unique_ptr Error::from_error(const DBusError& err) /*static*/ std::unique_ptr Error::from_message(DBusMessage& msg) { + DBusMessageIter iter; + dbus_message_iter_init(&msg, &iter); + std::string text; - detail::Deserializer d(&msg); - detail::Codec::decode(d, text); + Codec::decode(iter, text); - return std::unique_ptr(new Error(dbus_message_get_error_name(&msg), text.c_str(), dbus_message_get_reply_serial(&msg))); } diff --git a/src/serialization.cpp b/src/serialization.cpp index 6dbbf6a..02dc73e 100644 --- a/src/serialization.cpp +++ b/src/serialization.cpp @@ -1,4 +1,4 @@ -#include "simppl/detail/serialization.h" +//#include "simppl/detail/serialization.h" namespace simppl @@ -23,8 +23,6 @@ detail::Serializer::Serializer(DBusMessageIter* iter) #if 0 detail::Serializer& detail::Serializer::write(const std::string& str) { - char* c_str = const_cast(str.c_str()); - dbus_message_iter_append_basic(iter_, DBUS_TYPE_STRING, &c_str); return *this; } #endif @@ -33,53 +31,26 @@ detail::Serializer& detail::Serializer::write(const std::string& str) // FIXME maybe we don't need it at all. Write a test to verify... detail::Serializer& detail::Serializer::write_ptr(const char* str) { - char* c_str = const_cast(str); - dbus_message_iter_append_basic(iter_, DBUS_TYPE_STRING, &c_str); return *this; } detail::Serializer& detail::Serializer::write(const std::wstring& str) { - static_assert(sizeof(uint32_t) == sizeof(wchar_t), "data types mapping does not match"); - DBusMessageIter iter; - - dbus_message_iter_open_container(iter_, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32_AS_STRING, &iter); - - Serializer s(&iter); - for (auto& t : str) { - s.write((uint32_t)t); - } - - dbus_message_iter_close_container(iter_, &iter); - return *this; } detail::Serializer& detail::Serializer::write_ptr(const wchar_t* str) { - DBusMessageIter iter; - dbus_message_iter_open_container(iter_, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32_AS_STRING, &iter); - - Serializer s(&iter); - - while(str && *str) { - s.write((uint32_t)*str++); - } - - dbus_message_iter_close_container(iter_, &iter); - return *this; } detail::Serializer& detail::Serializer::write(const ObjectPath& p) { - char* c_str = const_cast(p.path.c_str()); - dbus_message_iter_append_basic(iter_, DBUS_TYPE_OBJECT_PATH, &c_str); return *this; } @@ -103,126 +74,35 @@ detail::Deserializer::Deserializer(DBusMessageIter* iter) detail::Deserializer& detail::Deserializer::read(char*& str) { - assert(str == nullptr); // we allocate the string via Deserializer::alloc -> free with Deserializer::free - - char* c_str = nullptr; - dbus_message_iter_get_basic(iter_, &c_str); - dbus_message_iter_next(iter_); - - if (c_str) - { - str = (char*)allocate(strlen(c_str)+1); - strcpy(str, c_str); - } - + return *this; } #if 0 detail::Deserializer& detail::Deserializer::read(std::string& str) { - char* c_str = nullptr; - dbus_message_iter_get_basic(iter_, &c_str); - dbus_message_iter_next(iter_); - - if (c_str) - { - str.assign(c_str); - } - else - str.clear(); - + return *this; } #endif detail::Deserializer& detail::Deserializer::read(wchar_t*& str) { - wchar_t* c_str = nullptr; - - //assert(str == nullptr); // we allocate the string via Deserializer::alloc -> free with Deserializer::free - - DBusMessageIter iter; - dbus_message_iter_recurse(iter_, &iter); - - int count = -#if DBUS_MAJOR_VERSION == 1 && DBUS_MINOR_VERSION < 7 - dbus_message_iter_get_array_len(&iter) / sizeof(uint32_t); -#else - dbus_message_iter_get_element_count(iter_); -#endif - if (count > 0) - { - c_str = (wchar_t*)allocate((count+1) * sizeof(wchar_t)); - c_str[count] = 0; - - Deserializer s(&iter); - - int i = 0; - while(dbus_message_iter_get_arg_type(&iter) != 0) - { - uint32_t t; - s.read(t); - c_str[i++] = (wchar_t)t; - } - - str = c_str; - } - else - str = nullptr; - - // advance to next element - dbus_message_iter_next(iter_); - + return *this; } detail::Deserializer& detail::Deserializer::read(std::wstring& str) { - str.clear(); - - DBusMessageIter iter; - dbus_message_iter_recurse(iter_, &iter); - int count = -#if DBUS_MAJOR_VERSION == 1 && DBUS_MINOR_VERSION < 7 - dbus_message_iter_get_array_len(&iter) / sizeof(uint32_t); -#else - dbus_message_iter_get_element_count(iter_); -#endif - if (count > 0) - str.reserve(count); - - Deserializer s(&iter); - - while(dbus_message_iter_get_arg_type(&iter) != 0) - { - uint32_t t; - s.read(t); - str.push_back((wchar_t)t); - } - - // advance to next element - dbus_message_iter_next(iter_); - return *this; } detail::Deserializer& detail::Deserializer::read(ObjectPath& p) { - char* c_str = nullptr; - dbus_message_iter_get_basic(iter_, &c_str); - dbus_message_iter_next(iter_); - - if (c_str) - { - p.path.assign(c_str); - } - else - p.path.clear(); - + return *this; } diff --git a/src/serverresponseholder.cpp b/src/serverresponseholder.cpp index 15d8a99..84863c4 100644 --- a/src/serverresponseholder.cpp +++ b/src/serverresponseholder.cpp @@ -1,7 +1,5 @@ #include "simppl/detail/serverresponseholder.h" -#include "simppl/detail/serialization.h" - namespace simppl { @@ -12,7 +10,7 @@ namespace dbus namespace detail { -ServerResponseHolder::ServerResponseHolder(std::function f) +ServerResponseHolder::ServerResponseHolder(std::function f) : f_(f) { // NOOP diff --git a/src/serverside.cpp b/src/serverside.cpp index 4279873..504a706 100644 --- a/src/serverside.cpp +++ b/src/serverside.cpp @@ -1,4 +1,3 @@ -#include "simppl/detail/serialization.h" #include "simppl/interface.h" #define SIMPPL_SERVERSIDE_CPP diff --git a/src/skeletonbase.cpp b/src/skeletonbase.cpp index e8b2046..d2f7c15 100644 --- a/src/skeletonbase.cpp +++ b/src/skeletonbase.cpp @@ -2,6 +2,8 @@ #include "simppl/dispatcher.h" #include "simppl/interface.h" +#include "simppl/string.h" +#include "simppl/vector.h" #define SIMPPL_SKELETONBASE_CPP #include "simppl/serverside.h" @@ -105,8 +107,10 @@ void SkeletonBase::respond_with(detail::ServerResponseHolder response) if (response.f_) { - detail::Serializer s(rmsg.get()); - response.f_(s); + DBusMessageIter iter; + dbus_message_iter_init_append(rmsg.get(), &iter); + + response.f_(iter); } dbus_connection_send(disp_->conn_, rmsg.get(), nullptr); @@ -124,8 +128,10 @@ void SkeletonBase::respond_on(ServerRequestDescriptor& req, detail::ServerRespon if (response.f_) { - detail::Serializer s(rmsg.get()); - response.f_(s); + DBusMessageIter iter; + dbus_message_iter_init_append(rmsg.get(), &iter); + + response.f_(iter); } dbus_connection_send(disp_->conn_, rmsg.get(), nullptr); @@ -236,9 +242,11 @@ DBusHandlerResult SkeletonBase::handle_request(DBusMessage* msg) DBusMessage* reply = dbus_message_new_method_return(msg); - detail::Serializer s(reply); - detail::Codec::encode(s, oss.str()); - + DBusMessageIter iter; + dbus_message_iter_init_append(reply, &iter); + + detail::serialize(iter, oss.str()); + dbus_connection_send(disp_->conn_, reply, nullptr); return DBUS_HANDLER_RESULT_HANDLED; @@ -254,9 +262,11 @@ DBusHandlerResult SkeletonBase::handle_request(DBusMessage* msg) std::string interface; std::string attribute; - detail::Deserializer ds(msg); - detail::Codec::decode(ds, interface); - detail::Codec::decode(ds, attribute); + DBusMessageIter iter; + dbus_message_iter_init(msg, &iter); + + Codec::decode(iter, interface); + Codec::decode(iter, attribute); while(p) { @@ -275,7 +285,7 @@ DBusHandlerResult SkeletonBase::handle_request(DBusMessage* msg) try { - p->evalSet(ds); + p->evalSet(iter); response = make_message(dbus_message_new_method_return(msg)); } @@ -340,26 +350,30 @@ DBusHandlerResult SkeletonBase::handle_request(DBusMessage* msg) } -void SkeletonBase::send_signal(const char* signame, std::function&& f) +void SkeletonBase::send_signal(const char* signame, std::function&& f) { message_ptr_t msg = make_message(dbus_message_new_signal(objectpath(), iface(), signame)); - detail::Serializer s(msg.get()); - f(s); + DBusMessageIter iter; + dbus_message_iter_init_append(msg.get(), &iter); + + f(iter); dbus_connection_send(disp_->conn_, msg.get(), nullptr); } -void SkeletonBase::send_property_change(const char* prop, std::function&& f) +void SkeletonBase::send_property_change(const char* prop, std::function&& f) { static std::vector invalid; message_ptr_t msg = make_message(dbus_message_new_signal(objectpath(), "org.freedesktop.DBus.Properties", "PropertiesChanged")); - detail::Serializer s(msg.get()); - s.write(iface()); - + DBusMessageIter iter; + dbus_message_iter_init_append(msg.get(), &iter); + + detail::serialize(iter, iface()); + // TODO make once std::ostringstream buf; buf << DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING @@ -367,22 +381,21 @@ void SkeletonBase::send_property_change(const char* prop, std::function>::encode(s, invalid); + dbus_message_iter_close_container(&iter, &vec_iter); + detail::serialize(iter, invalid); dbus_connection_send(disp_->conn_, msg.get(), nullptr); } diff --git a/src/stubbase.cpp b/src/stubbase.cpp index 3665640..9f4996d 100644 --- a/src/stubbase.cpp +++ b/src/stubbase.cpp @@ -1,6 +1,7 @@ #include "simppl/stub.h" #include "simppl/dispatcher.h" +#include "simppl/string.h" #include "simppl/detail/util.h" #include "simppl/clientside.h" @@ -85,13 +86,15 @@ Dispatcher& StubBase::disp() } -PendingCall StubBase::send_request(const char* method_name, std::function&& f, bool is_oneway) +PendingCall StubBase::send_request(const char* method_name, std::function&& f, bool is_oneway) { message_ptr_t msg = make_message(dbus_message_new_method_call(busname().c_str(), objectpath(), iface(), method_name)); DBusPendingCall* pending = nullptr; - detail::Serializer s(msg.get()); - f(s); + DBusMessageIter iter; + dbus_message_iter_init_append(msg.get(), &iter); + + f(iter); if (!is_oneway) { @@ -117,14 +120,16 @@ PendingCall StubBase::send_request(const char* method_name, std::function&& f, bool is_oneway) +message_ptr_t StubBase::send_request_and_block(const char* method_name, std::function&& f, bool is_oneway) { message_ptr_t msg = make_message(dbus_message_new_method_call(busname().c_str(), objectpath(), iface(), method_name)); DBusPendingCall* pending = nullptr; message_ptr_t rc(nullptr, &dbus_message_unref); - detail::Serializer s(msg.get()); - f(s); + DBusMessageIter iter; + dbus_message_iter_init_append(msg.get(), &iter); + + f(iter); if (!is_oneway) { @@ -198,7 +203,7 @@ void StubBase::unregister_signal(ClientSignalBase& sigbase) } -void StubBase::attach_property(const char* name, std::function&& f) +void StubBase::attach_property(const char* name, std::function&& f) { assert(disp_); @@ -245,8 +250,10 @@ PendingCall StubBase::get_property_async(const char* name) message_ptr_t msg = make_message(dbus_message_new_method_call(busname().c_str(), objectpath(), "org.freedesktop.DBus.Properties", "Get")); DBusPendingCall* pending = nullptr; - detail::Serializer s(msg.get()); - s.write(iface()).write(name); + DBusMessageIter iter; + dbus_message_iter_init_append(msg.get(), &iter); + + detail::serialize(iter, iface(), name); dbus_connection_send_with_reply(conn(), msg.get(), &pending, DBUS_TIMEOUT_USE_DEFAULT); @@ -259,8 +266,10 @@ message_ptr_t StubBase::get_property(const char* name) message_ptr_t msg = make_message(dbus_message_new_method_call(busname().c_str(), objectpath(), "org.freedesktop.DBus.Properties", "Get")); DBusPendingCall* pending = nullptr; - detail::Serializer s(msg.get()); - s.write(iface()).write(name); + DBusMessageIter iter; + dbus_message_iter_init_append(msg.get(), &iter); + + detail::serialize(iter, iface(), name); dbus_connection_send_with_reply(conn(), msg.get(), &pending, DBUS_TIMEOUT_USE_DEFAULT); @@ -273,13 +282,16 @@ message_ptr_t StubBase::get_property(const char* name) } -void StubBase::set_property(const char* name, std::function&& f) +void StubBase::set_property(const char* name, std::function&& f) { message_ptr_t msg = make_message(dbus_message_new_method_call(busname().c_str(), objectpath(), "org.freedesktop.DBus.Properties", "Set")); - detail::Serializer s(msg.get()); - s.write(iface()).write(name); - f(s); // and now serialize the variant + DBusMessageIter iter; + dbus_message_iter_init_append(msg.get(), &iter); + + detail::serialize(iter, iface(), name); + + f(iter); // and now serialize the variant DBusError err; dbus_error_init(&err); @@ -301,13 +313,15 @@ void StubBase::set_property(const char* name, std::function&& f) +PendingCall StubBase::set_property_async(const char* name, std::function&& f) { message_ptr_t msg = make_message(dbus_message_new_method_call(busname().c_str(), objectpath(), "org.freedesktop.DBus.Properties", "Set")); - detail::Serializer s(msg.get()); - s.write(iface()).write(name); - f(s); // and now serialize the variant + DBusMessageIter iter; + dbus_message_iter_init_append(msg.get(), &iter); + + detail::serialize(iter, iface(), name); + f(iter); // and now serialize the variant DBusPendingCall* pending = nullptr; @@ -322,28 +336,27 @@ void StubBase::try_handle_signal(DBusMessage* msg) // FIXME better check -> include interface! if (!strcmp(dbus_message_get_member(msg), "PropertiesChanged")) { - detail::Deserializer d(msg); + DBusMessageIter it; + dbus_message_iter_init(msg, &it); std::string iface; - detail::Codec::decode(d, iface); + Codec::decode(it, iface); // ignore interface name for now DBusMessageIter iter; - dbus_message_iter_recurse(d.iter_, &iter); + dbus_message_iter_recurse(&it, &iter); while(dbus_message_iter_get_arg_type(&iter) != 0) { DBusMessageIter item_iterator; dbus_message_iter_recurse(&iter, &item_iterator); - detail::Deserializer s(&item_iterator); - std::string property_name; - detail::Codec::decode(s, property_name); + Codec::decode(item_iterator, property_name); auto found = properties_.find(property_name); if (found != properties_.end()) - found->second(s); + found->second(item_iterator); // advance to next element dbus_message_iter_next(&iter); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 30da800..b9c74a6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,12 +10,12 @@ include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) add_executable(unittests - #timeout.cpp - #simple.cpp - #errors.cpp - #async_server.cpp - #properties.cpp - #variant.cpp + timeout.cpp + simple.cpp + errors.cpp + async_server.cpp + properties.cpp + variant.cpp buffer.cpp ) diff --git a/tests/buffer.cpp b/tests/buffer.cpp index ae001da..7548326 100644 --- a/tests/buffer.cpp +++ b/tests/buffer.cpp @@ -4,6 +4,7 @@ #include "simppl/skeleton.h" #include "simppl/dispatcher.h" #include "simppl/interface.h" +#include "simppl/buffer.h" #include diff --git a/tests/introserver.cpp b/tests/introserver.cpp index 2158820..8049e18 100644 --- a/tests/introserver.cpp +++ b/tests/introserver.cpp @@ -1,5 +1,10 @@ #include "simppl/skeleton.h" #include "simppl/interface.h" +#include "simppl/map.h" +#include "simppl/vector.h" +#include "simppl/struct.h" +#include "simppl/string.h" +#include "simppl/variant.h" using simppl::dbus::in; diff --git a/tests/properties.cpp b/tests/properties.cpp index ebff29e..1fdf7dc 100644 --- a/tests/properties.cpp +++ b/tests/properties.cpp @@ -11,6 +11,9 @@ #include "simppl/skeleton.h" #include "simppl/dispatcher.h" #include "simppl/interface.h" +#include "simppl/objectpath.h" +#include "simppl/map.h" +#include "simppl/string.h" #include diff --git a/tests/simple.cpp b/tests/simple.cpp index 2a709c8..23683e5 100644 --- a/tests/simple.cpp +++ b/tests/simple.cpp @@ -4,6 +4,9 @@ #include "simppl/skeleton.h" #include "simppl/dispatcher.h" #include "simppl/interface.h" +#include "simppl/struct.h" +#include "simppl/string.h" +#include "simppl/wstring.h" #include @@ -114,11 +117,12 @@ struct Client : simppl::dbus::Stub const wchar_t* wct = L"Hello world"; this->echo_wchart.async(wct) >> [this](simppl::dbus::CallState state, wchar_t* p){ + EXPECT_TRUE((bool)state); EXPECT_EQ(0, wcscmp(p, L"Hello world")); // must delete pointer now, it's mine - simppl::dbus::detail::Deserializer::free(p); + delete[] p; // shutdown this->oneway(7777); @@ -344,7 +348,7 @@ struct Server : simppl::dbus::Skeleton this->respond_with(echo_wchart(str)); // clean up pointer - simppl::dbus::detail::Deserializer::free(str); + delete[] str; }; test_rvo >> [this]() @@ -409,7 +413,7 @@ TEST(Simple, blocking) EXPECT_EQ(4, s.count_oneway_); }); - + simppl::dbus::Stub stub(d, "sb"); // wait for server to get ready @@ -453,14 +457,14 @@ TEST(Simple, blocking) wchar_t* rslt_p = stub.echo_wchart(text); EXPECT_EQ(0, ::wcscmp(rslt_p, L"Hello world")); - simppl::dbus::detail::Deserializer::free(rslt_p); + delete[] rslt_p; } { wchar_t* rslt_p = stub.echo_wchart(L"Hello world"); EXPECT_EQ(0, ::wcscmp(rslt_p, L"Hello world")); - simppl::dbus::detail::Deserializer::free(rslt_p); + delete[] rslt_p; } { @@ -469,7 +473,7 @@ TEST(Simple, blocking) wchar_t* rslt_p = stub.echo_wchart(text); EXPECT_EQ(0, ::wcscmp(rslt_p, L"Hello world")); - simppl::dbus::detail::Deserializer::free(rslt_p); + delete[] rslt_p; } { @@ -479,7 +483,7 @@ TEST(Simple, blocking) wchar_t* rslt_p = stub.echo_wchart(tp); EXPECT_EQ(0, ::wcscmp(rslt_p, L"Hello world")); - simppl::dbus::detail::Deserializer::free(rslt_p); + delete[] rslt_p; } stub.oneway(7777); // stop server diff --git a/tests/variant.cpp b/tests/variant.cpp index fbf4cc6..17b3361 100644 --- a/tests/variant.cpp +++ b/tests/variant.cpp @@ -3,6 +3,9 @@ #include "simppl/stub.h" #include "simppl/skeleton.h" #include "simppl/interface.h" +#include "simppl/struct.h" +#include "simppl/map.h" +#include "simppl/string.h" using simppl::dbus::in;