File indexing completed on 2025-01-18 09:29:32
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_BEAST_HTTP_SERIALIZER_HPP
0011 #define BOOST_BEAST_HTTP_SERIALIZER_HPP
0012
0013 #include <boost/beast/core/detail/config.hpp>
0014 #include <boost/beast/core/buffers_cat.hpp>
0015 #include <boost/beast/core/buffers_prefix.hpp>
0016 #include <boost/beast/core/buffers_suffix.hpp>
0017 #include <boost/beast/core/string.hpp>
0018 #include <boost/beast/core/detail/variant.hpp>
0019 #include <boost/beast/http/message.hpp>
0020 #include <boost/beast/http/chunk_encode.hpp>
0021 #include <boost/asio/buffer.hpp>
0022 #include <boost/optional.hpp>
0023
0024 namespace boost {
0025 namespace beast {
0026 namespace http {
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 template<
0053 bool isRequest,
0054 class Body,
0055 class Fields = fields>
0056 class serializer
0057 {
0058 public:
0059 static_assert(is_body<Body>::value,
0060 "Body type requirements not met");
0061
0062 static_assert(is_body_writer<Body>::value,
0063 "BodyWriter type requirements not met");
0064
0065
0066
0067
0068
0069
0070 #if BOOST_BEAST_DOXYGEN
0071 using value_type = __implementation_defined__;
0072 #else
0073 using value_type = typename std::conditional<
0074 std::is_constructible<typename Body::writer,
0075 header<isRequest, Fields>&,
0076 typename Body::value_type&>::value &&
0077 ! std::is_constructible<typename Body::writer,
0078 header<isRequest, Fields> const&,
0079 typename Body::value_type const&>::value,
0080 message<isRequest, Body, Fields>,
0081 message<isRequest, Body, Fields> const>::type;
0082 #endif
0083
0084 private:
0085 enum
0086 {
0087 do_construct = 0,
0088
0089 do_init = 10,
0090 do_header_only = 20,
0091 do_header = 30,
0092 do_body = 40,
0093
0094 do_init_c = 50,
0095 do_header_only_c = 60,
0096 do_header_c = 70,
0097 do_body_c = 80,
0098 do_final_c = 90,
0099 #ifndef BOOST_BEAST_NO_BIG_VARIANTS
0100 do_body_final_c = 100,
0101 do_all_c = 110,
0102 #endif
0103
0104 do_complete = 120
0105 };
0106
0107 void fwrinit(std::true_type);
0108 void fwrinit(std::false_type);
0109
0110 template<std::size_t, class Visit>
0111 void
0112 do_visit(error_code& ec, Visit& visit);
0113
0114 using writer = typename Body::writer;
0115
0116 using cb1_t = buffers_suffix<typename
0117 Fields::writer::const_buffers_type>;
0118 using pcb1_t = buffers_prefix_view<cb1_t const&>;
0119
0120 using cb2_t = buffers_suffix<buffers_cat_view<
0121 typename Fields::writer::const_buffers_type,
0122 typename writer::const_buffers_type>>;
0123 using pcb2_t = buffers_prefix_view<cb2_t const&>;
0124
0125 using cb3_t = buffers_suffix<
0126 typename writer::const_buffers_type>;
0127 using pcb3_t = buffers_prefix_view<cb3_t const&>;
0128
0129 using cb4_t = buffers_suffix<buffers_cat_view<
0130 typename Fields::writer::const_buffers_type,
0131 detail::chunk_size,
0132 net::const_buffer,
0133 chunk_crlf,
0134 typename writer::const_buffers_type,
0135 chunk_crlf>>;
0136 using pcb4_t = buffers_prefix_view<cb4_t const&>;
0137
0138 using cb5_t = buffers_suffix<buffers_cat_view<
0139 detail::chunk_size,
0140 net::const_buffer,
0141 chunk_crlf,
0142 typename writer::const_buffers_type,
0143 chunk_crlf>>;
0144 using pcb5_t = buffers_prefix_view<cb5_t const&>;
0145
0146 using cb6_t = buffers_suffix<buffers_cat_view<
0147 detail::chunk_size,
0148 net::const_buffer,
0149 chunk_crlf,
0150 typename writer::const_buffers_type,
0151 chunk_crlf,
0152 net::const_buffer,
0153 net::const_buffer,
0154 chunk_crlf>>;
0155 using pcb6_t = buffers_prefix_view<cb6_t const&>;
0156
0157 using cb7_t = buffers_suffix<buffers_cat_view<
0158 typename Fields::writer::const_buffers_type,
0159 detail::chunk_size,
0160 net::const_buffer,
0161 chunk_crlf,
0162 typename writer::const_buffers_type,
0163 chunk_crlf,
0164 net::const_buffer,
0165 net::const_buffer,
0166 chunk_crlf>>;
0167 using pcb7_t = buffers_prefix_view<cb7_t const&>;
0168
0169 using cb8_t = buffers_suffix<buffers_cat_view<
0170 net::const_buffer,
0171 net::const_buffer,
0172 chunk_crlf>>;
0173 using pcb8_t = buffers_prefix_view<cb8_t const&>;
0174
0175 value_type& m_;
0176 writer wr_;
0177 boost::optional<typename Fields::writer> fwr_;
0178 beast::detail::variant<
0179 cb1_t, cb2_t, cb3_t, cb4_t,
0180 cb5_t ,cb6_t, cb7_t, cb8_t> v_;
0181 beast::detail::variant<
0182 pcb1_t, pcb2_t, pcb3_t, pcb4_t,
0183 pcb5_t ,pcb6_t, pcb7_t, pcb8_t> pv_;
0184 std::size_t limit_ =
0185 (std::numeric_limits<std::size_t>::max)();
0186 int s_ = do_construct;
0187 bool split_ = false;
0188 bool header_done_ = false;
0189 bool more_ = false;
0190
0191 public:
0192
0193 serializer(serializer&&) = default;
0194
0195
0196 serializer(serializer const&) = default;
0197
0198
0199 serializer& operator=(serializer const&) = delete;
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215 explicit
0216 serializer(value_type& msg);
0217
0218
0219 value_type&
0220 get()
0221 {
0222 return m_;
0223 }
0224
0225
0226 std::size_t
0227 limit()
0228 {
0229 return limit_;
0230 }
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243 void
0244 limit(std::size_t limit)
0245 {
0246 limit_ = limit > 0 ? limit :
0247 (std::numeric_limits<std::size_t>::max)();
0248 }
0249
0250
0251
0252 bool
0253 split()
0254 {
0255 return split_;
0256 }
0257
0258
0259
0260
0261
0262
0263
0264
0265 void
0266 split(bool v)
0267 {
0268 split_ = v;
0269 }
0270
0271
0272
0273
0274
0275
0276 bool
0277 is_header_done()
0278 {
0279 return header_done_;
0280 }
0281
0282
0283
0284
0285
0286
0287
0288 bool
0289 is_done() const
0290 {
0291 return s_ == do_complete;
0292 }
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318 template<class Visit>
0319 void
0320 next(error_code& ec, Visit&& visit);
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336 void
0337 consume(std::size_t n);
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349 writer&
0350 writer_impl()
0351 {
0352 return wr_;
0353 }
0354 };
0355
0356
0357 template<class Body, class Fields = fields>
0358 using request_serializer = serializer<true, Body, Fields>;
0359
0360
0361 template<class Body, class Fields = fields>
0362 using response_serializer = serializer<false, Body, Fields>;
0363
0364 }
0365 }
0366 }
0367
0368 #include <boost/beast/http/impl/serializer.hpp>
0369
0370 #endif