OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2016 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/copyonwritebuffer.h" | |
12 #include "webrtc/base/gunit.h" | |
13 | |
14 namespace rtc { | |
15 | |
16 namespace { | |
17 | |
18 // clang-format off | |
19 const uint8_t kTestData[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, | |
20 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}; | |
21 // clang-format on | |
22 | |
23 } // namespace | |
24 | |
25 void EnsureBuffersShareData(const CopyOnWriteBuffer& buf1, | |
26 const CopyOnWriteBuffer& buf2) { | |
27 // Data is shared between buffers. | |
28 EXPECT_EQ(buf1.size(), buf2.size()); | |
29 EXPECT_EQ(buf1.capacity(), buf2.capacity()); | |
30 const uint8_t* data1 = buf1.data(); | |
31 const uint8_t* data2 = buf2.data(); | |
32 EXPECT_EQ(data1, data2); | |
33 EXPECT_EQ(buf1, buf2); | |
34 } | |
35 | |
36 void EnsureBuffersDontShareData(const CopyOnWriteBuffer& buf1, | |
37 const CopyOnWriteBuffer& buf2) { | |
38 // Data is not shared between buffers. | |
39 const uint8_t* data1 = buf1.cdata(); | |
40 const uint8_t* data2 = buf2.cdata(); | |
41 EXPECT_NE(data1, data2); | |
42 } | |
43 | |
44 TEST(CopyOnWriteBufferTest, TestCreateEmptyData) { | |
45 CopyOnWriteBuffer buf(static_cast<const uint8_t*>(nullptr), 0); | |
46 EXPECT_EQ(buf.size(), 0u); | |
47 EXPECT_EQ(buf.capacity(), 0u); | |
48 EXPECT_EQ(buf.data(), nullptr); | |
49 } | |
50 | |
51 TEST(CopyOnWriteBufferTest, TestMoveConstruct) { | |
52 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
53 size_t buf1_size = buf1.size(); | |
54 size_t buf1_capacity = buf1.capacity(); | |
55 const uint8_t* buf1_data = buf1.cdata(); | |
56 | |
57 CopyOnWriteBuffer buf2(std::move(buf1)); | |
58 EXPECT_EQ(buf1.size(), 0u); | |
59 EXPECT_EQ(buf1.capacity(), 0u); | |
60 EXPECT_EQ(buf1.data(), nullptr); | |
61 EXPECT_EQ(buf2.size(), buf1_size); | |
62 EXPECT_EQ(buf2.capacity(), buf1_capacity); | |
63 EXPECT_EQ(buf2.data(), buf1_data); | |
64 } | |
65 | |
66 TEST(CopyOnWriteBufferTest, TestMoveAssign) { | |
67 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
68 size_t buf1_size = buf1.size(); | |
69 size_t buf1_capacity = buf1.capacity(); | |
70 const uint8_t* buf1_data = buf1.cdata(); | |
71 | |
72 CopyOnWriteBuffer buf2; | |
73 buf2 = std::move(buf1); | |
74 EXPECT_EQ(buf1.size(), 0u); | |
75 EXPECT_EQ(buf1.capacity(), 0u); | |
76 EXPECT_EQ(buf1.data(), nullptr); | |
77 EXPECT_EQ(buf2.size(), buf1_size); | |
78 EXPECT_EQ(buf2.capacity(), buf1_capacity); | |
79 EXPECT_EQ(buf2.data(), buf1_data); | |
80 } | |
81 | |
82 TEST(CopyOnWriteBufferTest, TestSwap) { | |
83 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
84 size_t buf1_size = buf1.size(); | |
85 size_t buf1_capacity = buf1.capacity(); | |
86 const uint8_t* buf1_data = buf1.cdata(); | |
87 | |
88 CopyOnWriteBuffer buf2(kTestData, 6, 20); | |
89 size_t buf2_size = buf2.size(); | |
90 size_t buf2_capacity = buf2.capacity(); | |
91 const uint8_t* buf2_data = buf2.cdata(); | |
92 | |
93 std::swap(buf1, buf2); | |
94 EXPECT_EQ(buf1.size(), buf2_size); | |
95 EXPECT_EQ(buf1.capacity(), buf2_capacity); | |
96 EXPECT_EQ(buf1.data(), buf2_data); | |
97 EXPECT_EQ(buf2.size(), buf1_size); | |
98 EXPECT_EQ(buf2.capacity(), buf1_capacity); | |
99 EXPECT_EQ(buf2.data(), buf1_data); | |
100 } | |
101 | |
102 TEST(CopyOnWriteBufferTest, TestAppendData) { | |
103 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
104 CopyOnWriteBuffer buf2(buf1); | |
105 | |
106 EnsureBuffersShareData(buf1, buf2); | |
107 | |
108 // AppendData copies the underlying buffer. | |
109 buf2.AppendData("foo"); | |
110 EXPECT_EQ(buf2.size(), buf1.size() + 4); // "foo" + trailing 0x00 | |
111 EXPECT_EQ(buf2.capacity(), buf1.capacity()); | |
112 EXPECT_NE(buf2.data(), buf1.data()); | |
113 | |
114 EXPECT_EQ(buf1, CopyOnWriteBuffer(kTestData, 3)); | |
115 const int8_t exp[] = {0x0, 0x1, 0x2, 'f', 'o', 'o', 0x0}; | |
116 EXPECT_EQ(buf2, CopyOnWriteBuffer(exp)); | |
117 } | |
118 | |
119 TEST(CopyOnWriteBufferTest, SetEmptyData) { | |
120 CopyOnWriteBuffer buf(10); | |
121 | |
122 buf.SetData<uint8_t>(nullptr, 0); | |
123 | |
124 EXPECT_EQ(0u, buf.size()); | |
125 } | |
126 | |
127 TEST(CopyOnWriteBufferTest, SetDataNoMoreThanCapacityDoesntCauseReallocation) { | |
128 CopyOnWriteBuffer buf1(3, 10); | |
129 const uint8_t* const original_allocation = buf1.cdata(); | |
130 | |
131 buf1.SetData(kTestData, 10); | |
132 | |
133 EXPECT_EQ(original_allocation, buf1.cdata()); | |
134 EXPECT_EQ(buf1, CopyOnWriteBuffer(kTestData, 10)); | |
135 } | |
136 | |
137 TEST(CopyOnWriteBufferTest, SetDataMakeReferenceCopy) { | |
138 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
139 CopyOnWriteBuffer buf2; | |
140 | |
141 buf2.SetData(buf1); | |
142 | |
143 EnsureBuffersShareData(buf1, buf2); | |
144 } | |
145 | |
146 TEST(CopyOnWriteBufferTest, SetDataOnSharedKeepsOriginal) { | |
147 const uint8_t data[] = "foo"; | |
148 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
149 const uint8_t* const original_allocation = buf1.cdata(); | |
150 CopyOnWriteBuffer buf2(buf1); | |
151 | |
152 buf2.SetData(data); | |
153 | |
154 EnsureBuffersDontShareData(buf1, buf2); | |
155 EXPECT_EQ(original_allocation, buf1.cdata()); | |
156 EXPECT_EQ(buf1, CopyOnWriteBuffer(kTestData, 3)); | |
157 EXPECT_EQ(buf2, CopyOnWriteBuffer(data)); | |
158 } | |
159 | |
160 TEST(CopyOnWriteBufferTest, SetDataOnSharedKeepsCapacity) { | |
161 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
162 CopyOnWriteBuffer buf2(buf1); | |
163 EnsureBuffersShareData(buf1, buf2); | |
164 | |
165 buf2.SetData(kTestData, 2); | |
166 | |
167 EnsureBuffersDontShareData(buf1, buf2); | |
168 EXPECT_EQ(2u, buf2.size()); | |
169 EXPECT_EQ(10u, buf2.capacity()); | |
170 } | |
171 | |
172 TEST(CopyOnWriteBufferTest, TestEnsureCapacity) { | |
173 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
174 CopyOnWriteBuffer buf2(buf1); | |
175 | |
176 // Smaller than existing capacity -> no change and still same contents. | |
177 buf2.EnsureCapacity(8); | |
178 EnsureBuffersShareData(buf1, buf2); | |
179 EXPECT_EQ(buf1.size(), 3u); | |
180 EXPECT_EQ(buf1.capacity(), 10u); | |
181 EXPECT_EQ(buf2.size(), 3u); | |
182 EXPECT_EQ(buf2.capacity(), 10u); | |
183 | |
184 // Lager than existing capacity -> data is cloned. | |
185 buf2.EnsureCapacity(16); | |
186 EnsureBuffersDontShareData(buf1, buf2); | |
187 EXPECT_EQ(buf1.size(), 3u); | |
188 EXPECT_EQ(buf1.capacity(), 10u); | |
189 EXPECT_EQ(buf2.size(), 3u); | |
190 EXPECT_EQ(buf2.capacity(), 16u); | |
191 // The size and contents are still the same. | |
192 EXPECT_EQ(buf1, buf2); | |
193 } | |
194 | |
195 TEST(CopyOnWriteBufferTest, SetSizeDoesntChangeOriginal) { | |
196 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
197 const uint8_t* const original_allocation = buf1.cdata(); | |
198 CopyOnWriteBuffer buf2(buf1); | |
199 | |
200 buf2.SetSize(16); | |
201 | |
202 EnsureBuffersDontShareData(buf1, buf2); | |
203 EXPECT_EQ(original_allocation, buf1.cdata()); | |
204 EXPECT_EQ(3u, buf1.size()); | |
205 EXPECT_EQ(10u, buf1.capacity()); | |
206 } | |
207 | |
208 TEST(CopyOnWriteBufferTest, SetSizeCloneContent) { | |
209 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
210 CopyOnWriteBuffer buf2(buf1); | |
211 | |
212 buf2.SetSize(16); | |
213 | |
214 EXPECT_EQ(buf2.size(), 16u); | |
215 EXPECT_EQ(0, memcmp(buf2.data(), kTestData, 3)); | |
216 } | |
217 | |
218 TEST(CopyOnWriteBufferTest, SetSizeMayIncreaseCapacity) { | |
219 CopyOnWriteBuffer buf(kTestData, 3, 10); | |
220 | |
221 buf.SetSize(16); | |
222 | |
223 EXPECT_EQ(16u, buf.size()); | |
224 EXPECT_EQ(16u, buf.capacity()); | |
225 } | |
226 | |
227 TEST(CopyOnWriteBufferTest, SetSizeDoesntDecreaseCapacity) { | |
228 CopyOnWriteBuffer buf1(kTestData, 5, 10); | |
229 CopyOnWriteBuffer buf2(buf1); | |
230 | |
231 buf2.SetSize(2); | |
232 | |
233 EXPECT_EQ(2u, buf2.size()); | |
234 EXPECT_EQ(10u, buf2.capacity()); | |
235 } | |
236 | |
237 TEST(CopyOnWriteBufferTest, ClearDoesntChangeOriginal) { | |
238 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
239 const uint8_t* const original_allocation = buf1.cdata(); | |
240 CopyOnWriteBuffer buf2(buf1); | |
241 | |
242 buf2.Clear(); | |
243 | |
244 EnsureBuffersDontShareData(buf1, buf2); | |
245 EXPECT_EQ(3u, buf1.size()); | |
246 EXPECT_EQ(10u, buf1.capacity()); | |
247 EXPECT_EQ(original_allocation, buf1.cdata()); | |
248 EXPECT_EQ(0u, buf2.size()); | |
249 } | |
250 | |
251 TEST(CopyOnWriteBufferTest, ClearDoesntChangeCapacity) { | |
252 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
253 CopyOnWriteBuffer buf2(buf1); | |
254 | |
255 buf2.Clear(); | |
256 | |
257 EXPECT_EQ(0u, buf2.size()); | |
258 EXPECT_EQ(10u, buf2.capacity()); | |
259 } | |
260 | |
261 TEST(CopyOnWriteBufferTest, TestConstDataAccessor) { | |
262 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
263 CopyOnWriteBuffer buf2(buf1); | |
264 | |
265 // .cdata() doesn't clone data. | |
266 const uint8_t* cdata1 = buf1.cdata(); | |
267 const uint8_t* cdata2 = buf2.cdata(); | |
268 EXPECT_EQ(cdata1, cdata2); | |
269 | |
270 // Non-const .data() clones data if shared. | |
271 const uint8_t* data1 = buf1.data(); | |
272 const uint8_t* data2 = buf2.data(); | |
273 EXPECT_NE(data1, data2); | |
274 // buf1 was cloned above. | |
275 EXPECT_NE(data1, cdata1); | |
276 // Therefore buf2 was no longer sharing data and was not cloned. | |
277 EXPECT_EQ(data2, cdata1); | |
278 } | |
279 | |
280 TEST(CopyOnWriteBufferTest, TestBacketRead) { | |
281 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
282 CopyOnWriteBuffer buf2(buf1); | |
283 | |
284 EnsureBuffersShareData(buf1, buf2); | |
285 // Non-const reads clone the data if shared. | |
286 for (size_t i = 0; i != 3u; ++i) { | |
287 EXPECT_EQ(buf1[i], kTestData[i]); | |
288 } | |
289 EnsureBuffersDontShareData(buf1, buf2); | |
290 } | |
291 | |
292 TEST(CopyOnWriteBufferTest, TestBacketReadConst) { | |
293 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
294 CopyOnWriteBuffer buf2(buf1); | |
295 | |
296 EnsureBuffersShareData(buf1, buf2); | |
297 const CopyOnWriteBuffer& cbuf1 = buf1; | |
298 for (size_t i = 0; i != 3u; ++i) { | |
299 EXPECT_EQ(cbuf1[i], kTestData[i]); | |
300 } | |
301 EnsureBuffersShareData(buf1, buf2); | |
302 } | |
303 | |
304 TEST(CopyOnWriteBufferTest, TestBacketWrite) { | |
305 CopyOnWriteBuffer buf1(kTestData, 3, 10); | |
306 CopyOnWriteBuffer buf2(buf1); | |
307 | |
308 EnsureBuffersShareData(buf1, buf2); | |
309 for (size_t i = 0; i != 3u; ++i) { | |
310 buf1[i] = kTestData[i] + 1; | |
311 } | |
312 EXPECT_EQ(buf1.size(), 3u); | |
313 EXPECT_EQ(buf1.capacity(), 10u); | |
314 EXPECT_EQ(buf2.size(), 3u); | |
315 EXPECT_EQ(buf2.capacity(), 10u); | |
316 EXPECT_EQ(0, memcmp(buf2.cdata(), kTestData, 3)); | |
317 } | |
318 | |
319 } // namespace rtc | |
OLD | NEW |