Commit c05c1e0e authored by Dominik Charousset's avatar Dominik Charousset

Resurrect serialized_size function

parent 61881560
...@@ -74,6 +74,7 @@ set(LIBCAF_CORE_SRCS ...@@ -74,6 +74,7 @@ set(LIBCAF_CORE_SRCS
src/detail/pretty_type_name.cpp src/detail/pretty_type_name.cpp
src/detail/private_thread.cpp src/detail/private_thread.cpp
src/detail/ripemd_160.cpp src/detail/ripemd_160.cpp
src/detail/serialized_size.cpp
src/detail/set_thread_name.cpp src/detail/set_thread_name.cpp
src/detail/shared_spinlock.cpp src/detail/shared_spinlock.cpp
src/detail/simple_actor_clock.cpp src/detail/simple_actor_clock.cpp
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include "caf/error.hpp"
#include "caf/serializer.hpp"
namespace caf::detail {
class serialized_size_inspector final : public serializer {
public:
using super = serializer;
using super::super;
size_t result() const noexcept {
return result_;
}
result_type begin_object(uint16_t typenr, string_view type_name) override;
result_type end_object() override;
result_type begin_sequence(size_t num) override;
result_type end_sequence() override;
result_type apply(bool x) override;
result_type apply(int8_t x) override;
result_type apply(uint8_t x) override;
result_type apply(int16_t x) override;
result_type apply(uint16_t x) override;
result_type apply(int32_t x) override;
result_type apply(uint32_t x) override;
result_type apply(int64_t x) override;
result_type apply(uint64_t x) override;
result_type apply(float x) override;
result_type apply(double x) override;
result_type apply(long double x) override;
result_type apply(string_view x) override;
result_type apply(const std::u16string& x) override;
result_type apply(const std::u32string& x) override;
result_type apply(span<const byte> x) override;
result_type apply(const std::vector<bool>& xs) override;
private:
size_t result_ = 0;
};
template <class T>
size_t serialized_size(actor_system& sys, const T& x) {
serialized_size_inspector f{sys};
auto err = f(x);
static_cast<void>(err);
return f.result();
}
} // namespace caf::detail
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/detail/serialized_size.hpp"
#include <iomanip>
#include <sstream>
#include "caf/error.hpp"
#include "caf/string_view.hpp"
namespace caf::detail {
error serialized_size_inspector::begin_object(uint16_t nr, string_view name) {
if (nr != 0)
return apply(nr);
apply(nr);
return apply(name);
}
error serialized_size_inspector::end_object() {
return none;
}
error serialized_size_inspector::begin_sequence(size_t list_size) {
// Use varbyte encoding to compress sequence size on the wire.
// For 64-bit values, the encoded representation cannot get larger than 10
// bytes. A scratch space of 16 bytes suffices as upper bound.
uint8_t buf[16];
auto i = buf;
auto x = static_cast<uint32_t>(list_size);
while (x > 0x7f) {
*i++ = (static_cast<uint8_t>(x) & 0x7f) | 0x80;
x >>= 7;
}
*i++ = static_cast<uint8_t>(x) & 0x7f;
result_ += static_cast<size_t>(i - buf);
return none;
}
error serialized_size_inspector::end_sequence() {
return none;
}
error serialized_size_inspector::apply(bool) {
result_ += sizeof(uint8_t);
return none;
}
error serialized_size_inspector::apply(int8_t x) {
result_ += sizeof(x);
return none;
}
error serialized_size_inspector::apply(uint8_t x) {
result_ += sizeof(x);
return none;
}
error serialized_size_inspector::apply(int16_t x) {
result_ += sizeof(x);
return none;
}
error serialized_size_inspector::apply(uint16_t x) {
result_ += sizeof(x);
return none;
}
error serialized_size_inspector::apply(int32_t x) {
result_ += sizeof(x);
return none;
}
error serialized_size_inspector::apply(uint32_t x) {
result_ += sizeof(x);
return none;
}
error serialized_size_inspector::apply(int64_t x) {
result_ += sizeof(x);
return none;
}
error serialized_size_inspector::apply(uint64_t x) {
result_ += sizeof(x);
return none;
}
error serialized_size_inspector::apply(float x) {
result_ += sizeof(x);
return none;
}
error serialized_size_inspector::apply(double x) {
result_ += sizeof(x);
return none;
}
error serialized_size_inspector::apply(long double x) {
// The IEEE-754 conversion does not work for long double
// => fall back to string serialization (event though it sucks).
std::ostringstream oss;
oss << std::setprecision(std::numeric_limits<long double>::digits) << x;
auto tmp = oss.str();
return apply(tmp);
}
error serialized_size_inspector::apply(string_view x) {
begin_sequence(x.size());
result_ += x.size();
return end_sequence();
}
error serialized_size_inspector::apply(const std::u16string& x) {
begin_sequence(x.size());
result_ += x.size() * sizeof(uint16_t);
return end_sequence();
}
error serialized_size_inspector::apply(const std::u32string& x) {
begin_sequence(x.size());
result_ += x.size() * sizeof(uint32_t);
return end_sequence();
}
error serialized_size_inspector::apply(span<const byte> x) {
result_ += x.size();
return none;
}
error serialized_size_inspector::apply(const std::vector<bool>& xs) {
begin_sequence(xs.size());
result_ += (xs.size() + static_cast<size_t>(xs.size() % 8 != 0)) / 8;
return end_sequence();
}
} // namespace caf::detail
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#define CAF_SUITE detail.serialized_size
#include "caf/detail/serialized_size.hpp"
#include "caf/test/dsl.hpp"
#include <vector>
#include "caf/binary_serializer.hpp"
#include "caf/byte.hpp"
#include "caf/byte_buffer.hpp"
using namespace caf;
using caf::detail::serialized_size;
namespace {
struct fixture : test_coordinator_fixture<> {
template <class... Ts>
size_t actual_size(const Ts&... xs) {
byte_buffer buf;
binary_serializer sink{sys, buf};
if (auto err = sink(xs...))
CAF_FAIL("failed to serialize data: " << sys.render(err));
return buf.size();
}
};
} // namespace
#define CHECK_SAME_SIZE(...) \
CAF_CHECK_EQUAL(serialized_size(sys, __VA_ARGS__), actual_size(__VA_ARGS__))
CAF_TEST_FIXTURE_SCOPE(serialized_size_tests, fixture)
CAF_TEST(numbers) {
CHECK_SAME_SIZE(int8_t{42});
CHECK_SAME_SIZE(int16_t{42});
CHECK_SAME_SIZE(int32_t{42});
CHECK_SAME_SIZE(int64_t{42});
CHECK_SAME_SIZE(uint8_t{42});
CHECK_SAME_SIZE(uint16_t{42});
CHECK_SAME_SIZE(uint32_t{42});
CHECK_SAME_SIZE(uint64_t{42});
CHECK_SAME_SIZE(4.2f);
CHECK_SAME_SIZE(4.2);
}
CAF_TEST(containers) {
CHECK_SAME_SIZE(std::string{"foobar"});
CHECK_SAME_SIZE(std::vector<char>({'a', 'b', 'c'}));
CHECK_SAME_SIZE(std::vector<std::string>({"hello", "world"}));
}
CAF_TEST(messages) {
CHECK_SAME_SIZE(make_message(42));
CHECK_SAME_SIZE(make_message(1, 2, 3));
CHECK_SAME_SIZE(make_message("hello", "world"));
}
CAF_TEST_FIXTURE_SCOPE_END()
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