Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:30

0001 //
0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/beast
0008 //
0009 
0010 #ifndef BOOST_BEAST_HTTP_IMPL_SERIALIZER_HPP
0011 #define BOOST_BEAST_HTTP_IMPL_SERIALIZER_HPP
0012 
0013 #include <boost/beast/core/buffer_traits.hpp>
0014 #include <boost/beast/core/detail/buffers_ref.hpp>
0015 #include <boost/beast/http/error.hpp>
0016 #include <boost/beast/http/status.hpp>
0017 #include <boost/beast/core/detail/config.hpp>
0018 #include <boost/assert.hpp>
0019 #include <ostream>
0020 
0021 namespace boost {
0022 namespace beast {
0023 namespace http {
0024 
0025 template<
0026     bool isRequest, class Body, class Fields>
0027 void
0028 serializer<isRequest, Body, Fields>::
0029 fwrinit(std::true_type)
0030 {
0031     fwr_.emplace(m_, m_.version(), m_.method());
0032 }
0033 
0034 template<
0035     bool isRequest, class Body, class Fields>
0036 void
0037 serializer<isRequest, Body, Fields>::
0038 fwrinit(std::false_type)
0039 {
0040     fwr_.emplace(m_, m_.version(), m_.result_int());
0041 }
0042 
0043 template<
0044     bool isRequest, class Body, class Fields>
0045 template<std::size_t I, class Visit>
0046 inline
0047 void
0048 serializer<isRequest, Body, Fields>::
0049 do_visit(error_code& ec, Visit& visit)
0050 {
0051     pv_.template emplace<I>(limit_, v_.template get<I>());
0052     visit(ec, beast::detail::make_buffers_ref(
0053         pv_.template get<I>()));
0054 }
0055 
0056 //------------------------------------------------------------------------------
0057 
0058 template<
0059     bool isRequest, class Body, class Fields>
0060 serializer<isRequest, Body, Fields>::
0061 serializer(value_type& m)
0062     : m_(m)
0063     , wr_(m_.base(), m_.body())
0064 {
0065 }
0066 
0067 template<
0068     bool isRequest, class Body, class Fields>
0069 template<class Visit>
0070 void
0071 serializer<isRequest, Body, Fields>::
0072 next(error_code& ec, Visit&& visit)
0073 {
0074     switch(s_)
0075     {
0076     case do_construct:
0077     {
0078         fwrinit(std::integral_constant<bool,
0079             isRequest>{});
0080         if(m_.chunked())
0081             goto go_init_c;
0082         s_ = do_init;
0083         BOOST_FALLTHROUGH;
0084     }
0085 
0086     case do_init:
0087     {
0088         wr_.init(ec);
0089         if(ec)
0090             return;
0091         if(split_)
0092             goto go_header_only;
0093         auto result = wr_.get(ec);
0094         if(ec == error::need_more)
0095             goto go_header_only;
0096         if(ec)
0097             return;
0098         if(! result)
0099             goto go_header_only;
0100         more_ = result->second;
0101         v_.template emplace<2>(
0102             boost::in_place_init,
0103             fwr_->get(),
0104             result->first);
0105         s_ = do_header;
0106         BOOST_FALLTHROUGH;
0107     }
0108 
0109     case do_header:
0110         do_visit<2>(ec, visit);
0111         break;
0112 
0113     go_header_only:
0114         v_.template emplace<1>(fwr_->get());
0115         s_ = do_header_only;
0116         BOOST_FALLTHROUGH;
0117     case do_header_only:
0118         do_visit<1>(ec, visit);
0119         break;
0120 
0121     case do_body:
0122         s_ = do_body + 1;
0123         BOOST_FALLTHROUGH;
0124 
0125     case do_body + 1:
0126     {
0127         auto result = wr_.get(ec);
0128         if(ec)
0129             return;
0130         if(! result)
0131             goto go_complete;
0132         more_ = result->second;
0133         v_.template emplace<3>(result->first);
0134         s_ = do_body + 2;
0135         BOOST_FALLTHROUGH;
0136     }
0137 
0138     case do_body + 2:
0139         do_visit<3>(ec, visit);
0140         break;
0141 
0142     //----------------------------------------------------------------------
0143 
0144         go_init_c:
0145         s_ = do_init_c;
0146         BOOST_FALLTHROUGH;
0147     case do_init_c:
0148     {
0149         wr_.init(ec);
0150         if(ec)
0151             return;
0152         if(split_)
0153             goto go_header_only_c;
0154         auto result = wr_.get(ec);
0155         if(ec == error::need_more)
0156             goto go_header_only_c;
0157         if(ec)
0158             return;
0159         if(! result)
0160             goto go_header_only_c;
0161         more_ = result->second;
0162         if(! more_)
0163         {
0164             // do it all in one buffer
0165             v_.template emplace<7>(
0166                 boost::in_place_init,
0167                 fwr_->get(),
0168                 buffer_bytes(result->first),
0169                 net::const_buffer{nullptr, 0},
0170                 chunk_crlf{},
0171                 result->first,
0172                 chunk_crlf{},
0173                 detail::chunk_last(),
0174                 net::const_buffer{nullptr, 0},
0175                 chunk_crlf{});
0176             goto go_all_c;
0177         }
0178         v_.template emplace<4>(
0179             boost::in_place_init,
0180             fwr_->get(),
0181             buffer_bytes(result->first),
0182             net::const_buffer{nullptr, 0},
0183             chunk_crlf{},
0184             result->first,
0185             chunk_crlf{});
0186         s_ = do_header_c;
0187         BOOST_FALLTHROUGH;
0188     }
0189 
0190     case do_header_c:
0191         do_visit<4>(ec, visit);
0192         break;
0193 
0194     go_header_only_c:
0195         v_.template emplace<1>(fwr_->get());
0196         s_ = do_header_only_c;
0197         BOOST_FALLTHROUGH;
0198 
0199     case do_header_only_c:
0200         do_visit<1>(ec, visit);
0201         break;
0202 
0203     case do_body_c:
0204         s_ = do_body_c + 1;
0205         BOOST_FALLTHROUGH;
0206 
0207     case do_body_c + 1:
0208     {
0209         auto result = wr_.get(ec);
0210         if(ec)
0211             return;
0212         if(! result)
0213             goto go_final_c;
0214         more_ = result->second;
0215         if(! more_)
0216         {
0217             // do it all in one buffer
0218             v_.template emplace<6>(
0219                 boost::in_place_init,
0220                 buffer_bytes(result->first),
0221                 net::const_buffer{nullptr, 0},
0222                 chunk_crlf{},
0223                 result->first,
0224                 chunk_crlf{},
0225                 detail::chunk_last(),
0226                 net::const_buffer{nullptr, 0},
0227                 chunk_crlf{});
0228             goto go_body_final_c;
0229         }
0230         v_.template emplace<5>(
0231             boost::in_place_init,
0232             buffer_bytes(result->first),
0233             net::const_buffer{nullptr, 0},
0234             chunk_crlf{},
0235             result->first,
0236             chunk_crlf{});
0237         s_ = do_body_c + 2;
0238         BOOST_FALLTHROUGH;
0239     }
0240 
0241     case do_body_c + 2:
0242         do_visit<5>(ec, visit);
0243         break;
0244 
0245     go_body_final_c:
0246         s_ = do_body_final_c;
0247         BOOST_FALLTHROUGH;
0248     case do_body_final_c:
0249         do_visit<6>(ec, visit);
0250         break;
0251 
0252     go_all_c:
0253         s_ = do_all_c;
0254         BOOST_FALLTHROUGH;
0255     case do_all_c:
0256         do_visit<7>(ec, visit);
0257         break;
0258 
0259     go_final_c:
0260     case do_final_c:
0261         v_.template emplace<8>(
0262             boost::in_place_init,
0263             detail::chunk_last(),
0264             net::const_buffer{nullptr, 0},
0265             chunk_crlf{});
0266         s_ = do_final_c + 1;
0267         BOOST_FALLTHROUGH;
0268 
0269     case do_final_c + 1:
0270         do_visit<8>(ec, visit);
0271         break;
0272 
0273     //----------------------------------------------------------------------
0274 
0275     default:
0276     case do_complete:
0277         BOOST_ASSERT(false);
0278         break;
0279 
0280     go_complete:
0281         s_ = do_complete;
0282         break;
0283     }
0284 }
0285 
0286 template<
0287     bool isRequest, class Body, class Fields>
0288 void
0289 serializer<isRequest, Body, Fields>::
0290 consume(std::size_t n)
0291 {
0292     switch(s_)
0293     {
0294     case do_header:
0295         BOOST_ASSERT(
0296             n <= buffer_bytes(v_.template get<2>()));
0297         v_.template get<2>().consume(n);
0298         if(buffer_bytes(v_.template get<2>()) > 0)
0299             break;
0300         header_done_ = true;
0301         v_.reset();
0302         if(! more_)
0303             goto go_complete;
0304         s_ = do_body + 1;
0305         break;
0306 
0307     case do_header_only:
0308         BOOST_ASSERT(
0309             n <= buffer_bytes(v_.template get<1>()));
0310         v_.template get<1>().consume(n);
0311         if(buffer_bytes(v_.template get<1>()) > 0)
0312             break;
0313         fwr_ = boost::none;
0314         header_done_ = true;
0315         if(! split_)
0316             goto go_complete;
0317         s_ = do_body;
0318         break;
0319 
0320     case do_body + 2:
0321     {
0322         BOOST_ASSERT(
0323             n <= buffer_bytes(v_.template get<3>()));
0324         v_.template get<3>().consume(n);
0325         if(buffer_bytes(v_.template get<3>()) > 0)
0326             break;
0327         v_.reset();
0328         if(! more_)
0329             goto go_complete;
0330         s_ = do_body + 1;
0331         break;
0332     }
0333 
0334     //----------------------------------------------------------------------
0335 
0336     case do_header_c:
0337         BOOST_ASSERT(
0338             n <= buffer_bytes(v_.template get<4>()));
0339         v_.template get<4>().consume(n);
0340         if(buffer_bytes(v_.template get<4>()) > 0)
0341             break;
0342         header_done_ = true;
0343         v_.reset();
0344         if(more_)
0345             s_ = do_body_c + 1;
0346         else
0347             s_ = do_final_c;
0348         break;
0349 
0350     case do_header_only_c:
0351     {
0352         BOOST_ASSERT(
0353             n <= buffer_bytes(v_.template get<1>()));
0354         v_.template get<1>().consume(n);
0355         if(buffer_bytes(v_.template get<1>()) > 0)
0356             break;
0357         fwr_ = boost::none;
0358         header_done_ = true;
0359         if(! split_)
0360         {
0361             s_ = do_final_c;
0362             break;
0363         }
0364         s_ = do_body_c;
0365         break;
0366     }
0367 
0368     case do_body_c + 2:
0369         BOOST_ASSERT(
0370             n <= buffer_bytes(v_.template get<5>()));
0371         v_.template get<5>().consume(n);
0372         if(buffer_bytes(v_.template get<5>()) > 0)
0373             break;
0374         v_.reset();
0375         if(more_)
0376             s_ = do_body_c + 1;
0377         else
0378             s_ = do_final_c;
0379         break;
0380 
0381     case do_body_final_c:
0382     {
0383         BOOST_ASSERT(
0384             n <= buffer_bytes(v_.template get<6>()));
0385         v_.template get<6>().consume(n);
0386         if(buffer_bytes(v_.template get<6>()) > 0)
0387             break;
0388         v_.reset();
0389         s_ = do_complete;
0390         break;
0391     }
0392 
0393     case do_all_c:
0394     {
0395         BOOST_ASSERT(
0396             n <= buffer_bytes(v_.template get<7>()));
0397         v_.template get<7>().consume(n);
0398         if(buffer_bytes(v_.template get<7>()) > 0)
0399             break;
0400         header_done_ = true;
0401         v_.reset();
0402         s_ = do_complete;
0403         break;
0404     }
0405 
0406     case do_final_c + 1:
0407         BOOST_ASSERT(buffer_bytes(v_.template get<8>()));
0408         v_.template get<8>().consume(n);
0409         if(buffer_bytes(v_.template get<8>()) > 0)
0410             break;
0411         v_.reset();
0412         goto go_complete;
0413 
0414     //----------------------------------------------------------------------
0415 
0416     default:
0417         BOOST_ASSERT(false);
0418     case do_complete:
0419         break;
0420 
0421     go_complete:
0422         s_ = do_complete;
0423         break;
0424     }
0425 }
0426 
0427 } // http
0428 } // beast
0429 } // boost
0430 
0431 #endif