Commit 30dde302 authored by Dominik Charousset's avatar Dominik Charousset

added buffer to the list of announced types

parent 17325ef6
...@@ -42,6 +42,8 @@ namespace cppa { ...@@ -42,6 +42,8 @@ namespace cppa {
class object; class object;
class actor_addressing; class actor_addressing;
namespace util { class buffer; }
/** /**
* @ingroup TypeSystem * @ingroup TypeSystem
* @brief Technology-independent deserialization interface. * @brief Technology-independent deserialization interface.
...@@ -127,6 +129,9 @@ class deserializer { ...@@ -127,6 +129,9 @@ class deserializer {
inline actor_addressing* addressing() { return m_addressing; } inline actor_addressing* addressing() { return m_addressing; }
void read_raw(size_t num_bytes, util::buffer& storage);
private: private:
actor_addressing* m_addressing; actor_addressing* m_addressing;
......
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
#include "cppa/atom.hpp" #include "cppa/atom.hpp"
#include "cppa/process_information.hpp" #include "cppa/process_information.hpp"
#include "cppa/util/buffer.hpp"
#include "cppa/util/duration.hpp" #include "cppa/util/duration.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
...@@ -61,6 +63,7 @@ using mapped_type_list = util::type_list< ...@@ -61,6 +63,7 @@ using mapped_type_list = util::type_list<
process_information_ptr, process_information_ptr,
message_header, message_header,
std::nullptr_t, std::nullptr_t,
util::buffer,
util::duration, util::duration,
util::void_type, util::void_type,
double, double,
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#include <cstddef> // size_t #include <cstddef> // size_t
namespace cppa { class deserializer; }
namespace cppa { namespace network { class input_stream; } } namespace cppa { namespace network { class input_stream; } }
namespace cppa { namespace util { namespace cppa { namespace util {
...@@ -49,6 +51,8 @@ enum buffer_write_policy { ...@@ -49,6 +51,8 @@ enum buffer_write_policy {
*/ */
class buffer { class buffer {
friend class deserializer;
public: public:
buffer(); buffer();
...@@ -57,8 +61,12 @@ class buffer { ...@@ -57,8 +61,12 @@ class buffer {
buffer(buffer&& other); buffer(buffer&& other);
buffer(const buffer& other);
buffer& operator=(buffer&& other); buffer& operator=(buffer&& other);
buffer& operator=(const buffer& other);
~buffer(); ~buffer();
/** /**
...@@ -118,6 +126,12 @@ class buffer { ...@@ -118,6 +126,12 @@ class buffer {
void write(size_t num_bytes, const void* data, buffer_write_policy wp); void write(size_t num_bytes, const void* data, buffer_write_policy wp);
void write(const buffer& other, buffer_write_policy wp);
const char* begin() const { return m_data; }
const char* end() const { return m_data + m_written; }
/** /**
* @brief Appends up to @p remaining() bytes from @p istream to the buffer. * @brief Appends up to @p remaining() bytes from @p istream to the buffer.
*/ */
......
...@@ -45,11 +45,11 @@ const size_t default_max_size = 16 * 1024 * 1024; ...@@ -45,11 +45,11 @@ const size_t default_max_size = 16 * 1024 * 1024;
} // namespace anonymous } // namespace anonymous
buffer::buffer() buffer::buffer()
: m_data(0), m_written(0), m_allocated(0), m_final_size(0) : m_data(nullptr), m_written(0), m_allocated(0), m_final_size(0)
, m_chunk_size(default_chunk_size), m_max_buffer_size(default_max_size) { } , m_chunk_size(default_chunk_size), m_max_buffer_size(default_max_size) { }
buffer::buffer(size_t chunk_size, size_t max_buffer_size) buffer::buffer(size_t chunk_size, size_t max_buffer_size)
: m_data(0), m_written(0), m_allocated(0), m_final_size(0) : m_data(nullptr), m_written(0), m_allocated(0), m_final_size(0)
, m_chunk_size(chunk_size), m_max_buffer_size(max_buffer_size) { } , m_chunk_size(chunk_size), m_max_buffer_size(max_buffer_size) { }
buffer::buffer(buffer&& other) buffer::buffer(buffer&& other)
...@@ -60,6 +60,19 @@ buffer::buffer(buffer&& other) ...@@ -60,6 +60,19 @@ buffer::buffer(buffer&& other)
other.m_written = other.m_allocated = other.m_final_size = 0; other.m_written = other.m_allocated = other.m_final_size = 0;
} }
buffer::buffer(const buffer& other)
: m_data(nullptr), m_written(0), m_allocated(0), m_final_size(0)
, m_chunk_size(default_chunk_size), m_max_buffer_size(default_max_size) {
write(other, grow_if_needed);
}
buffer& buffer::operator=(const buffer& other) {
clear();
write(other, grow_if_needed);
return *this;
}
buffer& buffer::operator=(buffer&& other) { buffer& buffer::operator=(buffer&& other) {
std::swap(m_data, other.m_data); std::swap(m_data, other.m_data);
std::swap(m_written, other.m_written); std::swap(m_written, other.m_written);
...@@ -150,6 +163,10 @@ void buffer::write(size_t num_bytes, const void* data, buffer_write_policy wp) { ...@@ -150,6 +163,10 @@ void buffer::write(size_t num_bytes, const void* data, buffer_write_policy wp) {
inc_size(num_bytes); inc_size(num_bytes);
} }
void buffer::write(const buffer& other, buffer_write_policy wp) {
write(other.size(), other.data(), wp);
}
void buffer::append_from(network::input_stream* istream) { void buffer::append_from(network::input_stream* istream) {
CPPA_REQUIRE(remaining() > 0); CPPA_REQUIRE(remaining() > 0);
auto num_bytes = istream->read_some(wr_ptr(), remaining()); auto num_bytes = istream->read_some(wr_ptr(), remaining());
......
...@@ -33,6 +33,9 @@ ...@@ -33,6 +33,9 @@
#include "cppa/object.hpp" #include "cppa/object.hpp"
#include "cppa/deserializer.hpp" #include "cppa/deserializer.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/util/buffer.hpp"
#include "cppa/detail/to_uniform_name.hpp" #include "cppa/detail/to_uniform_name.hpp"
namespace cppa { namespace cppa {
...@@ -41,6 +44,12 @@ deserializer::deserializer(actor_addressing* aa) : m_addressing(aa) { } ...@@ -41,6 +44,12 @@ deserializer::deserializer(actor_addressing* aa) : m_addressing(aa) { }
deserializer::~deserializer() { } deserializer::~deserializer() { }
void deserializer::read_raw(size_t num_bytes, util::buffer& storage) {
storage.acquire(num_bytes);
read_raw(num_bytes, storage.data());
storage.inc_size(num_bytes);
}
deserializer& operator>>(deserializer& d, object& what) { deserializer& operator>>(deserializer& d, object& what) {
std::string tname = d.peek_object(); std::string tname = d.peek_object();
auto mtype = uniform_type_info::from(tname); auto mtype = uniform_type_info::from(tname);
......
...@@ -58,6 +58,7 @@ namespace cppa { namespace detail { ...@@ -58,6 +58,7 @@ namespace cppa { namespace detail {
{ "cppa::intrusive_ptr<cppa::process_information>", "@proc"}, { "cppa::intrusive_ptr<cppa::process_information>", "@proc"},
{ "cppa::message_header", "@header" }, { "cppa::message_header", "@header" },
{ "cppa::nullptr_t", "@null" }, { "cppa::nullptr_t", "@null" },
{ "cppa::util::buffer", "@buffer" },
{ "cppa::util::duration", "@duration" }, { "cppa::util::duration", "@duration" },
{ "cppa::util::void_type", "@0" }, { "cppa::util::void_type", "@0" },
{ "double", "double" }, { "double", "double" },
...@@ -526,6 +527,69 @@ class int_tinfo : public abstract_int_tinfo { ...@@ -526,6 +527,69 @@ class int_tinfo : public abstract_int_tinfo {
}; };
class buffer_type_info_impl : public uniform_type_info {
public:
void serialize(const void* instance, serializer* sink) const {
auto& val = deref(instance);
sink->begin_object(static_name());
sink->write_value(static_cast<uint32_t>(val.size()));
sink->write_raw(val.size(), val.data());
sink->end_object();
}
void deserialize(void* instance, deserializer* source) const {
assert_type_name(static_name(), source);
auto& ref = deref(instance);
source->begin_object(static_name());
auto s = source->read<uint32_t>();
source->read_raw(s, ref);
source->end_object();
}
const char* name() const {
return static_name();
}
protected:
bool equals(const std::type_info& ti) const {
return ti == typeid(util::buffer);
}
bool equals(const void* vlhs, const void* vrhs) const {
auto& lhs = deref(vlhs);
auto& rhs = deref(vrhs);
return (lhs.empty() && rhs.empty())
|| ( lhs.size() == rhs.size()
&& std::equal(lhs.begin(), lhs.end(), rhs.begin()));
}
void* new_instance(const void* ptr) const {
return (ptr) ? new util::buffer(deref(ptr)) : new util::buffer;
}
void delete_instance(void* instance) const {
delete reinterpret_cast<util::buffer*>(instance);
}
private:
static inline util::buffer& deref(void* ptr) {
return *reinterpret_cast<util::buffer*>(ptr);
}
static inline const util::buffer& deref(const void* ptr) {
return *reinterpret_cast<const util::buffer*>(ptr);
}
static inline const char* static_name() {
return "@buffer";
}
};
template<typename T> template<typename T>
void push_native_type(abstract_int_tinfo* m [][2]) { void push_native_type(abstract_int_tinfo* m [][2]) {
m[sizeof(T)][std::is_signed<T>::value ? 1 : 0]->add_native_type(typeid(T)); m[sizeof(T)][std::is_signed<T>::value ? 1 : 0]->add_native_type(typeid(T));
...@@ -574,31 +638,32 @@ class utim_impl : public uniform_type_info_map { ...@@ -574,31 +638,32 @@ class utim_impl : public uniform_type_info_map {
intptr_t >(mapping); intptr_t >(mapping);
// fill builtin types *in sorted order* (by uniform name) // fill builtin types *in sorted order* (by uniform name)
size_t i = 0; size_t i = 0;
m_builtin_types[i++] = &m_type_void; m_builtin_types[i++] = &m_type_void; // @0
m_builtin_types[i++] = &m_type_actor; m_builtin_types[i++] = &m_type_actor; // @actor
m_builtin_types[i++] = &m_type_atom; m_builtin_types[i++] = &m_type_atom; // @atom
m_builtin_types[i++] = &m_type_channel; m_builtin_types[i++] = &m_type_buffer; // @buffer
m_builtin_types[i++] = &m_type_duration; m_builtin_types[i++] = &m_type_channel; // @channel
m_builtin_types[i++] = &m_type_group; m_builtin_types[i++] = &m_type_duration; // @duration
m_builtin_types[i++] = &m_type_header; m_builtin_types[i++] = &m_type_group; // @group
m_builtin_types[i++] = &m_type_i16; m_builtin_types[i++] = &m_type_header; // @header
m_builtin_types[i++] = &m_type_i32; m_builtin_types[i++] = &m_type_i16; // @i16
m_builtin_types[i++] = &m_type_i64; m_builtin_types[i++] = &m_type_i32; // @i32
m_builtin_types[i++] = &m_type_i8; m_builtin_types[i++] = &m_type_i64; // @i64
m_builtin_types[i++] = &m_type_long_double; m_builtin_types[i++] = &m_type_i8; // @i8
m_builtin_types[i++] = &m_type_proc; m_builtin_types[i++] = &m_type_long_double; // @ldouble
m_builtin_types[i++] = &m_type_str; m_builtin_types[i++] = &m_type_proc; // @proc
m_builtin_types[i++] = &m_type_strmap; m_builtin_types[i++] = &m_type_str; // @str
m_builtin_types[i++] = &m_type_tuple; m_builtin_types[i++] = &m_type_strmap; // @strmap
m_builtin_types[i++] = &m_type_u16; m_builtin_types[i++] = &m_type_tuple; // @tuple
m_builtin_types[i++] = &m_type_u16str; m_builtin_types[i++] = &m_type_u16; // @u16
m_builtin_types[i++] = &m_type_u32; m_builtin_types[i++] = &m_type_u16str; // @u16str
m_builtin_types[i++] = &m_type_u32str; m_builtin_types[i++] = &m_type_u32; // @u32
m_builtin_types[i++] = &m_type_u64; m_builtin_types[i++] = &m_type_u32str; // @u32str
m_builtin_types[i++] = &m_type_u8; m_builtin_types[i++] = &m_type_u64; // @u64
m_builtin_types[i++] = &m_type_bool; m_builtin_types[i++] = &m_type_u8; // @u8
m_builtin_types[i++] = &m_type_double; m_builtin_types[i++] = &m_type_bool; // bool
m_builtin_types[i++] = &m_type_float; m_builtin_types[i++] = &m_type_double; // double
m_builtin_types[i++] = &m_type_float; // float
CPPA_REQUIRE(i == m_builtin_types.size()); CPPA_REQUIRE(i == m_builtin_types.size());
# if CPPA_DEBUG_MODE # if CPPA_DEBUG_MODE
auto cmp = [](pointer lhs, pointer rhs) { auto cmp = [](pointer lhs, pointer rhs) {
...@@ -671,6 +736,7 @@ class utim_impl : public uniform_type_info_map { ...@@ -671,6 +736,7 @@ class utim_impl : public uniform_type_info_map {
uti_impl<process_information_ptr> m_type_proc; uti_impl<process_information_ptr> m_type_proc;
uti_impl<channel_ptr> m_type_channel; uti_impl<channel_ptr> m_type_channel;
buffer_type_info_impl m_type_buffer;
uti_impl<actor_ptr> m_type_actor; uti_impl<actor_ptr> m_type_actor;
uti_impl<group_ptr> m_type_group; uti_impl<group_ptr> m_type_group;
uti_impl<any_tuple> m_type_tuple; uti_impl<any_tuple> m_type_tuple;
...@@ -696,7 +762,7 @@ class utim_impl : public uniform_type_info_map { ...@@ -696,7 +762,7 @@ class utim_impl : public uniform_type_info_map {
int_tinfo<std::uint64_t> m_type_u64; int_tinfo<std::uint64_t> m_type_u64;
// both containers are sorted by uniform name // both containers are sorted by uniform name
std::array<pointer, 25> m_builtin_types; std::array<pointer, 26> m_builtin_types;
std::vector<uniform_type_info*> m_user_types; std::vector<uniform_type_info*> m_user_types;
template<typename Container> template<typename Container>
......
...@@ -85,7 +85,8 @@ int main() { ...@@ -85,7 +85,8 @@ int main() {
"@group", // cppa::group_ptr "@group", // cppa::group_ptr
"@channel", // cppa::channel_ptr "@channel", // cppa::channel_ptr
"@proc", // cppa::intrusive_ptr<cppa::process_information> "@proc", // cppa::intrusive_ptr<cppa::process_information>
"@duration" // cppa::util::duration "@duration", // cppa::util::duration
"@buffer" // cppa::util::buffer
}; };
// holds the type names we see at runtime // holds the type names we see at runtime
std::set<std::string> found; std::set<std::string> found;
......
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