rippled
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 <ripple/basics/Buffer.h>
21 #include <ripple/beast/unit_test.h>
22 #include <cstdint>
23 #include <type_traits>
24 
25 namespace ripple {
26 namespace test {
27 
28 struct Buffer_test : beast::unit_test::suite
29 {
30  bool sane (Buffer const& b) const
31  {
32  if (b.size() == 0)
33  return b.data() == nullptr;
34 
35  return b.data() != nullptr;
36  }
37 
38  void run() override
39  {
40  std::uint8_t const data[] =
41  {
42  0xa8, 0xa1, 0x38, 0x45, 0x23, 0xec, 0xe4, 0x23,
43  0x71, 0x6d, 0x2a, 0x18, 0xb4, 0x70, 0xcb, 0xf5,
44  0xac, 0x2d, 0x89, 0x4d, 0x19, 0x9c, 0xf0, 0x2c,
45  0x15, 0xd1, 0xf9, 0x9b, 0x66, 0xd2, 0x30, 0xd3
46  };
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  (!defined(__APPLE__) && (__clang_major__ >= 7)) || \
103  (defined(__APPLE__) && (__apple_build_version__ >= 10010043))
104 #pragma clang diagnostic push
105 #pragma clang diagnostic ignored "-Wself-assign-overloaded"
106 #endif
107 
108  x = x;
109  BEAST_EXPECT (x == b0);
110  BEAST_EXPECT (sane (x));
111  y = y;
112  BEAST_EXPECT (y == b3);
113  BEAST_EXPECT (sane (y));
114 
115 #if defined(__clang__) && \
116  (!defined(__APPLE__) && (__clang_major__ >= 7)) || \
117  (defined(__APPLE__) && (__apple_build_version__ >= 10010043))
118 #pragma clang diagnostic pop
119 #endif
120  }
121 
122  // Check move constructor & move assignments:
123  {
124  testcase ("Move Construction / Assignment");
125 
128 
129  { // Move-construct from empty buf
130  Buffer x;
131  Buffer y { std::move(x) };
132  BEAST_EXPECT (sane(x));
133  BEAST_EXPECT (x.empty());
134  BEAST_EXPECT (sane(y));
135  BEAST_EXPECT (y.empty());
136  BEAST_EXPECT (x == y);
137  }
138 
139  { // Move-construct from non-empty buf
140  Buffer x { b1 };
141  Buffer y { std::move(x) };
142  BEAST_EXPECT (sane(x));
143  BEAST_EXPECT (x.empty());
144  BEAST_EXPECT (sane(y));
145  BEAST_EXPECT (y == b1);
146  }
147 
148  { // Move assign empty buf to empty buf
149  Buffer x;
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 empty buf
160  Buffer x;
161  Buffer y { b1 };
162 
163  x = std::move(y);
164  BEAST_EXPECT (sane(x));
165  BEAST_EXPECT (x == b1);
166  BEAST_EXPECT (sane(y));
167  BEAST_EXPECT (y.empty());
168  }
169 
170  { // Move assign empty buf to non-empty buf
171  Buffer x { b1 };
172  Buffer y;
173 
174  x = std::move(y);
175  BEAST_EXPECT (sane(x));
176  BEAST_EXPECT (x.empty());
177  BEAST_EXPECT (sane(y));
178  BEAST_EXPECT (y.empty());
179  }
180 
181  { // Move assign non-empty buf to non-empty buf
182  Buffer x { b1 };
183  Buffer y { b2 };
184  Buffer z { b3 };
185 
186  x = std::move(y);
187  BEAST_EXPECT (sane(x));
188  BEAST_EXPECT (!x.empty());
189  BEAST_EXPECT (sane(y));
190  BEAST_EXPECT (y.empty());
191 
192  x = std::move(z);
193  BEAST_EXPECT (sane(x));
194  BEAST_EXPECT (!x.empty());
195  BEAST_EXPECT (sane(z));
196  BEAST_EXPECT (z.empty());
197  }
198  }
199 
200  {
201  testcase ("Slice Conversion / Construction / Assignment");
202 
203  Buffer w { static_cast<Slice>(b0) };
204  BEAST_EXPECT(sane(w));
205  BEAST_EXPECT(w == b0);
206 
207  Buffer x { static_cast<Slice>(b1) };
208  BEAST_EXPECT(sane(x));
209  BEAST_EXPECT(x == b1);
210 
211  Buffer y { static_cast<Slice>(b2) };
212  BEAST_EXPECT(sane(y));
213  BEAST_EXPECT(y == b2);
214 
215  Buffer z { static_cast<Slice>(b3) };
216  BEAST_EXPECT(sane(z));
217  BEAST_EXPECT(z == b3);
218 
219  // Assign empty slice to empty buffer
220  w = static_cast<Slice>(b0);
221  BEAST_EXPECT(sane(w));
222  BEAST_EXPECT(w == b0);
223 
224  // Assign non-empty slice to empty buffer
225  w = static_cast<Slice>(b1);
226  BEAST_EXPECT(sane(w));
227  BEAST_EXPECT(w == b1);
228 
229  // Assign non-empty slice to non-empty buffer
230  x = static_cast<Slice>(b2);
231  BEAST_EXPECT(sane(x));
232  BEAST_EXPECT(x == b2);
233 
234  // Assign non-empty slice to non-empty buffer
235  y = static_cast<Slice>(z);
236  BEAST_EXPECT(sane(y));
237  BEAST_EXPECT(y == z);
238 
239  // Assign empty slice to non-empty buffer:
240  z = static_cast<Slice>(b0);
241  BEAST_EXPECT(sane(z));
242  BEAST_EXPECT (z == b0);
243  }
244 
245  {
246  testcase ("Allocation, Deallocation and Clearing");
247 
248  auto test = [this](Buffer const& b, std::size_t i)
249  {
250  Buffer x{b};
251 
252  // Try to allocate some number of bytes, possibly
253  // zero (which means clear) and sanity check
254  x(i);
255  BEAST_EXPECT (sane(x));
256  BEAST_EXPECT (x.size() == i);
257  BEAST_EXPECT ((x.data() == nullptr) == (i == 0));
258 
259  // Try to allocate some more data (always non-zero)
260  x(i + 1);
261  BEAST_EXPECT (sane(x));
262  BEAST_EXPECT (x.size() == i + 1);
263  BEAST_EXPECT (x.data() != nullptr);
264 
265  // Try to clear:
266  x.clear();
267  BEAST_EXPECT (sane(x));
268  BEAST_EXPECT (x.size() == 0);
269  BEAST_EXPECT (x.data() == nullptr);
270 
271  // Try to clear again:
272  x.clear();
273  BEAST_EXPECT (sane(x));
274  BEAST_EXPECT (x.size() == 0);
275  BEAST_EXPECT (x.data() == nullptr);
276  };
277 
278  for (std::size_t i = 0; i < 16; ++i)
279  {
280  test (b0, i);
281  test (b1, i);
282  }
283  }
284  }
285 };
286 
287 BEAST_DEFINE_TESTSUITE(Buffer, ripple_basics, ripple);
288 
289 } // namespace test
290 } // namespace ripple
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountDelete, app, ripple)
ripple::Slice
An immutable linear range of bytes.
Definition: Slice.h:43
ripple::Buffer::empty
bool empty() const noexcept
Definition: Buffer.h:136
ripple::Buffer
Like std::vector<char> but better.
Definition: Buffer.h:35
ripple::test::Buffer_test::sane
bool sane(Buffer const &b) const
Definition: Buffer_test.cpp:30
std::is_nothrow_move_constructible
ripple::test::Buffer_test
Definition: Buffer_test.cpp:28
ripple::Buffer::size
std::size_t size() const noexcept
Returns the number of bytes in the buffer.
Definition: Buffer.h:130
cstdint
ripple::Buffer::data
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition: Buffer.h:154
std::uint8_t
std::is_nothrow_move_assignable
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::Buffer_test::run
void run() override
Definition: Buffer_test.cpp:38
std::size_t
std::memcpy
T memcpy(T... args)
std::memcmp
T memcmp(T... args)
type_traits