summaryrefslogtreecommitdiff
path: root/boost/beast/http/detail/chunk_encode.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/beast/http/detail/chunk_encode.hpp')
-rw-r--r--boost/beast/http/detail/chunk_encode.hpp247
1 files changed, 247 insertions, 0 deletions
diff --git a/boost/beast/http/detail/chunk_encode.hpp b/boost/beast/http/detail/chunk_encode.hpp
new file mode 100644
index 0000000000..cad48418d9
--- /dev/null
+++ b/boost/beast/http/detail/chunk_encode.hpp
@@ -0,0 +1,247 @@
+//
+// Copyright (c) 2016-2017 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/core/type_traits.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 boost::asio::const_buffer str() = 0;
+};
+
+template<class ChunkExtensions>
+struct chunk_extensions_impl : chunk_extensions
+{
+ ChunkExtensions ext_;
+
+ chunk_extensions_impl(ChunkExtensions&& ext)
+ : ext_(std::move(ext))
+ {
+ }
+
+ chunk_extensions_impl(ChunkExtensions const& ext)
+ : ext_(ext)
+ {
+ }
+
+ boost::asio::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(),
+ (void)0)>> : 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
+ {
+ boost::asio::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 = boost::asio::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
+boost::asio::const_buffer
+chunk_crlf()
+{
+ return {"\r\n", 2};
+}
+
+/// Returns a buffer sequence holding a final chunk header
+inline
+boost::asio::const_buffer
+chunk_last()
+{
+ return {"0\r\n", 3};
+}
+
+//------------------------------------------------------------------------------
+
+template<class = void>
+struct chunk_crlf_iter_type
+{
+ class value_type
+ {
+ char const s[2] = {'\r', '\n'};
+
+ public:
+ value_type() = default;
+
+ operator
+ boost::asio::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>;
+
+//------------------------------------------------------------------------------
+
+template<class = void>
+struct chunk_size0_iter_type
+{
+ class value_type
+ {
+ char const s[3] = {'0', '\r', '\n'};
+
+ public:
+ value_type() = default;
+
+ operator
+ boost::asio::const_buffer() const
+ {
+ return {s, sizeof(s)};
+ }
+ };
+ static value_type value;
+};
+
+template<class T>
+typename chunk_size0_iter_type<T>::value_type
+chunk_size0_iter_type<T>::value;
+
+using chunk_size0_iter = chunk_size0_iter_type<void>;
+
+struct chunk_size0
+{
+ using value_type = chunk_size0_iter::value_type;
+
+ using const_iterator = value_type const*;
+
+ const_iterator
+ begin() const
+ {
+ return &chunk_size0_iter::value;
+ }
+
+ 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