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