Line data Source code
1 : //
2 : // Copyright (c) 2024 Christian Mazakas
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/CPPAlliance/http_proto
8 : //
9 :
10 : #ifndef BOOST_HTTP_PROTO_DETAIL_HEADER_IMPL_HPP
11 : #define BOOST_HTTP_PROTO_DETAIL_HEADER_IMPL_HPP
12 :
13 : #include <boost/http_proto/detail/except.hpp>
14 : #include <boost/http_proto/message_base.hpp>
15 : #include <boost/http_proto/detail/header.hpp>
16 : #include <boost/core/span.hpp>
17 : #include <cstddef>
18 :
19 : namespace boost {
20 : namespace http_proto {
21 : namespace detail {
22 :
23 : struct prefix_op
24 : {
25 : message_base& mb_;
26 : span<char> prefix_;
27 : char* buf_ = nullptr;
28 : std::size_t n_ = 0;
29 :
30 35 : prefix_op(
31 : message_base& mb,
32 : std::size_t n)
33 35 : : mb_{mb}
34 35 : , n_{n}
35 : {
36 35 : auto& h = mb_.h_;
37 35 : if( h.buf && n <= h.prefix )
38 : {
39 9 : prefix_ = {h.buf, n};
40 9 : return;
41 : }
42 :
43 : // allocate or grow
44 26 : if( n > h.prefix &&
45 24 : static_cast<std::size_t>(n - h.prefix) >
46 24 : static_cast<std::size_t>(max_offset - h.size) )
47 : {
48 1 : throw_length_error();
49 : }
50 :
51 25 : auto n1 = header::bytes_needed(
52 25 : n + h.size - h.prefix,
53 25 : h.count);
54 :
55 25 : auto p = new char[n1];
56 25 : if( h.buf != nullptr )
57 : {
58 5 : std::memcpy(
59 5 : p + n,
60 5 : h.buf + h.prefix,
61 5 : h.size - h.prefix);
62 5 : h.copy_table(p + n1);
63 : }
64 : else
65 : {
66 20 : std::memcpy(
67 20 : p + n,
68 20 : h.cbuf + h.prefix,
69 20 : h.size - h.prefix);
70 : }
71 :
72 25 : prefix_ = {p, n};
73 25 : buf_ = h.buf;
74 :
75 25 : h.buf = p;
76 25 : h.cbuf = p;
77 25 : h.size = static_cast<
78 25 : offset_type>(h.size +
79 25 : n - h.prefix);
80 25 : h.prefix = static_cast<
81 : offset_type>(n);
82 25 : h.cap = n1;
83 : }
84 :
85 : prefix_op(prefix_op&&) = delete;
86 : prefix_op(prefix_op const&) = delete;
87 :
88 34 : ~prefix_op()
89 : {
90 34 : auto& h = mb_.h_;
91 34 : if( n_ < h.prefix )
92 : {
93 5 : std::memmove(
94 5 : h.buf + n_,
95 5 : h.buf + h.prefix,
96 5 : h.size - h.prefix);
97 5 : h.size = static_cast<
98 5 : offset_type>(h.size -
99 5 : h.prefix + n_);
100 5 : h.prefix = static_cast<
101 5 : offset_type>(n_);
102 : }
103 34 : delete[] buf_;
104 34 : }
105 : };
106 :
107 : } // detail
108 : } // http_proto
109 : } // boost
110 :
111 : #endif // BOOST_HTTP_PROTO_DETAIL_HEADER_IMPL_HPP
|