Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:08:24

0001 /* Copyright (c) 2018-2024 Marcelo Zimbres Silva (mzimbres@gmail.com)
0002  *
0003  * Distributed under the Boost Software License, Version 1.0. (See
0004  * accompanying file LICENSE.txt)
0005  */
0006 
0007 #ifndef BOOST_REDIS_RESP3_SERIALIZATION_HPP
0008 #define BOOST_REDIS_RESP3_SERIALIZATION_HPP
0009 
0010 #include <boost/redis/resp3/type.hpp>
0011 #include <boost/system/system_error.hpp>
0012 #include <boost/throw_exception.hpp>
0013 #include <boost/redis/resp3/parser.hpp>
0014 
0015 #include <string>
0016 #include <tuple>
0017 
0018 // NOTE: Consider detecting tuples in the type in the parameter pack
0019 // to calculate the header size correctly.
0020 
0021 namespace boost::redis::resp3 {
0022 
0023 /** @brief Adds a bulk to the request.
0024  *  @relates boost::redis::request
0025  *
0026  *  This function is useful in serialization of your own data
0027  *  structures in a request. For example
0028  *
0029  *  @code
0030  *  void boost_redis_to_bulk(std::string& payload, mystruct const& obj)
0031  *  {
0032  *     auto const str = // Convert obj to a string.
0033  *     boost_redis_to_bulk(payload, str);
0034  *  }
0035  *  @endcode
0036  *
0037  *  @param payload Storage on which data will be copied into.
0038  *  @param data Data that will be serialized and stored in `payload`.
0039  *
0040  *  See more in @ref serialization.
0041  */
0042 void boost_redis_to_bulk(std::string& payload, std::string_view data);
0043 
0044 template <class T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
0045 void boost_redis_to_bulk(std::string& payload, T n)
0046 {
0047    auto const s = std::to_string(n);
0048    boost::redis::resp3::boost_redis_to_bulk(payload, std::string_view{s});
0049 }
0050 
0051 template <class T>
0052 struct add_bulk_impl {
0053    static void add(std::string& payload, T const& from)
0054    {
0055       using namespace boost::redis::resp3;
0056       boost_redis_to_bulk(payload, from);
0057    }
0058 };
0059 
0060 template <class ...Ts>
0061 struct add_bulk_impl<std::tuple<Ts...>> {
0062    static void add(std::string& payload, std::tuple<Ts...> const& t)
0063    {
0064       auto f = [&](auto const&... vs)
0065       {
0066          using namespace boost::redis::resp3;
0067          (boost_redis_to_bulk(payload, vs), ...);
0068       };
0069 
0070       std::apply(f, t);
0071    }
0072 };
0073 
0074 template <class U, class V>
0075 struct add_bulk_impl<std::pair<U, V>> {
0076    static void add(std::string& payload, std::pair<U, V> const& from)
0077    {
0078       using namespace boost::redis::resp3;
0079       boost_redis_to_bulk(payload, from.first);
0080       boost_redis_to_bulk(payload, from.second);
0081    }
0082 };
0083 
0084 void add_header(std::string& payload, type t, std::size_t size);
0085 
0086 template <class T>
0087 void add_bulk(std::string& payload, T const& data)
0088 {
0089    add_bulk_impl<T>::add(payload, data);
0090 }
0091 
0092 template <class>
0093 struct bulk_counter;
0094 
0095 template <class>
0096 struct bulk_counter {
0097   static constexpr auto size = 1U;
0098 };
0099 
0100 template <class T, class U>
0101 struct bulk_counter<std::pair<T, U>> {
0102   static constexpr auto size = 2U;
0103 };
0104 
0105 void add_blob(std::string& payload, std::string_view blob);
0106 void add_separator(std::string& payload);
0107 
0108 namespace detail
0109 {
0110 
0111 template <class Adapter>
0112 void deserialize(std::string_view const& data, Adapter adapter, system::error_code& ec)
0113 {
0114    parser parser;
0115    while (!parser.done()) {
0116       auto const res = parser.consume(data, ec);
0117       if (ec)
0118          return;
0119 
0120       BOOST_ASSERT(res.has_value());
0121 
0122       adapter(res.value(), ec);
0123       if (ec)
0124          return;
0125    }
0126 
0127    BOOST_ASSERT(parser.get_consumed() == std::size(data));
0128 }
0129 
0130 template <class Adapter>
0131 void deserialize(std::string_view const& data, Adapter adapter)
0132 {
0133    system::error_code ec;
0134    deserialize(data, adapter, ec);
0135 
0136    if (ec)
0137        BOOST_THROW_EXCEPTION(system::system_error{ec});
0138 }
0139 
0140 }
0141 
0142 } // boost::redis::resp3
0143 
0144 #endif // BOOST_REDIS_RESP3_SERIALIZATION_HPP