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/const_buffer.hpp>
14 : #include <boost/buffers/mutable_buffer.hpp>
15 : #include <boost/buffers/detail/except.hpp>
16 : #include <boost/assert.hpp>
17 :
18 : namespace boost {
19 : namespace buffers {
20 :
21 : /** A DynamicBuffer with a fixed capacity.
22 :
23 : Buffer sequences returned by this container
24 : always have a single element.
25 : */
26 : class flat_buffer
27 : {
28 : unsigned char* data_ = nullptr;
29 : std::size_t cap_ = 0;
30 : std::size_t in_pos_ = 0;
31 : std::size_t in_size_ = 0;
32 : std::size_t out_size_ = 0;
33 :
34 : public:
35 : using const_buffers_type =
36 : const_buffer;
37 :
38 : using mutable_buffers_type =
39 : mutable_buffer;
40 :
41 : /** Constructor.
42 : */
43 : flat_buffer() = default;
44 :
45 : /** Constructor.
46 : */
47 43 : flat_buffer(
48 : void* data,
49 : std::size_t capacity,
50 : std::size_t initial_size = 0)
51 43 : : data_(static_cast<
52 : unsigned char*>(data))
53 43 : , cap_(capacity)
54 43 : , in_size_(initial_size)
55 : {
56 : // initial size too large
57 43 : if(in_size_ > cap_)
58 1 : detail::throw_invalid_argument();
59 42 : }
60 :
61 : /** Constructor.
62 : */
63 : explicit
64 2 : flat_buffer(
65 : mutable_buffer const& b,
66 : std::size_t initial_size = 0)
67 2 : : flat_buffer(
68 : b.data(),
69 : b.size(),
70 2 : initial_size)
71 : {
72 2 : }
73 :
74 : /** Constructor.
75 : */
76 : flat_buffer(
77 : flat_buffer const&) = default;
78 :
79 : /** Constructor.
80 : */
81 : flat_buffer& operator=(
82 : flat_buffer const&) = default;
83 :
84 : std::size_t
85 42 : size() const noexcept
86 : {
87 42 : return in_size_;
88 : }
89 :
90 : std::size_t
91 12 : max_size() const noexcept
92 : {
93 12 : return cap_;
94 : }
95 :
96 : std::size_t
97 110 : capacity() const noexcept
98 : {
99 110 : return cap_ - (in_pos_ + in_size_);
100 : }
101 :
102 : const_buffers_type
103 49 : data() const noexcept
104 : {
105 : return {
106 49 : data_ + in_pos_,
107 49 : in_size_ };
108 : }
109 :
110 : mutable_buffers_type
111 67 : prepare(std::size_t n)
112 : {
113 : // n exceeds available space
114 67 : if( n > capacity() )
115 3 : detail::throw_invalid_argument();
116 :
117 64 : out_size_ = n;
118 64 : return { data_ +
119 64 : in_pos_ + in_size_, n };
120 : }
121 :
122 : void
123 48 : commit(
124 : std::size_t n) noexcept
125 : {
126 48 : if(n < out_size_)
127 15 : in_size_ += n;
128 : else
129 33 : in_size_ += out_size_;
130 48 : out_size_ = 0;
131 48 : }
132 :
133 : void
134 32 : consume(
135 : std::size_t n) noexcept
136 : {
137 32 : if(n < in_size_)
138 : {
139 30 : in_pos_ += n;
140 30 : in_size_ -= n;
141 : }
142 : else
143 : {
144 2 : in_pos_ = 0;
145 2 : in_size_ = 0;
146 : }
147 32 : }
148 : };
149 :
150 : } // buffers
151 : } // boost
152 :
153 : #endif
|