OLD | NEW |
| (Empty) |
1 /* | |
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 | |
11 #include "webrtc/base/buffer.h" | |
12 | |
13 #include "webrtc/base/array_view.h" | |
14 #include "webrtc/base/gunit.h" | |
15 | |
16 #include <type_traits> | |
17 #include <utility> | |
18 | |
19 namespace rtc { | |
20 | |
21 namespace { | |
22 | |
23 // clang-format off | |
24 const 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 | |
28 void TestBuf(const Buffer& b1, size_t size, size_t capacity) { | |
29 EXPECT_EQ(b1.size(), size); | |
30 EXPECT_EQ(b1.capacity(), capacity); | |
31 } | |
32 | |
33 } // namespace | |
34 | |
35 TEST(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); | |
46 } | |
47 | |
48 TEST(BufferTest, TestConstructData) { | |
49 Buffer buf(kTestData, 7); | |
50 EXPECT_EQ(buf.size(), 7u); | |
51 EXPECT_EQ(buf.capacity(), 7u); | |
52 EXPECT_FALSE(buf.empty()); | |
53 EXPECT_EQ(0, memcmp(buf.data(), kTestData, 7)); | |
54 } | |
55 | |
56 TEST(BufferTest, TestConstructDataWithCapacity) { | |
57 Buffer buf(kTestData, 7, 14); | |
58 EXPECT_EQ(buf.size(), 7u); | |
59 EXPECT_EQ(buf.capacity(), 14u); | |
60 EXPECT_FALSE(buf.empty()); | |
61 EXPECT_EQ(0, memcmp(buf.data(), kTestData, 7)); | |
62 } | |
63 | |
64 TEST(BufferTest, TestConstructArray) { | |
65 Buffer buf(kTestData); | |
66 EXPECT_EQ(buf.size(), 16u); | |
67 EXPECT_EQ(buf.capacity(), 16u); | |
68 EXPECT_FALSE(buf.empty()); | |
69 EXPECT_EQ(0, memcmp(buf.data(), kTestData, 16)); | |
70 } | |
71 | |
72 TEST(BufferTest, TestSetData) { | |
73 Buffer buf(kTestData + 4, 7); | |
74 buf.SetData(kTestData, 9); | |
75 EXPECT_EQ(buf.size(), 9u); | |
76 EXPECT_EQ(buf.capacity(), 7u * 3 / 2); | |
77 EXPECT_FALSE(buf.empty()); | |
78 EXPECT_EQ(0, memcmp(buf.data(), kTestData, 9)); | |
79 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)); | |
84 } | |
85 | |
86 TEST(BufferTest, TestAppendData) { | |
87 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)); | |
91 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 | |
98 TEST(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)); | |
111 } | |
112 | |
113 TEST(BufferTest, TestSetSizeSmaller) { | |
114 Buffer buf; | |
115 buf.SetData(kTestData, 15); | |
116 buf.SetSize(10); | |
117 EXPECT_EQ(buf.size(), 10u); | |
118 EXPECT_EQ(buf.capacity(), 15u); // Hasn't shrunk. | |
119 EXPECT_FALSE(buf.empty()); | |
120 EXPECT_EQ(buf, Buffer(kTestData, 10)); | |
121 } | |
122 | |
123 TEST(BufferTest, TestSetSizeLarger) { | |
124 Buffer buf; | |
125 buf.SetData(kTestData, 15); | |
126 EXPECT_EQ(buf.size(), 15u); | |
127 EXPECT_EQ(buf.capacity(), 15u); | |
128 EXPECT_FALSE(buf.empty()); | |
129 buf.SetSize(20); | |
130 EXPECT_EQ(buf.size(), 20u); | |
131 EXPECT_EQ(buf.capacity(), 15u * 3 / 2); // Has grown. | |
132 EXPECT_FALSE(buf.empty()); | |
133 EXPECT_EQ(0, memcmp(buf.data(), kTestData, 15)); | |
134 } | |
135 | |
136 TEST(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. | |
142 EXPECT_FALSE(buf.empty()); | |
143 EXPECT_EQ(buf, Buffer(kTestData)); | |
144 } | |
145 | |
146 TEST(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. | |
153 EXPECT_FALSE(buf.empty()); | |
154 EXPECT_EQ(buf, Buffer(kTestData, 10)); | |
155 } | |
156 | |
157 TEST(BufferTest, TestMoveConstruct) { | |
158 Buffer buf1(kTestData, 3, 40); | |
159 const uint8_t* data = buf1.data(); | |
160 Buffer buf2(std::move(buf1)); | |
161 EXPECT_EQ(buf2.size(), 3u); | |
162 EXPECT_EQ(buf2.capacity(), 40u); | |
163 EXPECT_EQ(buf2.data(), data); | |
164 EXPECT_FALSE(buf2.empty()); | |
165 buf1.Clear(); | |
166 EXPECT_EQ(buf1.size(), 0u); | |
167 EXPECT_EQ(buf1.capacity(), 0u); | |
168 EXPECT_EQ(buf1.data(), nullptr); | |
169 EXPECT_TRUE(buf1.empty()); | |
170 } | |
171 | |
172 TEST(BufferTest, TestMoveAssign) { | |
173 Buffer buf1(kTestData, 3, 40); | |
174 const uint8_t* data = buf1.data(); | |
175 Buffer buf2(kTestData); | |
176 buf2 = std::move(buf1); | |
177 EXPECT_EQ(buf2.size(), 3u); | |
178 EXPECT_EQ(buf2.capacity(), 40u); | |
179 EXPECT_EQ(buf2.data(), data); | |
180 EXPECT_FALSE(buf2.empty()); | |
181 buf1.Clear(); | |
182 EXPECT_EQ(buf1.size(), 0u); | |
183 EXPECT_EQ(buf1.capacity(), 0u); | |
184 EXPECT_EQ(buf1.data(), nullptr); | |
185 EXPECT_TRUE(buf1.empty()); | |
186 } | |
187 | |
188 TEST(BufferTest, TestSwap) { | |
189 Buffer buf1(kTestData, 3); | |
190 Buffer buf2(kTestData, 6, 40); | |
191 uint8_t* data1 = buf1.data(); | |
192 uint8_t* data2 = buf2.data(); | |
193 using std::swap; | |
194 swap(buf1, buf2); | |
195 EXPECT_EQ(buf1.size(), 6u); | |
196 EXPECT_EQ(buf1.capacity(), 40u); | |
197 EXPECT_EQ(buf1.data(), data2); | |
198 EXPECT_FALSE(buf1.empty()); | |
199 EXPECT_EQ(buf2.size(), 3u); | |
200 EXPECT_EQ(buf2.capacity(), 3u); | |
201 EXPECT_EQ(buf2.data(), data1); | |
202 EXPECT_FALSE(buf2.empty()); | |
203 } | |
204 | |
205 TEST(BufferTest, TestClear) { | |
206 Buffer buf; | |
207 buf.SetData(kTestData, 15); | |
208 EXPECT_EQ(buf.size(), 15u); | |
209 EXPECT_EQ(buf.capacity(), 15u); | |
210 EXPECT_FALSE(buf.empty()); | |
211 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. | |
216 EXPECT_TRUE(buf.empty()); | |
217 } | |
218 | |
219 TEST(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()); | |
235 EXPECT_FALSE(buf1.empty()); | |
236 EXPECT_FALSE(buf2.empty()); | |
237 } | |
238 | |
239 TEST(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()); | |
255 EXPECT_FALSE(buf1.empty()); | |
256 EXPECT_FALSE(buf2.empty()); | |
257 } | |
258 | |
259 TEST(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()); | |
273 EXPECT_FALSE(buf1.empty()); | |
274 EXPECT_FALSE(buf2.empty()); | |
275 } | |
276 | |
277 TEST(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. | |
289 EXPECT_FALSE(buf.empty()); | |
290 } | |
291 | |
292 TEST(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. | |
310 EXPECT_FALSE(buf.empty()); | |
311 | |
312 for (uint8_t i = 0; i != buf.size(); ++i) { | |
313 EXPECT_EQ(buf.data()[i], magic_number + i); | |
314 } | |
315 } | |
316 | |
317 TEST(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); | |
322 EXPECT_FALSE(buf.empty()); | |
323 | |
324 for (size_t i = 0; i != 7u; ++i) { | |
325 EXPECT_EQ(buf[i], kTestData[i]); | |
326 } | |
327 } | |
328 | |
329 TEST(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); | |
334 EXPECT_FALSE(buf.empty()); | |
335 | |
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 | |
343 TEST(BufferTest, TestBracketWrite) { | |
344 Buffer buf(7); | |
345 EXPECT_EQ(buf.size(), 7u); | |
346 EXPECT_EQ(buf.capacity(), 7u); | |
347 EXPECT_NE(buf.data(), nullptr); | |
348 EXPECT_FALSE(buf.empty()); | |
349 | |
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 | |
359 TEST(BufferTest, TestBeginEnd) { | |
360 const Buffer cbuf(kTestData); | |
361 Buffer buf(kTestData); | |
362 auto b1 = cbuf.begin(); | |
363 for (auto& x : buf) { | |
364 EXPECT_EQ(*b1, x); | |
365 ++b1; | |
366 ++x; | |
367 } | |
368 EXPECT_EQ(cbuf.end(), b1); | |
369 auto b2 = buf.begin(); | |
370 for (auto& y : cbuf) { | |
371 EXPECT_EQ(*b2, y + 1); | |
372 ++b2; | |
373 } | |
374 EXPECT_EQ(buf.end(), b2); | |
375 } | |
376 | |
377 TEST(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); | |
383 EXPECT_FALSE(buf.empty()); | |
384 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 | |
393 TEST(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); | |
399 EXPECT_TRUE(buf.empty()); | |
400 buf.SetData(test_data); | |
401 EXPECT_EQ(buf.size(), 5u); | |
402 EXPECT_EQ(buf.capacity(), 5u); | |
403 EXPECT_NE(buf.data(), nullptr); | |
404 EXPECT_FALSE(buf.empty()); | |
405 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 | |
418 TEST(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); | |
427 EXPECT_FALSE(buf.empty()); | |
428 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 | |
437 } // namespace rtc | |
OLD | NEW |