rippled
Loading...
Searching...
No Matches
Buffer_test.cpp
1#include <xrpl/basics/Buffer.h>
2#include <xrpl/beast/unit_test.h>
3
4#include <cstdint>
5#include <type_traits>
6
7namespace ripple {
8namespace test {
9
11{
12 bool
13 sane(Buffer const& b) const
14 {
15 if (b.size() == 0)
16 return b.data() == nullptr;
17
18 return b.data() != nullptr;
19 }
20
21 void
22 run() override
23 {
24 std::uint8_t const data[] = {
25 0xa8, 0xa1, 0x38, 0x45, 0x23, 0xec, 0xe4, 0x23, 0x71, 0x6d, 0x2a,
26 0x18, 0xb4, 0x70, 0xcb, 0xf5, 0xac, 0x2d, 0x89, 0x4d, 0x19, 0x9c,
27 0xf0, 0x2c, 0x15, 0xd1, 0xf9, 0x9b, 0x66, 0xd2, 0x30, 0xd3};
28
29 Buffer b0;
30 BEAST_EXPECT(sane(b0));
31 BEAST_EXPECT(b0.empty());
32
33 Buffer b1{0};
34 BEAST_EXPECT(sane(b1));
35 BEAST_EXPECT(b1.empty());
36 std::memcpy(b1.alloc(16), data, 16);
37 BEAST_EXPECT(sane(b1));
38 BEAST_EXPECT(!b1.empty());
39 BEAST_EXPECT(b1.size() == 16);
40
41 Buffer b2{b1.size()};
42 BEAST_EXPECT(sane(b2));
43 BEAST_EXPECT(!b2.empty());
44 BEAST_EXPECT(b2.size() == b1.size());
45 std::memcpy(b2.data(), data + 16, 16);
46
47 Buffer b3{data, sizeof(data)};
48 BEAST_EXPECT(sane(b3));
49 BEAST_EXPECT(!b3.empty());
50 BEAST_EXPECT(b3.size() == sizeof(data));
51 BEAST_EXPECT(std::memcmp(b3.data(), data, b3.size()) == 0);
52
53 // Check equality and inequality comparisons
54 BEAST_EXPECT(b0 == b0);
55 BEAST_EXPECT(b0 != b1);
56 BEAST_EXPECT(b1 == b1);
57 BEAST_EXPECT(b1 != b2);
58 BEAST_EXPECT(b2 != b3);
59
60 // Check copy constructors and copy assignments:
61 {
62 testcase("Copy Construction / Assignment");
63
64 Buffer x{b0};
65 BEAST_EXPECT(x == b0);
66 BEAST_EXPECT(sane(x));
67 Buffer y{b1};
68 BEAST_EXPECT(y == b1);
69 BEAST_EXPECT(sane(y));
70 x = b2;
71 BEAST_EXPECT(x == b2);
72 BEAST_EXPECT(sane(x));
73 x = y;
74 BEAST_EXPECT(x == y);
75 BEAST_EXPECT(sane(x));
76 y = b3;
77 BEAST_EXPECT(y == b3);
78 BEAST_EXPECT(sane(y));
79 x = b0;
80 BEAST_EXPECT(x == b0);
81 BEAST_EXPECT(sane(x));
82#if defined(__clang__)
83#pragma clang diagnostic push
84#pragma clang diagnostic ignored "-Wself-assign-overloaded"
85#endif
86
87 x = x;
88 BEAST_EXPECT(x == b0);
89 BEAST_EXPECT(sane(x));
90 y = y;
91 BEAST_EXPECT(y == b3);
92 BEAST_EXPECT(sane(y));
93
94#if defined(__clang__)
95#pragma clang diagnostic pop
96#endif
97 }
98
99 // Check move constructor & move assignments:
100 {
101 testcase("Move Construction / Assignment");
102
103 static_assert(
106
107 { // Move-construct from empty buf
108 Buffer x;
109 Buffer y{std::move(x)};
110 BEAST_EXPECT(sane(x));
111 BEAST_EXPECT(x.empty());
112 BEAST_EXPECT(sane(y));
113 BEAST_EXPECT(y.empty());
114 BEAST_EXPECT(x == y);
115 }
116
117 { // Move-construct from non-empty buf
118 Buffer x{b1};
119 Buffer y{std::move(x)};
120 BEAST_EXPECT(sane(x));
121 BEAST_EXPECT(x.empty());
122 BEAST_EXPECT(sane(y));
123 BEAST_EXPECT(y == b1);
124 }
125
126 { // Move assign empty buf to empty buf
127 Buffer x;
128 Buffer y;
129
130 x = std::move(y);
131 BEAST_EXPECT(sane(x));
132 BEAST_EXPECT(x.empty());
133 BEAST_EXPECT(sane(y));
134 BEAST_EXPECT(y.empty());
135 }
136
137 { // Move assign non-empty buf to empty buf
138 Buffer x;
139 Buffer y{b1};
140
141 x = std::move(y);
142 BEAST_EXPECT(sane(x));
143 BEAST_EXPECT(x == b1);
144 BEAST_EXPECT(sane(y));
145 BEAST_EXPECT(y.empty());
146 }
147
148 { // Move assign empty buf to non-empty buf
149 Buffer x{b1};
150 Buffer y;
151
152 x = std::move(y);
153 BEAST_EXPECT(sane(x));
154 BEAST_EXPECT(x.empty());
155 BEAST_EXPECT(sane(y));
156 BEAST_EXPECT(y.empty());
157 }
158
159 { // Move assign non-empty buf to non-empty buf
160 Buffer x{b1};
161 Buffer y{b2};
162 Buffer z{b3};
163
164 x = std::move(y);
165 BEAST_EXPECT(sane(x));
166 BEAST_EXPECT(!x.empty());
167 BEAST_EXPECT(sane(y));
168 BEAST_EXPECT(y.empty());
169
170 x = std::move(z);
171 BEAST_EXPECT(sane(x));
172 BEAST_EXPECT(!x.empty());
173 BEAST_EXPECT(sane(z));
174 BEAST_EXPECT(z.empty());
175 }
176 }
177
178 {
179 testcase("Slice Conversion / Construction / Assignment");
180
181 Buffer w{static_cast<Slice>(b0)};
182 BEAST_EXPECT(sane(w));
183 BEAST_EXPECT(w == b0);
184
185 Buffer x{static_cast<Slice>(b1)};
186 BEAST_EXPECT(sane(x));
187 BEAST_EXPECT(x == b1);
188
189 Buffer y{static_cast<Slice>(b2)};
190 BEAST_EXPECT(sane(y));
191 BEAST_EXPECT(y == b2);
192
193 Buffer z{static_cast<Slice>(b3)};
194 BEAST_EXPECT(sane(z));
195 BEAST_EXPECT(z == b3);
196
197 // Assign empty slice to empty buffer
198 w = static_cast<Slice>(b0);
199 BEAST_EXPECT(sane(w));
200 BEAST_EXPECT(w == b0);
201
202 // Assign non-empty slice to empty buffer
203 w = static_cast<Slice>(b1);
204 BEAST_EXPECT(sane(w));
205 BEAST_EXPECT(w == b1);
206
207 // Assign non-empty slice to non-empty buffer
208 x = static_cast<Slice>(b2);
209 BEAST_EXPECT(sane(x));
210 BEAST_EXPECT(x == b2);
211
212 // Assign non-empty slice to non-empty buffer
213 y = static_cast<Slice>(z);
214 BEAST_EXPECT(sane(y));
215 BEAST_EXPECT(y == z);
216
217 // Assign empty slice to non-empty buffer:
218 z = static_cast<Slice>(b0);
219 BEAST_EXPECT(sane(z));
220 BEAST_EXPECT(z == b0);
221 }
222
223 {
224 testcase("Allocation, Deallocation and Clearing");
225
226 auto test = [this](Buffer const& b, std::size_t i) {
227 Buffer x{b};
228
229 // Try to allocate some number of bytes, possibly
230 // zero (which means clear) and sanity check
231 x(i);
232 BEAST_EXPECT(sane(x));
233 BEAST_EXPECT(x.size() == i);
234 BEAST_EXPECT((x.data() == nullptr) == (i == 0));
235
236 // Try to allocate some more data (always non-zero)
237 x(i + 1);
238 BEAST_EXPECT(sane(x));
239 BEAST_EXPECT(x.size() == i + 1);
240 BEAST_EXPECT(x.data() != nullptr);
241
242 // Try to clear:
243 x.clear();
244 BEAST_EXPECT(sane(x));
245 BEAST_EXPECT(x.size() == 0);
246 BEAST_EXPECT(x.data() == nullptr);
247
248 // Try to clear again:
249 x.clear();
250 BEAST_EXPECT(sane(x));
251 BEAST_EXPECT(x.size() == 0);
252 BEAST_EXPECT(x.data() == nullptr);
253 };
254
255 for (std::size_t i = 0; i < 16; ++i)
256 {
257 test(b0, i);
258 test(b1, i);
259 }
260 }
261 }
262};
263
264BEAST_DEFINE_TESTSUITE(Buffer, basics, ripple);
265
266} // namespace test
267} // namespace ripple
A testsuite class.
Definition suite.h:52
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:152
Like std::vector<char> but better.
Definition Buffer.h:17
std::size_t size() const noexcept
Returns the number of bytes in the buffer.
Definition Buffer.h:108
bool empty() const noexcept
Definition Buffer.h:114
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition Buffer.h:132
An immutable linear range of bytes.
Definition Slice.h:27
T memcmp(T... args)
T memcpy(T... args)
auto const data
General field definitions, or fields used in multiple transaction namespaces.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
bool sane(Buffer const &b) const
void run() override
Runs the suite.