Line data Source code
1 : //
2 : // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.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/cppalliance/buffers
8 : //
9 :
10 : #ifndef BOOST_BUFFERS_FLAT_BUFFER_HPP
11 : #define BOOST_BUFFERS_FLAT_BUFFER_HPP
12 :
13 : #include <boost/buffers/detail/config.hpp>
14 : #include <boost/buffers/buffer.hpp>
15 : #include <boost/buffers/detail/except.hpp>
16 :
17 : namespace boost {
18 : namespace buffers {
19 :
20 : /** A DynamicBuffer with a fixed capacity.
21 :
22 : Buffer sequences returned by this container
23 : always have a single element.
24 : */
25 : class flat_buffer
26 : {
27 : unsigned char* data_ = nullptr;
28 : std::size_t cap_ = 0;
29 : std::size_t in_pos_ = 0;
30 : std::size_t in_size_ = 0;
31 : std::size_t out_size_ = 0;
32 :
33 : public:
34 : using const_buffers_type = const_buffer;
35 : using mutable_buffers_type = mutable_buffer;
36 :
37 : /** Constructor.
38 :
39 : Default constructed objects have zero capacity.
40 : */
41 : flat_buffer() = default;
42 :
43 : /** Constructor.
44 :
45 : @param data A pointer to the memory to use for the buffer.
46 : @param capacity The size of the memory pointed to by @p data.
47 : @param initial_size The initial size of the readable bytes.
48 : This must be less than or equal to @p capacity.
49 : */
50 41 : flat_buffer(
51 : void* data,
52 : std::size_t capacity,
53 : std::size_t initial_size = 0)
54 41 : : data_(static_cast<
55 : unsigned char*>(data))
56 41 : , cap_(capacity)
57 41 : , in_size_(initial_size)
58 : {
59 : // initial size too large
60 41 : if(in_size_ > cap_)
61 1 : detail::throw_invalid_argument();
62 40 : }
63 :
64 : /** Constructor.
65 : */
66 : flat_buffer(
67 : flat_buffer const&) = default;
68 :
69 : /** Constructor.
70 : */
71 : flat_buffer& operator=(
72 : flat_buffer const&) = default;
73 :
74 : std::size_t
75 40 : size() const noexcept
76 : {
77 40 : return in_size_;
78 : }
79 :
80 : /** Returns the maximum size of the buffer.
81 : */
82 : std::size_t
83 10 : max_size() const noexcept
84 : {
85 10 : return cap_;
86 : }
87 :
88 : /** Returns the total number of writable bytes.
89 : */
90 : std::size_t
91 108 : capacity() const noexcept
92 : {
93 108 : return cap_ - (in_pos_ + in_size_);
94 : }
95 :
96 : /** Returns a constant buffer sequence representing the readable bytes.
97 : */
98 : const_buffers_type
99 49 : data() const noexcept
100 : {
101 98 : return const_buffers_type(
102 49 : data_ + in_pos_, in_size_);
103 : }
104 :
105 : /** Returns a mutable buffer sequence representing the writable bytes.
106 : All buffer sequences previously obtained
107 : using @ref prepare become invalid.
108 : @param n The desired number of bytes in the
109 : returned buffer sequence.
110 : */
111 : mutable_buffers_type
112 67 : prepare(std::size_t n)
113 : {
114 : // n exceeds available space
115 67 : if( n > capacity() )
116 3 : detail::throw_invalid_argument();
117 :
118 64 : out_size_ = n;
119 128 : return mutable_buffers_type(
120 64 : data_ + in_pos_ + in_size_, n);
121 : }
122 :
123 : /** Commit bytes to the input sequence.
124 : @param n The number of bytes to commit.
125 : */
126 : void
127 48 : commit(
128 : std::size_t n) noexcept
129 : {
130 48 : if(n < out_size_)
131 15 : in_size_ += n;
132 : else
133 33 : in_size_ += out_size_;
134 48 : out_size_ = 0;
135 48 : }
136 :
137 : /** Consume bytes from the input sequence.
138 : @param n The number of bytes to consume.
139 : */
140 : void
141 32 : consume(
142 : std::size_t n) noexcept
143 : {
144 32 : if(n < in_size_)
145 : {
146 30 : in_pos_ += n;
147 30 : in_size_ -= n;
148 : }
149 : else
150 : {
151 2 : in_pos_ = 0;
152 2 : in_size_ = 0;
153 : }
154 32 : }
155 : };
156 :
157 : } // buffers
158 : } // boost
159 :
160 : #endif
|