ゴミ箱
chunk_encode.hpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2016-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 // Official repository: https://github.com/boostorg/beast
8 //
9 
10 #ifndef BOOST_BEAST_HTTP_DETAIL_CHUNK_ENCODE_HPP
11 #define BOOST_BEAST_HTTP_DETAIL_CHUNK_ENCODE_HPP
12 
15 #include <boost/asio/buffer.hpp>
16 #include <algorithm>
17 #include <array>
18 #include <cstddef>
19 
20 namespace boost {
21 namespace beast {
22 namespace http {
23 namespace detail {
24 
26 {
27  virtual ~chunk_extensions() = default;
28  virtual boost::asio::const_buffers_1 str() = 0;
29 };
30 
31 template<class ChunkExtensions>
33 {
34  ChunkExtensions ext_;
35 
36  chunk_extensions_impl(ChunkExtensions&& ext)
37  : ext_(std::move(ext))
38  {
39  }
40 
41  chunk_extensions_impl(ChunkExtensions const& ext)
42  : ext_(ext)
43  {
44  }
45 
46  boost::asio::const_buffers_1
47  str() override
48  {
49  auto const s = ext_.str();
50  return {s.data(), s.size()};
51  }
52 };
53 
54 template<class T, class = void>
55 struct is_chunk_extensions : std::false_type {};
56 
57 template<class T>
58 struct is_chunk_extensions<T, beast::detail::void_t<decltype(
59  std::declval<string_view&>() = std::declval<T&>().str(),
60  (void)0)>> : std::true_type
61 {
62 };
63 
64 //------------------------------------------------------------------------------
65 
69 {
70 public:
71  // Storage for the longest hex string we might need
72  class value_type
73  {
74  friend class chunk_size;
75 
76  // First byte holds the length
77  char buf_[1 + 2 * sizeof(std::size_t)];
78 
79  template<class = void>
80  void
81  prepare(std::size_t n);
82 
83  template<class OutIter>
84  static
85  OutIter
86  to_hex(OutIter last, std::size_t n)
87  {
88  if(n == 0)
89  {
90  *--last = '0';
91  return last;
92  }
93  while(n)
94  {
95  *--last = "0123456789abcdef"[n&0xf];
96  n>>=4;
97  }
98  return last;
99  }
100  public:
101  operator
102  boost::asio::const_buffer() const
103  {
104  return {
105  buf_ + sizeof(buf_) - buf_[0],
106  static_cast<unsigned>(buf_[0])};
107  }
108  };
109 
110  using const_iterator = value_type const*;
111 
112  chunk_size(chunk_size const& other) = default;
113 
118  chunk_size(std::size_t n)
119  {
120  value_.prepare(n);
121  }
122 
124  begin() const
125  {
126  return &value_;
127  }
128 
130  end() const
131  {
132  return begin() + 1;
133  }
134 
135 private:
136  value_type value_;
137 };
138 
139 template<class>
140 void
141 chunk_size::
142 value_type::
143 prepare(std::size_t n)
144 {
145  auto const last = &buf_[sizeof(buf_)];
146  auto it = to_hex(last, n);
147  buf_[0] = static_cast<char>(last - it);
148 }
149 
150 //------------------------------------------------------------------------------
151 
153 inline
154 boost::asio::const_buffers_1
156 {
157  return {"\r\n", 2};
158 }
159 
161 inline
162 boost::asio::const_buffers_1
164 {
165  return {"0\r\n", 3};
166 }
167 
168 //------------------------------------------------------------------------------
169 
170 template<class = void>
172 {
174  {
175  char const s[2] = {'\r', '\n'};
176 
177  public:
178  value_type() = default;
179 
180  operator
181  boost::asio::const_buffer() const
182  {
183  return {s, sizeof(s)};
184  }
185  };
187 };
188 
189 template<class T>
192 
194 
195 //------------------------------------------------------------------------------
196 
197 template<class = void>
199 {
201  {
202  char const s[3] = {'0', '\r', '\n'};
203 
204  public:
205  value_type() = default;
206 
207  operator
208  boost::asio::const_buffer() const
209  {
210  return {s, sizeof(s)};
211  }
212  };
214 };
215 
216 template<class T>
219 
221 
223 {
225 
226  using const_iterator = value_type const*;
227 
229  begin() const
230  {
231  return &chunk_size0_iter::value;
232  }
233 
235  end() const
236  {
237  return begin() + 1;
238  }
239 };
240 
241 //------------------------------------------------------------------------------
242 
243 template<class T,
244  bool = is_fields<T>::value>
246 {
247  using type = typename
248  T::reader::const_buffers_type;
249 };
250 
251 template<class T>
252 struct buffers_or_fields<T, false>
253 {
254  using type = T;
255 };
256 
257 } // detail
258 } // http
259 } // beast
260 } // boost
261 
262 #endif
chunk_extensions_impl(ChunkExtensions const &ext)
Definition: chunk_encode.hpp:41
Definition: chunk_encode.hpp:245
Definition: async_result.hpp:20
const_iterator end() const
Definition: chunk_encode.hpp:130
boost::asio::const_buffers_1 str() override
Definition: chunk_encode.hpp:47
STL namespace.
const_iterator end() const
Definition: chunk_encode.hpp:235
Definition: beast_common.hpp:6
Definition: chunk_encode.hpp:171
Definition: chunk_encode.hpp:222
chunk_size(std::size_t n)
Definition: chunk_encode.hpp:118
Definition: chunk_encode.hpp:25
typename make_void< Ts... >::type void_t
Definition: type_traits.hpp:62
ChunkExtensions ext_
Definition: chunk_encode.hpp:34
boost::asio::const_buffers_1 chunk_last()
Returns a buffer sequence holding a final chunk header.
Definition: chunk_encode.hpp:163
chunk_extensions_impl(ChunkExtensions &&ext)
Definition: chunk_encode.hpp:36
static value_type value
Definition: chunk_encode.hpp:213
typename detail::is_fields_helper< T >::type is_fields
Definition: type_traits.hpp:178
const_iterator begin() const
Definition: chunk_encode.hpp:124
const_iterator begin() const
Definition: chunk_encode.hpp:229
boost::asio::const_buffers_1 chunk_crlf()
Returns a buffer sequence holding a CRLF for chunk encoding.
Definition: chunk_encode.hpp:155
static value_type value
Definition: chunk_encode.hpp:186
value_type const * const_iterator
Definition: chunk_encode.hpp:110
virtual boost::asio::const_buffers_1 str()=0
typename T::reader::const_buffers_type type
Definition: chunk_encode.hpp:248
value_type const * const_iterator
Definition: chunk_encode.hpp:226
Definition: chunk_encode.hpp:68