1  
//
1  
//
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3  
// Copyright (c) 2025 Mohammad Nejati
3  
// Copyright (c) 2025 Mohammad Nejati
4  
//
4  
//
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  
//
7  
//
8  
// Official repository: https://github.com/cppalliance/http
8  
// Official repository: https://github.com/cppalliance/http
9  
//
9  
//
10  

10  

11  
#ifndef BOOST_HTTP_DETAIL_WORKSPACE_HPP
11  
#ifndef BOOST_HTTP_DETAIL_WORKSPACE_HPP
12  
#define BOOST_HTTP_DETAIL_WORKSPACE_HPP
12  
#define BOOST_HTTP_DETAIL_WORKSPACE_HPP
13  

13  

14  
#include <boost/http/detail/except.hpp>
14  
#include <boost/http/detail/except.hpp>
15  
#include <boost/assert.hpp>
15  
#include <boost/assert.hpp>
16  
#include <cstdlib>
16  
#include <cstdlib>
17  
#include <new>
17  
#include <new>
18  
#include <utility>
18  
#include <utility>
19  
#include <stddef.h> // ::max_align_t
19  
#include <stddef.h> // ::max_align_t
20  

20  

21  
namespace boost {
21  
namespace boost {
22  
namespace http {
22  
namespace http {
23  
namespace detail {
23  
namespace detail {
24  

24  

25  
/** A contiguous buffer of storage used by algorithms.
25  
/** A contiguous buffer of storage used by algorithms.
26  

26  

27  
    Objects of this type retain ownership of a
27  
    Objects of this type retain ownership of a
28  
    contiguous buffer of storage allocated upon
28  
    contiguous buffer of storage allocated upon
29  
    construction. This storage is divided into
29  
    construction. This storage is divided into
30  
    three regions:
30  
    three regions:
31  

31  

32  
    @code
32  
    @code
33  
    | front | free | acquired | back |
33  
    | front | free | acquired | back |
34  
    @endcode
34  
    @endcode
35  

35  

36  
    @li The reserved area, which starts at the
36  
    @li The reserved area, which starts at the
37  
        beginning of the buffer and can grow
37  
        beginning of the buffer and can grow
38  
        upwards towards the end of the buffer.
38  
        upwards towards the end of the buffer.
39  

39  

40  
    @li The acquired area, which starts at the
40  
    @li The acquired area, which starts at the
41  
        end of the buffer and can grow downwards
41  
        end of the buffer and can grow downwards
42  
        towards the beginning of the buffer.
42  
        towards the beginning of the buffer.
43  

43  

44  
    @li The unused area, which starts from the
44  
    @li The unused area, which starts from the
45  
        end of the reserved area and stretches
45  
        end of the reserved area and stretches
46  
        until the beginning of the acquired area.
46  
        until the beginning of the acquired area.
47  
*/
47  
*/
48  
class workspace
48  
class workspace
49  
{
49  
{
50  
    unsigned char* begin_ = nullptr;
50  
    unsigned char* begin_ = nullptr;
51  
    unsigned char* front_ = nullptr;
51  
    unsigned char* front_ = nullptr;
52  
    unsigned char* head_ = nullptr;
52  
    unsigned char* head_ = nullptr;
53  
    unsigned char* back_ = nullptr;
53  
    unsigned char* back_ = nullptr;
54  
    unsigned char* end_ = nullptr;
54  
    unsigned char* end_ = nullptr;
55  

55  

56  
    template<class>
56  
    template<class>
57  
    struct any_impl;
57  
    struct any_impl;
58  
    struct any;
58  
    struct any;
59  
    struct undo;
59  
    struct undo;
60  

60  

61  
public:
61  
public:
62  
    /** Return the number of aligned bytes required for T
62  
    /** Return the number of aligned bytes required for T
63  
    */
63  
    */
64  
    template<class T>
64  
    template<class T>
65  
    static
65  
    static
66  
    constexpr
66  
    constexpr
67  
    std::size_t
67  
    std::size_t
68  
    space_needed();
68  
    space_needed();
69  

69  

70  
    /** Destructor.
70  
    /** Destructor.
71  
    */
71  
    */
72  
    ~workspace();
72  
    ~workspace();
73  

73  

74  
    /** Constructor.
74  
    /** Constructor.
75  

75  

76  
        @param n The number of bytes of storage
76  
        @param n The number of bytes of storage
77  
            to allocate for the internal buffer.
77  
            to allocate for the internal buffer.
78  
    */
78  
    */
79  
    explicit
79  
    explicit
80  
    workspace(
80  
    workspace(
81  
        std::size_t n);
81  
        std::size_t n);
82  

82  

83  
    /** Constructor.
83  
    /** Constructor.
84  
    */
84  
    */
85  
    workspace() = default;
85  
    workspace() = default;
86  

86  

87  
    /** Constructor.
87  
    /** Constructor.
88  
    */
88  
    */
89  
    workspace(workspace&&) noexcept;
89  
    workspace(workspace&&) noexcept;
90  

90  

91  
    /** Assignment.
91  
    /** Assignment.
92  
    */
92  
    */
93  
    workspace&
93  
    workspace&
94  
    operator=(workspace&&) noexcept;
94  
    operator=(workspace&&) noexcept;
95  

95  

96  
    /** Allocate internal storage.
96  
    /** Allocate internal storage.
97  

97  

98  
        @throw std::logic_error this->size() > 0
98  
        @throw std::logic_error this->size() > 0
99  

99  

100  
        @throw std::invalid_argument n == 0
100  
        @throw std::invalid_argument n == 0
101  
    */
101  
    */
102  
    void
102  
    void
103  
    allocate(
103  
    allocate(
104  
        std::size_t n);
104  
        std::size_t n);
105  

105  

106  
    /** Return a pointer to the unused area.
106  
    /** Return a pointer to the unused area.
107  
    */
107  
    */
108  
    unsigned char*
108  
    unsigned char*
109  
    data() noexcept
109  
    data() noexcept
110  
    {
110  
    {
111  
        return front_;
111  
        return front_;
112  
    }
112  
    }
113  

113  

114  
    /** Return the size of the unused area.
114  
    /** Return the size of the unused area.
115  
    */
115  
    */
116  
    std::size_t
116  
    std::size_t
117  
    size() const noexcept
117  
    size() const noexcept
118  
    {
118  
    {
119  
        return head_ - front_;
119  
        return head_ - front_;
120  
    }
120  
    }
121  

121  

122  
    /** Clear the contents while preserving capacity.
122  
    /** Clear the contents while preserving capacity.
123  
    */
123  
    */
124  
    BOOST_HTTP_DECL
124  
    BOOST_HTTP_DECL
125  
    void
125  
    void
126  
    clear() noexcept;
126  
    clear() noexcept;
127  

127  

128  
    /** Convert unused storage to reserved storage.
128  
    /** Convert unused storage to reserved storage.
129  

129  

130  
        @throw std::invalid_argument n >= this->size()
130  
        @throw std::invalid_argument n >= this->size()
131  
    */
131  
    */
132  
    BOOST_HTTP_DECL
132  
    BOOST_HTTP_DECL
133  
    unsigned char*
133  
    unsigned char*
134  
    reserve_front(
134  
    reserve_front(
135  
        std::size_t n);
135  
        std::size_t n);
136  

136  

137  
    /** Convert unused storage to reserved storage.
137  
    /** Convert unused storage to reserved storage.
138  

138  

139  
        @return nullptr if n >= this->size() 
139  
        @return nullptr if n >= this->size() 
140  
    */
140  
    */
141  
    BOOST_HTTP_DECL
141  
    BOOST_HTTP_DECL
142  
    unsigned char*
142  
    unsigned char*
143  
    try_reserve_front(
143  
    try_reserve_front(
144  
        std::size_t n) noexcept;
144  
        std::size_t n) noexcept;
145  

145  

146  
    template<class T, class... Args>
146  
    template<class T, class... Args>
147  
    typename std::decay<T>::type&
147  
    typename std::decay<T>::type&
148  
    emplace(Args&&... args);
148  
    emplace(Args&&... args);
149  

149  

150  
    template<class T>
150  
    template<class T>
151  
    T*
151  
    T*
152  
    push_array(
152  
    push_array(
153  
        std::size_t n,
153  
        std::size_t n,
154  
        T const& t);
154  
        T const& t);
155  

155  

156  
    BOOST_HTTP_DECL
156  
    BOOST_HTTP_DECL
157  
    unsigned char*
157  
    unsigned char*
158  
    reserve_back(
158  
    reserve_back(
159  
        std::size_t n);
159  
        std::size_t n);
160  

160  

161  
private:
161  
private:
162  
    BOOST_HTTP_DECL
162  
    BOOST_HTTP_DECL
163  
    unsigned char*
163  
    unsigned char*
164  
    bump_down(
164  
    bump_down(
165  
        std::size_t size,
165  
        std::size_t size,
166  
        std::size_t align);
166  
        std::size_t align);
167  
};
167  
};
168  

168  

169  
} // detail
169  
} // detail
170  
} // http
170  
} // http
171  
} // boost
171  
} // boost
172  

172  

173  
#include <boost/http/detail/impl/workspace.hpp>
173  
#include <boost/http/detail/impl/workspace.hpp>
174  

174  

175  
#endif
175  
#endif