Back to home page

EIC code displayed by LXR

 
 

    


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

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_DETAIL_CHUNK_ENCODE_HPP
0011 #define BOOST_BEAST_HTTP_DETAIL_CHUNK_ENCODE_HPP
0012 
0013 #include <boost/beast/http/type_traits.hpp>
0014 #include <boost/asio/buffer.hpp>
0015 #include <algorithm>
0016 #include <array>
0017 #include <cstddef>
0018 #include <memory>
0019 
0020 namespace boost {
0021 namespace beast {
0022 namespace http {
0023 namespace detail {
0024 
0025 struct chunk_extensions
0026 {
0027     virtual ~chunk_extensions() = default;
0028     virtual net::const_buffer str() = 0;
0029 };
0030 
0031 template<class ChunkExtensions>
0032 struct chunk_extensions_impl : chunk_extensions
0033 {
0034     ChunkExtensions ext_;
0035 
0036     chunk_extensions_impl(ChunkExtensions&& ext) noexcept
0037         : ext_(std::move(ext))
0038     {
0039     }
0040 
0041     chunk_extensions_impl(ChunkExtensions const& ext)
0042         : ext_(ext)
0043     {
0044     }
0045 
0046     net::const_buffer
0047     str() override
0048     {
0049         auto const s = ext_.str();
0050         return {s.data(), s.size()};
0051     }
0052 };
0053 
0054 template<class T, class = void>
0055 struct is_chunk_extensions : std::false_type {};
0056 
0057 template<class T>
0058 struct is_chunk_extensions<T, beast::detail::void_t<decltype(
0059     std::declval<string_view&>() = std::declval<T&>().str()
0060         )>> : std::true_type
0061 {
0062 };
0063 
0064 //------------------------------------------------------------------------------
0065 
0066 /** A buffer sequence containing a chunk-encoding header
0067 */
0068 class chunk_size
0069 {
0070     template<class OutIter>
0071     static
0072     OutIter
0073     to_hex(OutIter last, std::size_t n)
0074     {
0075         if(n == 0)
0076         {
0077             *--last = '0';
0078             return last;
0079         }
0080         while(n)
0081         {
0082             *--last = "0123456789abcdef"[n&0xf];
0083             n>>=4;
0084         }
0085         return last;
0086     }
0087 
0088     struct sequence
0089     {
0090         net::const_buffer b;
0091         char data[1 + 2 * sizeof(std::size_t)];
0092 
0093         explicit
0094         sequence(std::size_t n)
0095         {
0096             char* it0 = data + sizeof(data);
0097             auto it = to_hex(it0, n);
0098             b = {it,
0099                 static_cast<std::size_t>(it0 - it)};
0100         }
0101     };
0102 
0103     std::shared_ptr<sequence> sp_;
0104 
0105 public:
0106     using value_type = net::const_buffer;
0107 
0108     using const_iterator = value_type const*;
0109 
0110     chunk_size(chunk_size const& other) = default;
0111 
0112     /** Construct a chunk header
0113 
0114         @param n The number of octets in this chunk.
0115     */
0116     chunk_size(std::size_t n)
0117         : sp_(std::make_shared<sequence>(n))
0118     {
0119     }
0120 
0121     const_iterator
0122     begin() const
0123     {
0124         return &sp_->b;
0125     }
0126 
0127     const_iterator
0128     end() const
0129     {
0130         return begin() + 1;
0131     }
0132 };
0133 
0134 //------------------------------------------------------------------------------
0135 
0136 /// Returns a buffer sequence holding a CRLF for chunk encoding
0137 inline
0138 net::const_buffer const&
0139 chunk_crlf()
0140 {
0141     static net::const_buffer const cb{"\r\n", 2};
0142     return cb;
0143 }
0144 
0145 /// Returns a buffer sequence holding a final chunk header
0146 inline
0147 net::const_buffer const&
0148 chunk_last()
0149 {
0150     static net::const_buffer const cb{"0\r\n", 3};
0151     return cb;
0152 }
0153 
0154 //------------------------------------------------------------------------------
0155 
0156 #if 0
0157 template<class = void>
0158 struct chunk_crlf_iter_type
0159 {
0160     class value_type
0161     {
0162         char const s[2] = {'\r', '\n'};
0163 
0164     public:
0165         value_type() = default;
0166 
0167         operator
0168         net::const_buffer() const
0169         {
0170             return {s, sizeof(s)};
0171         }
0172     };
0173     static value_type value;
0174 };
0175 
0176 template<class T>
0177 typename chunk_crlf_iter_type<T>::value_type
0178 chunk_crlf_iter_type<T>::value;
0179 
0180 using chunk_crlf_iter = chunk_crlf_iter_type<void>;
0181 #endif
0182 
0183 //------------------------------------------------------------------------------
0184 
0185 struct chunk_size0
0186 {
0187     using value_type = net::const_buffer;
0188     using const_iterator = value_type const*;
0189 
0190     const_iterator
0191     begin() const
0192     {
0193         return &chunk_last();
0194     }
0195 
0196     const_iterator
0197     end() const
0198     {
0199         return begin() + 1;
0200     }
0201 };
0202 
0203 //------------------------------------------------------------------------------
0204 
0205 template<class T,
0206     bool = is_fields<T>::value>
0207 struct buffers_or_fields
0208 {
0209     using type = typename
0210         T::writer::const_buffers_type;
0211 };
0212 
0213 template<class T>
0214 struct buffers_or_fields<T, false>
0215 {
0216     using type = T;
0217 };
0218 
0219 } // detail
0220 } // http
0221 } // beast
0222 } // boost
0223 
0224 #endif