blob: 5cd18891b911a9dfec213c708178863178479ccf [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:261/*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 04:47:3111#include "rtc_base/buffer.h"
kwibergd3134032016-09-05 14:46:2012
Mirko Bonadei92ea95e2017-09-15 04:47:3113#include "api/array_view.h"
14#include "rtc_base/gunit.h"
henrike@webrtc.orgf0488722014-05-13 18:00:2615
kwiberga4ac4782016-04-29 15:00:2216#include <type_traits>
17#include <utility>
Karl Wiberg94784372015-04-20 12:03:0718
henrike@webrtc.orgf0488722014-05-13 18:00:2619namespace rtc {
20
Karl Wiberg94784372015-04-20 12:03:0721namespace {
henrike@webrtc.orgf0488722014-05-13 18:00:2622
Karl Wiberg94784372015-04-20 12:03:0723// clang-format off
24const uint8_t kTestData[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
25 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
26// clang-format on
27
28void TestBuf(const Buffer& b1, size_t size, size_t capacity) {
29 EXPECT_EQ(b1.size(), size);
30 EXPECT_EQ(b1.capacity(), capacity);
henrike@webrtc.orgf0488722014-05-13 18:00:2631}
32
Karl Wiberg94784372015-04-20 12:03:0733} // namespace
34
35TEST(BufferTest, TestConstructEmpty) {
36 TestBuf(Buffer(), 0, 0);
37 TestBuf(Buffer(Buffer()), 0, 0);
38 TestBuf(Buffer(0), 0, 0);
39
40 // We can't use a literal 0 for the first argument, because C++ will allow
41 // that to be considered a null pointer, which makes the call ambiguous.
42 TestBuf(Buffer(0 + 0, 10), 0, 10);
43
44 TestBuf(Buffer(kTestData, 0), 0, 0);
45 TestBuf(Buffer(kTestData, 0, 20), 0, 20);
henrike@webrtc.orgf0488722014-05-13 18:00:2646}
47
48TEST(BufferTest, TestConstructData) {
Karl Wiberg94784372015-04-20 12:03:0749 Buffer buf(kTestData, 7);
50 EXPECT_EQ(buf.size(), 7u);
51 EXPECT_EQ(buf.capacity(), 7u);
ossu5955e242016-08-31 15:40:0452 EXPECT_FALSE(buf.empty());
Karl Wiberg94784372015-04-20 12:03:0753 EXPECT_EQ(0, memcmp(buf.data(), kTestData, 7));
henrike@webrtc.orgf0488722014-05-13 18:00:2654}
55
56TEST(BufferTest, TestConstructDataWithCapacity) {
Karl Wiberg94784372015-04-20 12:03:0757 Buffer buf(kTestData, 7, 14);
58 EXPECT_EQ(buf.size(), 7u);
59 EXPECT_EQ(buf.capacity(), 14u);
ossu5955e242016-08-31 15:40:0460 EXPECT_FALSE(buf.empty());
Karl Wiberg94784372015-04-20 12:03:0761 EXPECT_EQ(0, memcmp(buf.data(), kTestData, 7));
62}
63
64TEST(BufferTest, TestConstructArray) {
65 Buffer buf(kTestData);
66 EXPECT_EQ(buf.size(), 16u);
67 EXPECT_EQ(buf.capacity(), 16u);
ossu5955e242016-08-31 15:40:0468 EXPECT_FALSE(buf.empty());
Karl Wiberg94784372015-04-20 12:03:0769 EXPECT_EQ(0, memcmp(buf.data(), kTestData, 16));
henrike@webrtc.orgf0488722014-05-13 18:00:2670}
71
henrike@webrtc.orgf0488722014-05-13 18:00:2672TEST(BufferTest, TestSetData) {
Karl Wiberg94784372015-04-20 12:03:0773 Buffer buf(kTestData + 4, 7);
74 buf.SetData(kTestData, 9);
75 EXPECT_EQ(buf.size(), 9u);
kwibergc8535972016-06-20 11:47:3976 EXPECT_EQ(buf.capacity(), 7u * 3 / 2);
ossu5955e242016-08-31 15:40:0477 EXPECT_FALSE(buf.empty());
Karl Wiberg94784372015-04-20 12:03:0778 EXPECT_EQ(0, memcmp(buf.data(), kTestData, 9));
kwibergd3134032016-09-05 14:46:2079 Buffer buf2;
80 buf2.SetData(buf);
81 EXPECT_EQ(buf.size(), 9u);
82 EXPECT_EQ(buf.capacity(), 7u * 3 / 2);
83 EXPECT_EQ(0, memcmp(buf.data(), kTestData, 9));
henrike@webrtc.orgf0488722014-05-13 18:00:2684}
85
86TEST(BufferTest, TestAppendData) {
Karl Wiberg94784372015-04-20 12:03:0787 Buffer buf(kTestData + 4, 3);
88 buf.AppendData(kTestData + 10, 2);
89 const int8_t exp[] = {0x4, 0x5, 0x6, 0xa, 0xb};
90 EXPECT_EQ(buf, Buffer(exp));
kwibergd3134032016-09-05 14:46:2091 Buffer buf2;
92 buf2.AppendData(buf);
93 buf2.AppendData(rtc::ArrayView<uint8_t>(buf));
94 const int8_t exp2[] = {0x4, 0x5, 0x6, 0xa, 0xb, 0x4, 0x5, 0x6, 0xa, 0xb};
95 EXPECT_EQ(buf2, Buffer(exp2));
96}
97
98TEST(BufferTest, TestSetAndAppendWithUnknownArg) {
99 struct TestDataContainer {
100 size_t size() const { return 3; }
101 const uint8_t* data() const { return kTestData; }
102 };
103 Buffer buf;
104 buf.SetData(TestDataContainer());
105 EXPECT_EQ(3u, buf.size());
106 EXPECT_EQ(Buffer(kTestData, 3), buf);
107 buf.AppendData(TestDataContainer());
108 EXPECT_EQ(6u, buf.size());
109 EXPECT_EQ(0, memcmp(buf.data(), kTestData, 3));
110 EXPECT_EQ(0, memcmp(buf.data() + 3, kTestData, 3));
henrike@webrtc.orgf0488722014-05-13 18:00:26111}
112
kwiberg@webrtc.orgeebcab52015-03-24 09:19:06113TEST(BufferTest, TestSetSizeSmaller) {
henrike@webrtc.orgf0488722014-05-13 18:00:26114 Buffer buf;
Karl Wiberg94784372015-04-20 12:03:07115 buf.SetData(kTestData, 15);
116 buf.SetSize(10);
117 EXPECT_EQ(buf.size(), 10u);
118 EXPECT_EQ(buf.capacity(), 15u); // Hasn't shrunk.
ossu5955e242016-08-31 15:40:04119 EXPECT_FALSE(buf.empty());
Karl Wiberg94784372015-04-20 12:03:07120 EXPECT_EQ(buf, Buffer(kTestData, 10));
henrike@webrtc.orgf0488722014-05-13 18:00:26121}
122
kwiberg@webrtc.orgeebcab52015-03-24 09:19:06123TEST(BufferTest, TestSetSizeLarger) {
henrike@webrtc.orgf0488722014-05-13 18:00:26124 Buffer buf;
Karl Wiberg94784372015-04-20 12:03:07125 buf.SetData(kTestData, 15);
126 EXPECT_EQ(buf.size(), 15u);
127 EXPECT_EQ(buf.capacity(), 15u);
ossu5955e242016-08-31 15:40:04128 EXPECT_FALSE(buf.empty());
Karl Wiberg94784372015-04-20 12:03:07129 buf.SetSize(20);
130 EXPECT_EQ(buf.size(), 20u);
kwibergc8535972016-06-20 11:47:39131 EXPECT_EQ(buf.capacity(), 15u * 3 / 2); // Has grown.
ossu5955e242016-08-31 15:40:04132 EXPECT_FALSE(buf.empty());
Karl Wiberg94784372015-04-20 12:03:07133 EXPECT_EQ(0, memcmp(buf.data(), kTestData, 15));
henrike@webrtc.orgf0488722014-05-13 18:00:26134}
135
Karl Wiberg94784372015-04-20 12:03:07136TEST(BufferTest, TestEnsureCapacitySmaller) {
137 Buffer buf(kTestData);
138 const char* data = buf.data<char>();
139 buf.EnsureCapacity(4);
140 EXPECT_EQ(buf.capacity(), 16u); // Hasn't shrunk.
141 EXPECT_EQ(buf.data<char>(), data); // No reallocation.
ossu5955e242016-08-31 15:40:04142 EXPECT_FALSE(buf.empty());
Karl Wiberg94784372015-04-20 12:03:07143 EXPECT_EQ(buf, Buffer(kTestData));
henrike@webrtc.orgf0488722014-05-13 18:00:26144}
145
Karl Wiberg94784372015-04-20 12:03:07146TEST(BufferTest, TestEnsureCapacityLarger) {
147 Buffer buf(kTestData, 5);
148 buf.EnsureCapacity(10);
149 const int8_t* data = buf.data<int8_t>();
150 EXPECT_EQ(buf.capacity(), 10u);
151 buf.AppendData(kTestData + 5, 5);
152 EXPECT_EQ(buf.data<int8_t>(), data); // No reallocation.
ossu5955e242016-08-31 15:40:04153 EXPECT_FALSE(buf.empty());
Karl Wiberg94784372015-04-20 12:03:07154 EXPECT_EQ(buf, Buffer(kTestData, 10));
henrike@webrtc.orgf0488722014-05-13 18:00:26155}
156
Karl Wiberg94784372015-04-20 12:03:07157TEST(BufferTest, TestMoveConstruct) {
158 Buffer buf1(kTestData, 3, 40);
Karl Wibergc56ac1e2015-05-04 12:54:55159 const uint8_t* data = buf1.data();
kwiberg0149e752016-03-11 22:40:52160 Buffer buf2(std::move(buf1));
Karl Wiberg94784372015-04-20 12:03:07161 EXPECT_EQ(buf2.size(), 3u);
162 EXPECT_EQ(buf2.capacity(), 40u);
Karl Wibergc56ac1e2015-05-04 12:54:55163 EXPECT_EQ(buf2.data(), data);
ossu5955e242016-08-31 15:40:04164 EXPECT_FALSE(buf2.empty());
Karl Wiberg94784372015-04-20 12:03:07165 buf1.Clear();
166 EXPECT_EQ(buf1.size(), 0u);
167 EXPECT_EQ(buf1.capacity(), 0u);
168 EXPECT_EQ(buf1.data(), nullptr);
ossu5955e242016-08-31 15:40:04169 EXPECT_TRUE(buf1.empty());
henrike@webrtc.orgf0488722014-05-13 18:00:26170}
171
Karl Wiberg94784372015-04-20 12:03:07172TEST(BufferTest, TestMoveAssign) {
173 Buffer buf1(kTestData, 3, 40);
Karl Wibergc56ac1e2015-05-04 12:54:55174 const uint8_t* data = buf1.data();
Karl Wiberg94784372015-04-20 12:03:07175 Buffer buf2(kTestData);
kwiberg0149e752016-03-11 22:40:52176 buf2 = std::move(buf1);
Karl Wiberg94784372015-04-20 12:03:07177 EXPECT_EQ(buf2.size(), 3u);
178 EXPECT_EQ(buf2.capacity(), 40u);
Karl Wibergc56ac1e2015-05-04 12:54:55179 EXPECT_EQ(buf2.data(), data);
ossu5955e242016-08-31 15:40:04180 EXPECT_FALSE(buf2.empty());
Karl Wiberg94784372015-04-20 12:03:07181 buf1.Clear();
182 EXPECT_EQ(buf1.size(), 0u);
183 EXPECT_EQ(buf1.capacity(), 0u);
184 EXPECT_EQ(buf1.data(), nullptr);
ossu5955e242016-08-31 15:40:04185 EXPECT_TRUE(buf1.empty());
Karl Wiberg94784372015-04-20 12:03:07186}
187
188TEST(BufferTest, TestSwap) {
189 Buffer buf1(kTestData, 3);
190 Buffer buf2(kTestData, 6, 40);
Karl Wibergc56ac1e2015-05-04 12:54:55191 uint8_t* data1 = buf1.data();
192 uint8_t* data2 = buf2.data();
Karl Wiberg94784372015-04-20 12:03:07193 using std::swap;
194 swap(buf1, buf2);
195 EXPECT_EQ(buf1.size(), 6u);
196 EXPECT_EQ(buf1.capacity(), 40u);
Karl Wibergc56ac1e2015-05-04 12:54:55197 EXPECT_EQ(buf1.data(), data2);
ossu5955e242016-08-31 15:40:04198 EXPECT_FALSE(buf1.empty());
Karl Wiberg94784372015-04-20 12:03:07199 EXPECT_EQ(buf2.size(), 3u);
200 EXPECT_EQ(buf2.capacity(), 3u);
Karl Wibergc56ac1e2015-05-04 12:54:55201 EXPECT_EQ(buf2.data(), data1);
ossu5955e242016-08-31 15:40:04202 EXPECT_FALSE(buf2.empty());
henrike@webrtc.orgf0488722014-05-13 18:00:26203}
204
ossu728012e2016-02-19 10:38:32205TEST(BufferTest, TestClear) {
206 Buffer buf;
207 buf.SetData(kTestData, 15);
208 EXPECT_EQ(buf.size(), 15u);
209 EXPECT_EQ(buf.capacity(), 15u);
ossu5955e242016-08-31 15:40:04210 EXPECT_FALSE(buf.empty());
ossu728012e2016-02-19 10:38:32211 const char *data = buf.data<char>();
212 buf.Clear();
213 EXPECT_EQ(buf.size(), 0u);
214 EXPECT_EQ(buf.capacity(), 15u); // Hasn't shrunk.
215 EXPECT_EQ(buf.data<char>(), data); // No reallocation.
ossu5955e242016-08-31 15:40:04216 EXPECT_TRUE(buf.empty());
ossu728012e2016-02-19 10:38:32217}
218
ossub01c7812016-02-24 09:05:56219TEST(BufferTest, TestLambdaSetAppend) {
220 auto setter = [] (rtc::ArrayView<uint8_t> av) {
221 for (int i = 0; i != 15; ++i)
222 av[i] = kTestData[i];
223 return 15;
224 };
225
226 Buffer buf1;
227 buf1.SetData(kTestData, 15);
228 buf1.AppendData(kTestData, 15);
229
230 Buffer buf2;
231 EXPECT_EQ(buf2.SetData(15, setter), 15u);
232 EXPECT_EQ(buf2.AppendData(15, setter), 15u);
233 EXPECT_EQ(buf1, buf2);
234 EXPECT_EQ(buf1.capacity(), buf2.capacity());
ossu5955e242016-08-31 15:40:04235 EXPECT_FALSE(buf1.empty());
236 EXPECT_FALSE(buf2.empty());
ossub01c7812016-02-24 09:05:56237}
238
239TEST(BufferTest, TestLambdaSetAppendSigned) {
240 auto setter = [] (rtc::ArrayView<int8_t> av) {
241 for (int i = 0; i != 15; ++i)
242 av[i] = kTestData[i];
243 return 15;
244 };
245
246 Buffer buf1;
247 buf1.SetData(kTestData, 15);
248 buf1.AppendData(kTestData, 15);
249
250 Buffer buf2;
251 EXPECT_EQ(buf2.SetData<int8_t>(15, setter), 15u);
252 EXPECT_EQ(buf2.AppendData<int8_t>(15, setter), 15u);
253 EXPECT_EQ(buf1, buf2);
254 EXPECT_EQ(buf1.capacity(), buf2.capacity());
ossu5955e242016-08-31 15:40:04255 EXPECT_FALSE(buf1.empty());
256 EXPECT_FALSE(buf2.empty());
ossub01c7812016-02-24 09:05:56257}
258
259TEST(BufferTest, TestLambdaAppendEmpty) {
260 auto setter = [] (rtc::ArrayView<uint8_t> av) {
261 for (int i = 0; i != 15; ++i)
262 av[i] = kTestData[i];
263 return 15;
264 };
265
266 Buffer buf1;
267 buf1.SetData(kTestData, 15);
268
269 Buffer buf2;
270 EXPECT_EQ(buf2.AppendData(15, setter), 15u);
271 EXPECT_EQ(buf1, buf2);
272 EXPECT_EQ(buf1.capacity(), buf2.capacity());
ossu5955e242016-08-31 15:40:04273 EXPECT_FALSE(buf1.empty());
274 EXPECT_FALSE(buf2.empty());
ossub01c7812016-02-24 09:05:56275}
276
277TEST(BufferTest, TestLambdaAppendPartial) {
278 auto setter = [] (rtc::ArrayView<uint8_t> av) {
279 for (int i = 0; i != 7; ++i)
280 av[i] = kTestData[i];
281 return 7;
282 };
283
284 Buffer buf;
285 EXPECT_EQ(buf.AppendData(15, setter), 7u);
286 EXPECT_EQ(buf.size(), 7u); // Size is exactly what we wrote.
287 EXPECT_GE(buf.capacity(), 7u); // Capacity is valid.
288 EXPECT_NE(buf.data<char>(), nullptr); // Data is actually stored.
ossu5955e242016-08-31 15:40:04289 EXPECT_FALSE(buf.empty());
ossub01c7812016-02-24 09:05:56290}
291
292TEST(BufferTest, TestMutableLambdaSetAppend) {
293 uint8_t magic_number = 17;
294 auto setter = [magic_number] (rtc::ArrayView<uint8_t> av) mutable {
295 for (int i = 0; i != 15; ++i) {
296 av[i] = magic_number;
297 ++magic_number;
298 }
299 return 15;
300 };
301
302 EXPECT_EQ(magic_number, 17);
303
304 Buffer buf;
305 EXPECT_EQ(buf.SetData(15, setter), 15u);
306 EXPECT_EQ(buf.AppendData(15, setter), 15u);
307 EXPECT_EQ(buf.size(), 30u); // Size is exactly what we wrote.
308 EXPECT_GE(buf.capacity(), 30u); // Capacity is valid.
309 EXPECT_NE(buf.data<char>(), nullptr); // Data is actually stored.
ossu5955e242016-08-31 15:40:04310 EXPECT_FALSE(buf.empty());
ossub01c7812016-02-24 09:05:56311
312 for (uint8_t i = 0; i != buf.size(); ++i) {
313 EXPECT_EQ(buf.data()[i], magic_number + i);
314 }
315}
316
ossub9338ac2016-02-29 17:36:37317TEST(BufferTest, TestBracketRead) {
318 Buffer buf(kTestData, 7);
319 EXPECT_EQ(buf.size(), 7u);
320 EXPECT_EQ(buf.capacity(), 7u);
321 EXPECT_NE(buf.data(), nullptr);
ossu5955e242016-08-31 15:40:04322 EXPECT_FALSE(buf.empty());
ossub9338ac2016-02-29 17:36:37323
324 for (size_t i = 0; i != 7u; ++i) {
325 EXPECT_EQ(buf[i], kTestData[i]);
326 }
327}
328
329TEST(BufferTest, TestBracketReadConst) {
330 Buffer buf(kTestData, 7);
331 EXPECT_EQ(buf.size(), 7u);
332 EXPECT_EQ(buf.capacity(), 7u);
333 EXPECT_NE(buf.data(), nullptr);
ossu5955e242016-08-31 15:40:04334 EXPECT_FALSE(buf.empty());
ossub9338ac2016-02-29 17:36:37335
336 const Buffer& cbuf = buf;
337
338 for (size_t i = 0; i != 7u; ++i) {
339 EXPECT_EQ(cbuf[i], kTestData[i]);
340 }
341}
342
343TEST(BufferTest, TestBracketWrite) {
344 Buffer buf(7);
345 EXPECT_EQ(buf.size(), 7u);
346 EXPECT_EQ(buf.capacity(), 7u);
347 EXPECT_NE(buf.data(), nullptr);
ossu5955e242016-08-31 15:40:04348 EXPECT_FALSE(buf.empty());
ossub9338ac2016-02-29 17:36:37349
350 for (size_t i = 0; i != 7u; ++i) {
351 buf[i] = kTestData[i];
352 }
353
354 for (size_t i = 0; i != 7u; ++i) {
355 EXPECT_EQ(buf[i], kTestData[i]);
356 }
357}
358
kwiberg1ba21eb2017-04-05 14:38:06359TEST(BufferTest, TestBeginEnd) {
360 const Buffer cbuf(kTestData);
361 Buffer buf(kTestData);
Steve Anton9de3aac2017-10-24 17:08:26362 auto* b1 = cbuf.begin();
kwiberg1ba21eb2017-04-05 14:38:06363 for (auto& x : buf) {
364 EXPECT_EQ(*b1, x);
365 ++b1;
366 ++x;
367 }
368 EXPECT_EQ(cbuf.end(), b1);
Steve Anton9de3aac2017-10-24 17:08:26369 auto* b2 = buf.begin();
kwiberg1ba21eb2017-04-05 14:38:06370 for (auto& y : cbuf) {
371 EXPECT_EQ(*b2, y + 1);
372 ++b2;
373 }
374 EXPECT_EQ(buf.end(), b2);
375}
376
kwiberga4ac4782016-04-29 15:00:22377TEST(BufferTest, TestInt16) {
378 static constexpr int16_t test_data[] = {14, 15, 16, 17, 18};
379 BufferT<int16_t> buf(test_data);
380 EXPECT_EQ(buf.size(), 5u);
381 EXPECT_EQ(buf.capacity(), 5u);
382 EXPECT_NE(buf.data(), nullptr);
ossu5955e242016-08-31 15:40:04383 EXPECT_FALSE(buf.empty());
kwiberga4ac4782016-04-29 15:00:22384 for (size_t i = 0; i != buf.size(); ++i) {
385 EXPECT_EQ(test_data[i], buf[i]);
386 }
387 BufferT<int16_t> buf2(test_data);
388 EXPECT_EQ(buf, buf2);
389 buf2[0] = 9;
390 EXPECT_NE(buf, buf2);
391}
392
393TEST(BufferTest, TestFloat) {
394 static constexpr float test_data[] = {14, 15, 16, 17, 18};
395 BufferT<float> buf;
396 EXPECT_EQ(buf.size(), 0u);
397 EXPECT_EQ(buf.capacity(), 0u);
398 EXPECT_EQ(buf.data(), nullptr);
ossu5955e242016-08-31 15:40:04399 EXPECT_TRUE(buf.empty());
kwiberga4ac4782016-04-29 15:00:22400 buf.SetData(test_data);
401 EXPECT_EQ(buf.size(), 5u);
402 EXPECT_EQ(buf.capacity(), 5u);
403 EXPECT_NE(buf.data(), nullptr);
ossu5955e242016-08-31 15:40:04404 EXPECT_FALSE(buf.empty());
kwiberga4ac4782016-04-29 15:00:22405 float* p1 = buf.data();
406 while (buf.data() == p1) {
407 buf.AppendData(test_data);
408 }
409 EXPECT_EQ(buf.size(), buf.capacity());
410 EXPECT_GT(buf.size(), 5u);
411 EXPECT_EQ(buf.size() % 5, 0u);
412 EXPECT_NE(buf.data(), nullptr);
413 for (size_t i = 0; i != buf.size(); ++i) {
414 EXPECT_EQ(test_data[i % 5], buf[i]);
415 }
416}
417
418TEST(BufferTest, TestStruct) {
419 struct BloodStone {
420 bool blood;
421 const char* stone;
422 };
423 BufferT<BloodStone> buf(4);
424 EXPECT_EQ(buf.size(), 4u);
425 EXPECT_EQ(buf.capacity(), 4u);
426 EXPECT_NE(buf.data(), nullptr);
ossu5955e242016-08-31 15:40:04427 EXPECT_FALSE(buf.empty());
kwiberga4ac4782016-04-29 15:00:22428 BufferT<BloodStone*> buf2(4);
429 for (size_t i = 0; i < buf2.size(); ++i) {
430 buf2[i] = &buf[i];
431 }
432 static const char kObsidian[] = "obsidian";
433 buf2[2]->stone = kObsidian;
434 EXPECT_EQ(kObsidian, buf[2].stone);
435}
436
henrike@webrtc.orgf0488722014-05-13 18:00:26437} // namespace rtc