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