C++ 的Serialization / Deserialization已經很成熟了
有了Boost 和 Cereal可以選,不過它們需要ifstream
和ofstream
做參數傳入
如果我們需要用於網路傳輸跟Database該怎麼辦
Boost ASIO幫我們解決了這個問題
Output Wrapper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| template <typename Container, typename SinkType, typename CharType> class container_sink { public: typedef CharType char_type; typedef boost::iostreams::sink_tag category;
container_sink(Container& container) : container_(container) { static_assert(sizeof(SinkType) == sizeof(CharType), "invalid size"); }
std::streamsize write(const char_type* buffer, std::streamsize size) { const auto safe_sink = reinterpret_cast<const SinkType*>(buffer); container_.insert(container_.end(), safe_sink, safe_sink + size); return size; }
private: Container& container_; };
template <typename Container> using byte_sink = container_sink<Container, uint8_t, char>; using data_sink = boost::iostreams::stream<byte_sink<data_chunk>>;
|
如何使用
1 2 3 4 5 6 7
| data_chunk data; data_sink ostream(data); boost::archive::binary_oarchive oa(ostream); const gps_position g(35, 59, 24.567f); oa << g; ostream.flush(); return ostream;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| template <typename Container, typename SourceType, typename CharType> class container_source { public: typedef CharType char_type; typedef boost::iostreams::source_tag category;
container_source(const Container& container) : container_(container), position_(0) { static_assert(sizeof(SourceType) == sizeof(CharType), "invalid size"); }
std::streamsize read(char_type* buffer, std::streamsize size) { const auto amount = container_.size() - position_; const auto result = std::min(size, static_cast<std::streamsize>(amount));
if (result <= 0) return -1;
const auto value = static_cast<typename Container::size_type>(result); const auto limit = position_ + value; const auto start = container_.begin() + position_;
const auto end = container_.begin() + limit; std::copy(start, end, buffer); position_ = limit; return result; }
private: const Container& container_; typename Container::size_type position_; };
template <typename Container> using byte_source = container_source<Container, uint8_t, char>; using data_source = boost::iostreams::stream<byte_source<data_chunk>>;
|
如何使用
1 2 3 4
| data_chunk data; data_source istream(data); boost::archive::binary_iarchive ia(istream); istream >> g;
|