rippled
Loading...
Searching...
No Matches
Buffer_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github0.com/ripple/rippled
4 Copyright (c) 2012-2016 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/basics/Buffer.h>
21#include <xrpl/beast/unit_test.h>
22
23#include <cstdint>
24#include <type_traits>
25
26namespace ripple {
27namespace test {
28
30{
31 bool
32 sane(Buffer const& b) const
33 {
34 if (b.size() == 0)
35 return b.data() == nullptr;
36
37 return b.data() != nullptr;
38 }
39
40 void
41 run() override
42 {
43 std::uint8_t const data[] = {
44 0xa8, 0xa1, 0x38, 0x45, 0x23, 0xec, 0xe4, 0x23, 0x71, 0x6d, 0x2a,
45 0x18, 0xb4, 0x70, 0xcb, 0xf5, 0xac, 0x2d, 0x89, 0x4d, 0x19, 0x9c,
46 0xf0, 0x2c, 0x15, 0xd1, 0xf9, 0x9b, 0x66, 0xd2, 0x30, 0xd3};
47
48 Buffer b0;
49 BEAST_EXPECT(sane(b0));
50 BEAST_EXPECT(b0.empty());
51
52 Buffer b1{0};
53 BEAST_EXPECT(sane(b1));
54 BEAST_EXPECT(b1.empty());
55 std::memcpy(b1.alloc(16), data, 16);
56 BEAST_EXPECT(sane(b1));
57 BEAST_EXPECT(!b1.empty());
58 BEAST_EXPECT(b1.size() == 16);
59
60 Buffer b2{b1.size()};
61 BEAST_EXPECT(sane(b2));
62 BEAST_EXPECT(!b2.empty());
63 BEAST_EXPECT(b2.size() == b1.size());
64 std::memcpy(b2.data(), data + 16, 16);
65
66 Buffer b3{data, sizeof(data)};
67 BEAST_EXPECT(sane(b3));
68 BEAST_EXPECT(!b3.empty());
69 BEAST_EXPECT(b3.size() == sizeof(data));
70 BEAST_EXPECT(std::memcmp(b3.data(), data, b3.size()) == 0);
71
72 // Check equality and inequality comparisons
73 BEAST_EXPECT(b0 == b0);
74 BEAST_EXPECT(b0 != b1);
75 BEAST_EXPECT(b1 == b1);
76 BEAST_EXPECT(b1 != b2);
77 BEAST_EXPECT(b2 != b3);
78
79 // Check copy constructors and copy assignments:
80 {
81 testcase("Copy Construction / Assignment");
82
83 Buffer x{b0};
84 BEAST_EXPECT(x == b0);
85 BEAST_EXPECT(sane(x));
86 Buffer y{b1};
87 BEAST_EXPECT(y == b1);
88 BEAST_EXPECT(sane(y));
89 x = b2;
90 BEAST_EXPECT(x == b2);
91 BEAST_EXPECT(sane(x));
92 x = y;
93 BEAST_EXPECT(x == y);
94 BEAST_EXPECT(sane(x));
95 y = b3;
96 BEAST_EXPECT(y == b3);
97 BEAST_EXPECT(sane(y));
98 x = b0;
99 BEAST_EXPECT(x == b0);
100 BEAST_EXPECT(sane(x));
101#if defined(__clang__)
102#pragma clang diagnostic push
103#pragma clang diagnostic ignored "-Wself-assign-overloaded"
104#endif
105
106 x = x;
107 BEAST_EXPECT(x == b0);
108 BEAST_EXPECT(sane(x));
109 y = y;
110 BEAST_EXPECT(y == b3);
111 BEAST_EXPECT(sane(y));
112
113#if defined(__clang__)
114#pragma clang diagnostic pop
115#endif
116 }
117
118 // Check move constructor & move assignments:
119 {
120 testcase("Move Construction / Assignment");
121
122 static_assert(
125
126 { // Move-construct from empty buf
127 Buffer x;
128 Buffer y{std::move(x)};
129 BEAST_EXPECT(sane(x));
130 BEAST_EXPECT(x.empty());
131 BEAST_EXPECT(sane(y));
132 BEAST_EXPECT(y.empty());
133 BEAST_EXPECT(x == y);
134 }
135
136 { // Move-construct from non-empty buf
137 Buffer x{b1};
138 Buffer y{std::move(x)};
139 BEAST_EXPECT(sane(x));
140 BEAST_EXPECT(x.empty());
141 BEAST_EXPECT(sane(y));
142 BEAST_EXPECT(y == b1);
143 }
144
145 { // Move assign empty buf to empty buf
146 Buffer x;
147 Buffer y;
148
149 x = std::move(y);
150 BEAST_EXPECT(sane(x));
151 BEAST_EXPECT(x.empty());
152 BEAST_EXPECT(sane(y));
153 BEAST_EXPECT(y.empty());
154 }
155
156 { // Move assign non-empty buf to empty buf
157 Buffer x;
158 Buffer y{b1};
159
160 x = std::move(y);
161 BEAST_EXPECT(sane(x));
162 BEAST_EXPECT(x == b1);
163 BEAST_EXPECT(sane(y));
164 BEAST_EXPECT(y.empty());
165 }
166
167 { // Move assign empty buf to non-empty buf
168 Buffer x{b1};
169 Buffer y;
170
171 x = std::move(y);
172 BEAST_EXPECT(sane(x));
173 BEAST_EXPECT(x.empty());
174 BEAST_EXPECT(sane(y));
175 BEAST_EXPECT(y.empty());
176 }
177
178 { // Move assign non-empty buf to non-empty buf
179 Buffer x{b1};
180 Buffer y{b2};
181 Buffer z{b3};
182
183 x = std::move(y);
184 BEAST_EXPECT(sane(x));
185 BEAST_EXPECT(!x.empty());
186 BEAST_EXPECT(sane(y));
187 BEAST_EXPECT(y.empty());
188
189 x = std::move(z);
190 BEAST_EXPECT(sane(x));
191 BEAST_EXPECT(!x.empty());
192 BEAST_EXPECT(sane(z));
193 BEAST_EXPECT(z.empty());
194 }
195 }
196
197 {
198 testcase("Slice Conversion / Construction / Assignment");
199
200 Buffer w{static_cast<Slice>(b0)};
201 BEAST_EXPECT(sane(w));
202 BEAST_EXPECT(w == b0);
203
204 Buffer x{static_cast<Slice>(b1)};
205 BEAST_EXPECT(sane(x));
206 BEAST_EXPECT(x == b1);
207
208 Buffer y{static_cast<Slice>(b2)};
209 BEAST_EXPECT(sane(y));
210 BEAST_EXPECT(y == b2);
211
212 Buffer z{static_cast<Slice>(b3)};
213 BEAST_EXPECT(sane(z));
214 BEAST_EXPECT(z == b3);
215
216 // Assign empty slice to empty buffer
217 w = static_cast<Slice>(b0);
218 BEAST_EXPECT(sane(w));
219 BEAST_EXPECT(w == b0);
220
221 // Assign non-empty slice to empty buffer
222 w = static_cast<Slice>(b1);
223 BEAST_EXPECT(sane(w));
224 BEAST_EXPECT(w == b1);
225
226 // Assign non-empty slice to non-empty buffer
227 x = static_cast<Slice>(b2);
228 BEAST_EXPECT(sane(x));
229 BEAST_EXPECT(x == b2);
230
231 // Assign non-empty slice to non-empty buffer
232 y = static_cast<Slice>(z);
233 BEAST_EXPECT(sane(y));
234 BEAST_EXPECT(y == z);
235
236 // Assign empty slice to non-empty buffer:
237 z = static_cast<Slice>(b0);
238 BEAST_EXPECT(sane(z));
239 BEAST_EXPECT(z == b0);
240 }
241
242 {
243 testcase("Allocation, Deallocation and Clearing");
244
245 auto test = [this](Buffer const& b, std::size_t i) {
246 Buffer x{b};
247
248 // Try to allocate some number of bytes, possibly
249 // zero (which means clear) and sanity check
250 x(i);
251 BEAST_EXPECT(sane(x));
252 BEAST_EXPECT(x.size() == i);
253 BEAST_EXPECT((x.data() == nullptr) == (i == 0));
254
255 // Try to allocate some more data (always non-zero)
256 x(i + 1);
257 BEAST_EXPECT(sane(x));
258 BEAST_EXPECT(x.size() == i + 1);
259 BEAST_EXPECT(x.data() != nullptr);
260
261 // Try to clear:
262 x.clear();
263 BEAST_EXPECT(sane(x));
264 BEAST_EXPECT(x.size() == 0);
265 BEAST_EXPECT(x.data() == nullptr);
266
267 // Try to clear again:
268 x.clear();
269 BEAST_EXPECT(sane(x));
270 BEAST_EXPECT(x.size() == 0);
271 BEAST_EXPECT(x.data() == nullptr);
272 };
273
274 for (std::size_t i = 0; i < 16; ++i)
275 {
276 test(b0, i);
277 test(b1, i);
278 }
279 }
280 }
281};
282
283BEAST_DEFINE_TESTSUITE(Buffer, ripple_basics, ripple);
284
285} // namespace test
286} // namespace ripple
A testsuite class.
Definition: suite.h:55
testcase_t testcase
Memberspace for declaring test cases.
Definition: suite.h:155
Like std::vector<char> but better.
Definition: Buffer.h:36
std::size_t size() const noexcept
Returns the number of bytes in the buffer.
Definition: Buffer.h:127
bool empty() const noexcept
Definition: Buffer.h:133
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition: Buffer.h:151
An immutable linear range of bytes.
Definition: Slice.h:46
T memcmp(T... args)
T memcpy(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:25
bool sane(Buffer const &b) const
Definition: Buffer_test.cpp:32
void run() override
Runs the suite.
Definition: Buffer_test.cpp:41