Commit c2a66286 authored by Dominik Charousset's avatar Dominik Charousset

Allow binary_deserializer to insert into vectors

parent dd8f1f1a
...@@ -125,6 +125,9 @@ public: ...@@ -125,6 +125,9 @@ public:
friend class abstract_actor; friend class abstract_actor;
friend class io::middleman; friend class io::middleman;
actor_system(const actor_system&) = delete;
actor_system& operator=(const actor_system&) = delete;
/// An (optional) component of the actor system. /// An (optional) component of the actor system.
class module { class module {
public: public:
...@@ -208,6 +211,10 @@ public: ...@@ -208,6 +211,10 @@ public:
/// @throws `std::logic_error` if the I/O module has not been loaded. /// @throws `std::logic_error` if the I/O module has not been loaded.
io::middleman& middleman(); io::middleman& middleman();
/// Returns a dummy execution unit that forwards
/// everything to the scheduler.
scoped_execution_unit* dummy_execution_unit();
/// Returns a new actor ID. /// Returns a new actor ID.
actor_id next_actor_id(); actor_id next_actor_id();
...@@ -376,9 +383,8 @@ private: ...@@ -376,9 +383,8 @@ private:
: 0; : 0;
if (has_detach_flag(Os) || has_blocking_api_flag(Os)) if (has_detach_flag(Os) || has_blocking_api_flag(Os))
cfg.flags |= abstract_actor::is_detached_flag; cfg.flags |= abstract_actor::is_detached_flag;
scoped_execution_unit context{this};
if (! cfg.host) if (! cfg.host)
cfg.host = &context; cfg.host = dummy_execution_unit();
auto ptr = make_counted<C>(cfg, std::forward<Ts>(xs)...); auto ptr = make_counted<C>(cfg, std::forward<Ts>(xs)...);
CAF_SET_LOGGER_SYS(this); CAF_SET_LOGGER_SYS(this);
CAF_LOG_DEBUG("spawned actor:" << CAF_ARG(ptr->id())); CAF_LOG_DEBUG("spawned actor:" << CAF_ARG(ptr->id()));
...@@ -395,6 +401,7 @@ private: ...@@ -395,6 +401,7 @@ private:
group_manager groups_; group_manager groups_;
module_array modules_; module_array modules_;
io::middleman* middleman_; io::middleman* middleman_;
scoped_execution_unit dummy_execution_unit_;
}; };
} // namespace caf } // namespace caf
......
...@@ -31,10 +31,17 @@ namespace caf { ...@@ -31,10 +31,17 @@ namespace caf {
/// Implements the deserializer interface with a binary serialization protocol. /// Implements the deserializer interface with a binary serialization protocol.
class binary_deserializer : public deserializer { class binary_deserializer : public deserializer {
public: public:
binary_deserializer(actor_system& sys, const void* buf, size_t buf_size);
binary_deserializer(execution_unit* ctx, const void* buf, size_t buf_size); binary_deserializer(execution_unit* ctx, const void* buf, size_t buf_size);
binary_deserializer(actor_system& ctx, const void* first, const void* last);
binary_deserializer(execution_unit* ctx, const void* first, const void* last); binary_deserializer(execution_unit* ctx, const void* first, const void* last);
template <class C, class T>
binary_deserializer(C&& ctx, const T& xs)
: binary_deserializer(std::forward<C>(ctx), xs.data(), xs.size()) {
// nop
}
/// Replaces the current read buffer. /// Replaces the current read buffer.
void set_rdbuf(const void* buf, size_t buf_size); void set_rdbuf(const void* buf, size_t buf_size);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <utility> #include <utility>
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
#include <iterator>
#include <functional> #include <functional>
#include <type_traits> #include <type_traits>
...@@ -30,7 +31,6 @@ ...@@ -30,7 +31,6 @@
#include "caf/serializer.hpp" #include "caf/serializer.hpp"
#include "caf/primitive_variant.hpp" #include "caf/primitive_variant.hpp"
#include "caf/detail/ieee_754.hpp"
#include "caf/detail/type_traits.hpp" #include "caf/detail/type_traits.hpp"
namespace caf { namespace caf {
...@@ -39,9 +39,31 @@ namespace caf { ...@@ -39,9 +39,31 @@ namespace caf {
class binary_serializer : public serializer { class binary_serializer : public serializer {
public: public:
/// Creates a binary serializer writing to given iterator position. /// Creates a binary serializer writing to given iterator position.
template <class Out> template <class C,
binary_serializer(execution_unit* ctx, Out iter) : serializer(ctx) { class Out,
reset(iter); class E =
typename std::enable_if<
std::is_same<
typename std::iterator_traits<Out>::iterator_category,
std::output_iterator_tag
>::value
|| std::is_same<
typename std::iterator_traits<Out>::iterator_category,
std::random_access_iterator_tag
>::value
>::type>
binary_serializer(C&& ctx, Out it) : serializer(std::forward<C>(ctx)) {
reset_iter(it);
}
template <class C,
class T,
class E =
typename std::enable_if<
detail::has_char_insert<T>::value
>::type>
binary_serializer(C&& ctx, T& out) : serializer(std::forward<C>(ctx)) {
reset_container(out);
} }
using write_fun = std::function<void(const char*, size_t)>; using write_fun = std::function<void(const char*, size_t)>;
...@@ -59,7 +81,7 @@ public: ...@@ -59,7 +81,7 @@ public:
void apply_builtin(builtin in_out_type, void* in_out) override; void apply_builtin(builtin in_out_type, void* in_out) override;
template <class OutIter> template <class OutIter>
void reset(OutIter iter) { void reset_iter(OutIter iter) {
struct fun { struct fun {
fun(OutIter pos) : pos_(pos) { fun(OutIter pos) : pos_(pos) {
// nop // nop
...@@ -72,6 +94,21 @@ public: ...@@ -72,6 +94,21 @@ public:
out_ = fun{iter}; out_ = fun{iter};
} }
template <class T>
void reset_container(T& x) {
struct fun {
fun(T& container) : x_(container) {
// nop
}
void operator()(const char* first, size_t num_bytes) {
auto last = first + num_bytes;
x_.insert(x_.end(), first, last);
}
T& x_;
};
out_ = fun{x};
}
private: private:
write_fun out_; write_fun out_;
}; };
......
...@@ -40,6 +40,8 @@ public: ...@@ -40,6 +40,8 @@ public:
using is_loading = std::true_type; using is_loading = std::true_type;
explicit deserializer(actor_system& sys);
explicit deserializer(execution_unit* ctx); explicit deserializer(execution_unit* ctx);
}; };
......
...@@ -187,6 +187,32 @@ public: ...@@ -187,6 +187,32 @@ public:
static constexpr bool value = std::is_same<bool, result_type>::value; static constexpr bool value = std::is_same<bool, result_type>::value;
}; };
/// Checks wheter `T x` allows `x.insert(x.end(), first, last)` where
/// both `first` and `last` have type `const char*`.
template <class T>
class has_char_insert {
template <class C>
static bool sfinae_fun(C* cc,
const char* first = nullptr,
const char* last = nullptr,
decltype(cc->insert(cc->end(), first, last))* = 0) {
return true;
}
// SFNINAE default
static void sfinae_fun(const void*) {
// nop
}
using decayed = typename std::decay<T>::type;
using result_type = decltype(sfinae_fun(static_cast<decayed*>(nullptr)));
public:
static constexpr bool value = is_primitive<T>::value == false &&
std::is_same<bool, result_type>::value;
};
/// Checks wheter `T` has `begin()` and `end()` member /// Checks wheter `T` has `begin()` and `end()` member
/// functions returning forward iterators. /// functions returning forward iterators.
template <class T> template <class T>
......
...@@ -229,7 +229,7 @@ public: ...@@ -229,7 +229,7 @@ public:
>::type...>; >::type...>;
token tk; token tk;
check_typed_input(dest, tk); check_typed_input(dest, tk);
delayed_send_impl(message_id::make(), actor_cast<abstract_channel*>(dest), delayed_send_impl(message_id::make(), actor_cast<channel>(dest),
rtime, make_message(std::forward<Ts>(xs)...)); rtime, make_message(std::forward<Ts>(xs)...));
} }
......
...@@ -39,6 +39,8 @@ public: ...@@ -39,6 +39,8 @@ public:
using is_loading = std::false_type; using is_loading = std::false_type;
explicit serializer(actor_system& sys);
explicit serializer(execution_unit* ctx); explicit serializer(execution_unit* ctx);
virtual ~serializer(); virtual ~serializer();
......
...@@ -55,7 +55,8 @@ actor_system::actor_system(actor_system_config&& cfg) ...@@ -55,7 +55,8 @@ actor_system::actor_system(actor_system_config&& cfg)
logger_(*this), logger_(*this),
registry_(*this), registry_(*this),
groups_(*this), groups_(*this),
middleman_(nullptr) { middleman_(nullptr),
dummy_execution_unit_(this) {
CAF_SET_LOGGER_SYS(this); CAF_SET_LOGGER_SYS(this);
for (auto& f : cfg.module_factories_) { for (auto& f : cfg.module_factories_) {
auto ptr = f(*this); auto ptr = f(*this);
...@@ -174,6 +175,10 @@ io::middleman& actor_system::middleman() { ...@@ -174,6 +175,10 @@ io::middleman& actor_system::middleman() {
return *middleman_; return *middleman_;
} }
scoped_execution_unit* actor_system::dummy_execution_unit() {
return &dummy_execution_unit_;
}
actor_id actor_system::next_actor_id() { actor_id actor_system::next_actor_id() {
return ++ids_; return ++ids_;
} }
......
...@@ -73,11 +73,22 @@ void apply_float(binary_deserializer& bd, T& x) { ...@@ -73,11 +73,22 @@ void apply_float(binary_deserializer& bd, T& x) {
} // namespace <anonmyous> } // namespace <anonmyous>
binary_deserializer::binary_deserializer(execution_unit* ctx, binary_deserializer::binary_deserializer(actor_system& sys,
const void* buf, size_t buf_size) const void* buf, size_t buf_size)
: deserializer(ctx), : binary_deserializer(sys, buf, advanced(buf, buf_size)) {
pos_(buf), // nop
end_(advanced(buf, buf_size)) { }
binary_deserializer::binary_deserializer(execution_unit* ctx,
const void* buf,
size_t buf_size)
: binary_deserializer(ctx, buf, advanced(buf, buf_size)) {
// nop
}
binary_deserializer::binary_deserializer(actor_system& sys,
const void* first, const void* last)
: binary_deserializer(sys.dummy_execution_unit(), first, last) {
// nop // nop
} }
......
...@@ -17,9 +17,11 @@ ...@@ -17,9 +17,11 @@
* http://www.boost.org/LICENSE_1_0.txt. * * http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/ ******************************************************************************/
#include "caf/binary_serializer.hpp"
#include <limits> #include <limits>
#include "caf/binary_serializer.hpp" #include "caf/detail/ieee_754.hpp"
#include "caf/detail/network_order.hpp" #include "caf/detail/network_order.hpp"
namespace caf { namespace caf {
......
...@@ -19,9 +19,15 @@ ...@@ -19,9 +19,15 @@
#include "caf/deserializer.hpp" #include "caf/deserializer.hpp"
#include "caf/actor_system.hpp"
namespace caf { namespace caf {
deserializer::deserializer(execution_unit* ctx) : super(ctx) { deserializer::deserializer(actor_system& x) : super(x.dummy_execution_unit()) {
// nop
}
deserializer::deserializer(execution_unit* x) : super(x) {
// nop // nop
} }
......
...@@ -19,8 +19,14 @@ ...@@ -19,8 +19,14 @@
#include "caf/serializer.hpp" #include "caf/serializer.hpp"
#include "caf/actor_system.hpp"
namespace caf { namespace caf {
serializer::serializer(actor_system& sys) : super(sys.dummy_execution_unit()) {
// nop
}
serializer::serializer(execution_unit* ctx) : super(ctx) { serializer::serializer(execution_unit* ctx) : super(ctx) {
// nop // nop
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment