]> git.proxmox.com Git - ceph.git/blob - ceph/src/Beast/include/beast/http/detail/chunk_encode.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / Beast / include / beast / http / detail / chunk_encode.hpp
1 //
2 // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7
8 #ifndef BEAST_HTTP_DETAIL_CHUNK_ENCODE_HPP
9 #define BEAST_HTTP_DETAIL_CHUNK_ENCODE_HPP
10
11 #include <boost/asio/buffer.hpp>
12 #include <algorithm>
13 #include <array>
14 #include <cstddef>
15
16 namespace beast {
17 namespace http {
18 namespace detail {
19
20 class chunk_encode_delim
21 {
22 boost::asio::const_buffer cb_;
23
24 // Storage for the longest hex string we might need, plus delimiters.
25 std::array<char, 2 * sizeof(std::size_t) + 2> buf_;
26
27 template<class = void>
28 void
29 copy(chunk_encode_delim const& other);
30
31 template<class = void>
32 void
33 setup(std::size_t n);
34
35 template<class OutIter>
36 static
37 OutIter
38 to_hex(OutIter last, std::size_t n)
39 {
40 if(n == 0)
41 {
42 *--last = '0';
43 return last;
44 }
45 while(n)
46 {
47 *--last = "0123456789abcdef"[n&0xf];
48 n>>=4;
49 }
50 return last;
51 }
52
53 public:
54 using value_type = boost::asio::const_buffer;
55
56 using const_iterator = value_type const*;
57
58 chunk_encode_delim(chunk_encode_delim const& other)
59 {
60 copy(other);
61 }
62
63 explicit
64 chunk_encode_delim(std::size_t n)
65 {
66 setup(n);
67 }
68
69 const_iterator
70 begin() const
71 {
72 return &cb_;
73 }
74
75 const_iterator
76 end() const
77 {
78 return begin() + 1;
79 }
80 };
81
82 template<class>
83 void
84 chunk_encode_delim::
85 copy(chunk_encode_delim const& other)
86 {
87 auto const n =
88 boost::asio::buffer_size(other.cb_);
89 buf_ = other.buf_;
90 cb_ = boost::asio::const_buffer(
91 &buf_[buf_.size() - n], n);
92 }
93
94 template<class>
95 void
96 chunk_encode_delim::
97 setup(std::size_t n)
98 {
99 buf_[buf_.size() - 2] = '\r';
100 buf_[buf_.size() - 1] = '\n';
101 auto it = to_hex(buf_.end() - 2, n);
102 cb_ = boost::asio::const_buffer{&*it,
103 static_cast<std::size_t>(
104 std::distance(it, buf_.end()))};
105 }
106
107 } // detail
108 } // http
109 } // beast
110
111 #endif