diff options
author | Roland Reichwein <mail@reichwein.it> | 2023-01-05 18:19:44 +0100 |
---|---|---|
committer | Roland Reichwein <mail@reichwein.it> | 2023-01-05 18:19:44 +0100 |
commit | 15b6682b177dda1bc64384c7ff1a82e88917c2e5 (patch) | |
tree | 9d89f9729c1f815ddb46da9a1eca71dac76fcdbe /archive.h | |
parent | 455fcf0bb13baa18eac12d265ebdb743cb8815f3 (diff) |
Moved archive.h to libreichwein
Diffstat (limited to 'archive.h')
-rw-r--r-- | archive.h | 227 |
1 files changed, 0 insertions, 227 deletions
diff --git a/archive.h b/archive.h deleted file mode 100644 index 9c9d256..0000000 --- a/archive.h +++ /dev/null @@ -1,227 +0,0 @@ -#pragma once - -#include <boost/coroutine2/coroutine.hpp> -#include <boost/endian/conversion.hpp> - -#include <cstdint> -#include <ostream> -#include <iostream> -#include <istream> -#include <sstream> -#include <string> -#include <vector> - -typedef boost::coroutines2::coroutine<void> coro_t; - -// Serialization, similar to Boost Serialization -// but for portable binary archive -// using big endian coding (network byte order) -namespace Serialization { - -class OArchive -{ -public: - OArchive(std::ostream& os): os(os) {} - ~OArchive() {} - - template<class T> - OArchive& operator &(T& v) { - v.serialize(*this); - - return *this; - }; - - template <class T> - OArchive& write_fundamental(T& v) - { - T value = boost::endian::native_to_big(v); - os.write((char*)&value, sizeof(value)); - return *this; - } - - OArchive& operator &(uint8_t& v) - { - return write_fundamental(v); - }; - - OArchive& operator &(uint16_t& v) - { - return write_fundamental(v); - }; - - OArchive& operator &(uint32_t& v) - { - return write_fundamental(v); - }; - - OArchive& operator &(uint64_t& v) - { - return write_fundamental(v); - }; - - OArchive& operator &(int64_t& v) - { - return write_fundamental(*reinterpret_cast<uint64_t*>(v)); - }; - - OArchive& operator &(std::vector<uint8_t>& v) - { - uint32_t size = static_cast<uint32_t>(v.size()); - *this & size; - os.write((char*)v.data(), size); - return *this; - }; - - OArchive& operator &(std::string& v) - { - uint32_t size = static_cast<uint32_t>(v.size()); - *this & size; - os.write((char*)v.data(), v.size()); - return *this; - }; - -private: - std::ostream &os; -}; - -class IArchive -{ -public: - IArchive(std::istream& is): is(is) {} - IArchive(std::stringstream& is, coro_t::pull_type& coro) : is(is), mStringStream(&is), mCoro(&coro) {} - ~IArchive() {} - - template<class T> - IArchive& operator &(T& v) - { - v.serialize(*this); - - return *this; - }; - - template <class T> - IArchive& read_fundamental(T& v) - { - // in coroutine case, wait for input, if necessary - if (mCoro && mStringStream) { - while (true) { - auto pindex {mStringStream->tellp()}; - auto gindex {mStringStream->tellg()}; - if (pindex != std::stringstream::pos_type(-1) && gindex != std::stringstream::pos_type(-1) && pindex > gindex) { - if (static_cast<size_t>(pindex - gindex) < sizeof(v)) - (*mCoro)(); - else - break; - } else { - std::cerr << "Error: read_fundamental: Bad stringstream indices: " << pindex << ", " << gindex << std::endl; - break; - } - } - } - - // now, we have enough bytes available - T value; - is.read((char*)&value, sizeof(value)); - v = boost::endian::big_to_native(value); - return *this; - } - - IArchive& operator &(uint8_t& v) - { - return read_fundamental(v); - }; - - IArchive& operator &(uint16_t& v) - { - return read_fundamental(v); - }; - - IArchive& operator &(uint32_t& v) - { - return read_fundamental(v); - }; - - IArchive& operator &(uint64_t& v) - { - return read_fundamental(v); - }; - - IArchive& operator &(int64_t& v) - { - uint64_t uv; - read_fundamental(uv); - v = *reinterpret_cast<int64_t*>(uv); - return *this; - }; - - template <class T> - IArchive& read_bytes_vector(T& v) - { - uint32_t size; - *this & size; - - v.resize(size); - - // in coroutine case, wait for input, if necessary - if (mCoro && mStringStream) { - while (true) { - auto pindex {mStringStream->tellp()}; - auto gindex {mStringStream->tellg()}; - if (pindex != std::stringstream::pos_type(-1) && gindex != std::stringstream::pos_type(-1) && pindex > gindex) { - if (static_cast<uint32_t>(pindex - gindex) < size) - (*mCoro)(); - else - break; - } else { - std::cerr << "Error: read_bytes_vector: Bad stringstream indices: " << pindex << ", " << gindex << std::endl; - break; - } - } - } - - // now, we have enough bytes available - is.read((char*)v.data(), size); - return *this; - } - - IArchive& operator &(std::vector<uint8_t>& v) - { - return read_bytes_vector(v); - }; - - IArchive& operator &(std::string& v) - { - return read_bytes_vector(v); - }; - -private: - std::istream &is; - std::stringstream* mStringStream{ }; // for i/o sizes access - coro_t::pull_type* mCoro{ }; // optional for coroutine -}; - -// - Free functions ---------------------------------------------------------- - -template<class Archive, class T> -void serialize(Archive& ar, T& v) -{ - ar & v; -} - -template<class T> -OArchive& operator <<(OArchive& ar, T& v) -{ - serialize(ar, v); - - return ar; -}; - -template<class T> -IArchive& operator >>(IArchive& ar, T& v) -{ - serialize(ar, v); - - return ar; -}; - -} |