123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- //
- // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- // Official repository: https://github.com/boostorg/beast
- //
- #ifndef BOOST_BEAST_HTTP_DETAIL_CHUNK_ENCODE_HPP
- #define BOOST_BEAST_HTTP_DETAIL_CHUNK_ENCODE_HPP
- #include <boost/beast/http/type_traits.hpp>
- #include <boost/asio/buffer.hpp>
- #include <algorithm>
- #include <array>
- #include <cstddef>
- #include <memory>
- namespace boost {
- namespace beast {
- namespace http {
- namespace detail {
- struct chunk_extensions
- {
- virtual ~chunk_extensions() = default;
- virtual net::const_buffer str() = 0;
- };
- template<class ChunkExtensions>
- struct chunk_extensions_impl : chunk_extensions
- {
- ChunkExtensions ext_;
- chunk_extensions_impl(ChunkExtensions&& ext) noexcept
- : ext_(std::move(ext))
- {
- }
- chunk_extensions_impl(ChunkExtensions const& ext)
- : ext_(ext)
- {
- }
- net::const_buffer
- str() override
- {
- auto const s = ext_.str();
- return {s.data(), s.size()};
- }
- };
- template<class T, class = void>
- struct is_chunk_extensions : std::false_type {};
- template<class T>
- struct is_chunk_extensions<T, beast::detail::void_t<decltype(
- std::declval<string_view&>() = std::declval<T&>().str()
- )>> : std::true_type
- {
- };
- //------------------------------------------------------------------------------
- /** A buffer sequence containing a chunk-encoding header
- */
- class chunk_size
- {
- template<class OutIter>
- static
- OutIter
- to_hex(OutIter last, std::size_t n)
- {
- if(n == 0)
- {
- *--last = '0';
- return last;
- }
- while(n)
- {
- *--last = "0123456789abcdef"[n&0xf];
- n>>=4;
- }
- return last;
- }
- struct sequence
- {
- net::const_buffer b;
- char data[1 + 2 * sizeof(std::size_t)];
- explicit
- sequence(std::size_t n)
- {
- char* it0 = data + sizeof(data);
- auto it = to_hex(it0, n);
- b = {it,
- static_cast<std::size_t>(it0 - it)};
- }
- };
- std::shared_ptr<sequence> sp_;
- public:
- using value_type = net::const_buffer;
- using const_iterator = value_type const*;
- chunk_size(chunk_size const& other) = default;
- /** Construct a chunk header
- @param n The number of octets in this chunk.
- */
- chunk_size(std::size_t n)
- : sp_(std::make_shared<sequence>(n))
- {
- }
- const_iterator
- begin() const
- {
- return &sp_->b;
- }
- const_iterator
- end() const
- {
- return begin() + 1;
- }
- };
- //------------------------------------------------------------------------------
- /// Returns a buffer sequence holding a CRLF for chunk encoding
- inline
- net::const_buffer const&
- chunk_crlf()
- {
- static net::const_buffer const cb{"\r\n", 2};
- return cb;
- }
- /// Returns a buffer sequence holding a final chunk header
- inline
- net::const_buffer const&
- chunk_last()
- {
- static net::const_buffer const cb{"0\r\n", 3};
- return cb;
- }
- //------------------------------------------------------------------------------
- #if 0
- template<class = void>
- struct chunk_crlf_iter_type
- {
- class value_type
- {
- char const s[2] = {'\r', '\n'};
- public:
- value_type() = default;
- operator
- net::const_buffer() const
- {
- return {s, sizeof(s)};
- }
- };
- static value_type value;
- };
- template<class T>
- typename chunk_crlf_iter_type<T>::value_type
- chunk_crlf_iter_type<T>::value;
- using chunk_crlf_iter = chunk_crlf_iter_type<void>;
- #endif
- //------------------------------------------------------------------------------
- struct chunk_size0
- {
- using value_type = net::const_buffer;
- using const_iterator = value_type const*;
- const_iterator
- begin() const
- {
- return &chunk_last();
- }
- const_iterator
- end() const
- {
- return begin() + 1;
- }
- };
- //------------------------------------------------------------------------------
- template<class T,
- bool = is_fields<T>::value>
- struct buffers_or_fields
- {
- using type = typename
- T::writer::const_buffers_type;
- };
- template<class T>
- struct buffers_or_fields<T, false>
- {
- using type = T;
- };
- } // detail
- } // http
- } // beast
- } // boost
- #endif
|