rpc_serialization.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Copyright (c) 2017-2023 zhllxt
  3. *
  4. * author : zhllxt
  5. * email : 37792738@qq.com
  6. *
  7. * Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. */
  10. #ifndef __ASIO2_RPC_SERIALIZATION_HPP__
  11. #define __ASIO2_RPC_SERIALIZATION_HPP__
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. #pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <istream>
  16. #include <ostream>
  17. #include <streambuf>
  18. #include <string>
  19. #include <string_view>
  20. #include <asio2/external/cereal.hpp>
  21. #include <asio2/base/error.hpp>
  22. #include <asio2/rpc/detail/rpc_portable_binary.hpp>
  23. #include <asio2/rpc/error.hpp>
  24. namespace asio2::detail
  25. {
  26. class ostrbuf : public std::streambuf
  27. {
  28. public:
  29. using string_type = std::basic_string<char_type, traits_type>;
  30. using size_type = typename string_type::size_type;
  31. ostrbuf() {}
  32. virtual ~ostrbuf() noexcept {}
  33. inline const string_type& str() const noexcept
  34. {
  35. return this->str_;
  36. }
  37. inline void clear() noexcept
  38. {
  39. this->str_.clear();
  40. this->setp(this->str_.data(), this->str_.data() + this->str_.size());
  41. }
  42. protected:
  43. virtual std::streamsize xsputn(const char_type* s, std::streamsize count) override
  44. {
  45. this->str_.append(s, size_type(count));
  46. this->setp(this->str_.data(), this->str_.data() + this->str_.size());
  47. return count;
  48. }
  49. protected:
  50. string_type str_;
  51. };
  52. class istrbuf : public std::streambuf
  53. {
  54. public:
  55. using string_type = std::basic_string<char_type, traits_type>;
  56. using size_type = typename string_type::size_type;
  57. istrbuf() {}
  58. virtual ~istrbuf() noexcept {}
  59. inline void setbuf(std::string_view s) noexcept
  60. {
  61. this->setbuf(const_cast<char_type*>(s.data()), std::streamsize(s.size()));
  62. }
  63. virtual std::streambuf* setbuf(char_type* s, std::streamsize n) override
  64. {
  65. this->setg(s, s, s + n);
  66. return this;
  67. }
  68. protected:
  69. virtual std::streamsize xsgetn(char_type* s, std::streamsize count) override
  70. {
  71. if (this->in_avail() < count)
  72. return std::streamsize(0);
  73. std::memcpy((void*)s, (const void*)(this->gptr()), size_type(count));
  74. this->setg(this->eback(), this->gptr() + count, this->egptr());
  75. return count;
  76. }
  77. };
  78. class rpc_serializer
  79. {
  80. public:
  81. using oarchive = cereal::RPCPortableBinaryOutputArchive;
  82. rpc_serializer()
  83. : obuffer_()
  84. , ostream_(std::addressof(obuffer_))
  85. , oarchive_(ostream_)
  86. {}
  87. ~rpc_serializer() = default;
  88. template<typename T>
  89. inline rpc_serializer& operator<<(const T& v)
  90. {
  91. this->oarchive_ << v;
  92. return (*this);
  93. }
  94. inline rpc_serializer& operator<<(const error_code& ec)
  95. {
  96. this->oarchive_ << ec.value();
  97. return (*this);
  98. }
  99. template<class ...Args>
  100. inline rpc_serializer& save(const Args&... args)
  101. {
  102. ((this->oarchive_ << args), ...);
  103. return (*this);
  104. }
  105. inline rpc_serializer& reset()
  106. {
  107. this->obuffer_.clear();
  108. this->oarchive_.save_endian();
  109. return (*this);
  110. }
  111. inline const auto& str() const noexcept
  112. {
  113. return this->obuffer_.str();
  114. }
  115. inline ostrbuf& buffer() noexcept { return this->obuffer_; }
  116. protected:
  117. ostrbuf obuffer_;
  118. std::ostream ostream_;
  119. oarchive oarchive_;
  120. };
  121. class rpc_deserializer
  122. {
  123. public:
  124. using iarchive = cereal::RPCPortableBinaryInputArchive;
  125. rpc_deserializer()
  126. : ibuffer_()
  127. , istream_(std::addressof(ibuffer_))
  128. , iarchive_(istream_)
  129. {}
  130. ~rpc_deserializer() = default;
  131. template<typename T>
  132. inline rpc_deserializer& operator>>(T& v)
  133. {
  134. this->iarchive_ >> v;
  135. return (*this);
  136. }
  137. inline rpc_deserializer& operator>>(error_code& ec)
  138. {
  139. decltype(ec.value()) v;
  140. this->iarchive_ >> v;
  141. ec.assign(v, ec.category());
  142. return (*this);
  143. }
  144. template<class ...Args>
  145. inline rpc_deserializer& load(Args&... args)
  146. {
  147. ((this->iarchive_ >> args), ...);
  148. return (*this);
  149. }
  150. inline rpc_deserializer& reset(std::string_view s)
  151. {
  152. this->ibuffer_.setbuf(s);
  153. this->iarchive_.load_endian();
  154. return (*this);
  155. }
  156. inline istrbuf& buffer() noexcept { return this->ibuffer_; }
  157. protected:
  158. istrbuf ibuffer_;
  159. std::istream istream_;
  160. iarchive iarchive_;
  161. };
  162. }
  163. namespace asio2::rpc
  164. {
  165. // for serializer
  166. using oarchive = cereal::RPCPortableBinaryOutputArchive;
  167. // for deserializer
  168. using iarchive = cereal::RPCPortableBinaryInputArchive;
  169. }
  170. #endif // !__ASIO2_RPC_SERIALIZATION_HPP__