OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Crashpad Authors. All rights reserved. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 | |
15 #include "util/file/string_file_writer.h" | |
16 | |
17 #include <algorithm> | |
18 #include <limits> | |
19 | |
20 #include "gtest/gtest.h" | |
21 | |
22 namespace crashpad { | |
23 namespace test { | |
24 namespace { | |
25 | |
26 TEST(StringFileWriter, EmptyFile) { | |
27 StringFileWriter writer; | |
28 EXPECT_TRUE(writer.string().empty()); | |
29 EXPECT_EQ(0, writer.Seek(0, SEEK_CUR)); | |
30 EXPECT_TRUE(writer.Write("", 0)); | |
31 EXPECT_TRUE(writer.string().empty()); | |
32 EXPECT_EQ(0, writer.Seek(0, SEEK_CUR)); | |
33 } | |
34 | |
35 TEST(StringFileWriter, OneByteFile) { | |
36 StringFileWriter writer; | |
37 | |
38 EXPECT_TRUE(writer.Write("a", 1)); | |
39 EXPECT_EQ(1u, writer.string().size()); | |
40 EXPECT_EQ("a", writer.string()); | |
41 EXPECT_EQ(1, writer.Seek(0, SEEK_CUR)); | |
42 | |
43 EXPECT_EQ(0, writer.Seek(0, SEEK_SET)); | |
44 EXPECT_TRUE(writer.Write("b", 1)); | |
45 EXPECT_EQ(1u, writer.string().size()); | |
46 EXPECT_EQ("b", writer.string()); | |
47 EXPECT_EQ(1, writer.Seek(0, SEEK_CUR)); | |
48 | |
49 EXPECT_EQ(0, writer.Seek(0, SEEK_SET)); | |
50 EXPECT_TRUE(writer.Write("\0", 1)); | |
51 EXPECT_EQ(1u, writer.string().size()); | |
52 EXPECT_EQ('\0', writer.string()[0]); | |
53 EXPECT_EQ(1, writer.Seek(0, SEEK_CUR)); | |
54 } | |
55 | |
56 TEST(StringFileWriter, Reset) { | |
57 StringFileWriter writer; | |
58 | |
59 EXPECT_TRUE(writer.Write("abc", 3)); | |
60 EXPECT_EQ(3u, writer.string().size()); | |
61 EXPECT_EQ("abc", writer.string()); | |
62 EXPECT_EQ(3, writer.Seek(0, SEEK_CUR)); | |
63 | |
64 writer.Reset(); | |
65 EXPECT_TRUE(writer.string().empty()); | |
66 EXPECT_EQ(0, writer.Seek(0, SEEK_CUR)); | |
67 | |
68 EXPECT_TRUE(writer.Write("de", 2)); | |
69 EXPECT_EQ(2u, writer.string().size()); | |
70 EXPECT_EQ("de", writer.string()); | |
71 EXPECT_EQ(2, writer.Seek(0, SEEK_CUR)); | |
72 | |
73 writer.Reset(); | |
74 EXPECT_TRUE(writer.string().empty()); | |
75 EXPECT_EQ(0, writer.Seek(0, SEEK_CUR)); | |
76 | |
77 EXPECT_TRUE(writer.Write("fghi", 4)); | |
78 EXPECT_EQ(4u, writer.string().size()); | |
79 EXPECT_EQ("fghi", writer.string()); | |
80 EXPECT_EQ(4, writer.Seek(0, SEEK_CUR)); | |
81 | |
82 writer.Reset(); | |
83 EXPECT_TRUE(writer.string().empty()); | |
84 EXPECT_EQ(0, writer.Seek(0, SEEK_CUR)); | |
85 | |
86 // Test resetting after a sparse write. | |
87 EXPECT_EQ(1, writer.Seek(1, SEEK_SET)); | |
88 EXPECT_TRUE(writer.Write("j", 1)); | |
89 EXPECT_EQ(2u, writer.string().size()); | |
90 EXPECT_EQ(std::string("\0j", 2), writer.string()); | |
91 EXPECT_EQ(2, writer.Seek(0, SEEK_CUR)); | |
92 | |
93 writer.Reset(); | |
94 EXPECT_TRUE(writer.string().empty()); | |
95 EXPECT_EQ(0, writer.Seek(0, SEEK_CUR)); | |
96 } | |
97 | |
98 TEST(StringFileWriter, WriteInvalid) { | |
99 StringFileWriter writer; | |
100 | |
101 EXPECT_EQ(0, writer.Seek(0, SEEK_CUR)); | |
102 | |
103 EXPECT_FALSE(writer.Write( | |
104 "", implicit_cast<size_t>(std::numeric_limits<ssize_t>::max()) + 1)); | |
105 EXPECT_TRUE(writer.string().empty()); | |
106 EXPECT_EQ(0, writer.Seek(0, SEEK_CUR)); | |
107 | |
108 EXPECT_TRUE(writer.Write("a", 1)); | |
109 EXPECT_FALSE(writer.Write( | |
110 "", implicit_cast<size_t>(std::numeric_limits<ssize_t>::max()))); | |
111 EXPECT_EQ(1u, writer.string().size()); | |
112 EXPECT_EQ("a", writer.string()); | |
113 EXPECT_EQ(1, writer.Seek(0, SEEK_CUR)); | |
114 } | |
115 | |
116 TEST(StringFileWriter, WriteIoVec) { | |
117 StringFileWriter writer; | |
118 | |
119 std::vector<WritableIoVec> iovecs; | |
120 WritableIoVec iov; | |
121 iov.iov_base = ""; | |
122 iov.iov_len = 0; | |
123 iovecs.push_back(iov); | |
124 EXPECT_TRUE(writer.WriteIoVec(&iovecs)); | |
125 EXPECT_TRUE(writer.string().empty()); | |
126 EXPECT_EQ(0, writer.Seek(0, SEEK_CUR)); | |
127 | |
128 iovecs.clear(); | |
129 iov.iov_base = "a"; | |
130 iov.iov_len = 1; | |
131 iovecs.push_back(iov); | |
132 EXPECT_TRUE(writer.WriteIoVec(&iovecs)); | |
133 EXPECT_EQ(1u, writer.string().size()); | |
134 EXPECT_EQ("a", writer.string()); | |
135 EXPECT_EQ(1, writer.Seek(0, SEEK_CUR)); | |
136 | |
137 iovecs.clear(); | |
138 iovecs.push_back(iov); | |
139 EXPECT_TRUE(writer.WriteIoVec(&iovecs)); | |
140 EXPECT_EQ(2u, writer.string().size()); | |
141 EXPECT_EQ("aa", writer.string()); | |
142 EXPECT_EQ(2, writer.Seek(0, SEEK_CUR)); | |
143 | |
144 iovecs.clear(); | |
145 iovecs.push_back(iov); | |
146 iov.iov_base = "bc"; | |
147 iov.iov_len = 2; | |
148 iovecs.push_back(iov); | |
149 EXPECT_TRUE(writer.WriteIoVec(&iovecs)); | |
150 EXPECT_EQ(5u, writer.string().size()); | |
151 EXPECT_EQ("aaabc", writer.string()); | |
152 EXPECT_EQ(5, writer.Seek(0, SEEK_CUR)); | |
153 | |
154 EXPECT_TRUE(writer.Write("def", 3)); | |
155 EXPECT_EQ(8u, writer.string().size()); | |
156 EXPECT_EQ("aaabcdef", writer.string()); | |
157 EXPECT_EQ(8, writer.Seek(0, SEEK_CUR)); | |
158 | |
159 iovecs.clear(); | |
160 iov.iov_base = "ghij"; | |
161 iov.iov_len = 4; | |
162 iovecs.push_back(iov); | |
163 iov.iov_base = "klmno"; | |
164 iov.iov_len = 5; | |
165 iovecs.push_back(iov); | |
166 EXPECT_TRUE(writer.WriteIoVec(&iovecs)); | |
167 EXPECT_EQ(17u, writer.string().size()); | |
168 EXPECT_EQ("aaabcdefghijklmno", writer.string()); | |
169 EXPECT_EQ(17, writer.Seek(0, SEEK_CUR)); | |
170 | |
171 writer.Reset(); | |
172 EXPECT_TRUE(writer.string().empty()); | |
173 EXPECT_EQ(0, writer.Seek(0, SEEK_CUR)); | |
174 | |
175 iovecs.clear(); | |
176 iov.iov_base = "abcd"; | |
177 iov.iov_len = 4; | |
178 iovecs.resize(16, iov); | |
179 EXPECT_TRUE(writer.WriteIoVec(&iovecs)); | |
180 EXPECT_EQ(64u, writer.string().size()); | |
181 EXPECT_EQ("abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", | |
182 writer.string()); | |
183 EXPECT_EQ(64, writer.Seek(0, SEEK_CUR)); | |
184 } | |
185 | |
186 TEST(StringFileWriter, WriteIoVecInvalid) { | |
187 StringFileWriter writer; | |
188 | |
189 std::vector<WritableIoVec> iovecs; | |
190 EXPECT_FALSE(writer.WriteIoVec(&iovecs)); | |
191 EXPECT_TRUE(writer.string().empty()); | |
192 EXPECT_EQ(0, writer.Seek(0, SEEK_CUR)); | |
193 | |
194 WritableIoVec iov; | |
195 EXPECT_EQ(1, writer.Seek(1, SEEK_CUR)); | |
196 iov.iov_base = "a"; | |
197 iov.iov_len = std::numeric_limits<ssize_t>::max(); | |
198 iovecs.push_back(iov); | |
199 EXPECT_FALSE(writer.WriteIoVec(&iovecs)); | |
200 EXPECT_TRUE(writer.string().empty()); | |
201 EXPECT_EQ(1, writer.Seek(0, SEEK_CUR)); | |
202 | |
203 iovecs.clear(); | |
204 iov.iov_base = "a"; | |
205 iov.iov_len = 1; | |
206 iovecs.push_back(iov); | |
207 iov.iov_len = std::numeric_limits<ssize_t>::max() - 1; | |
208 iovecs.push_back(iov); | |
209 EXPECT_FALSE(writer.WriteIoVec(&iovecs)); | |
210 EXPECT_TRUE(writer.string().empty()); | |
211 EXPECT_EQ(1, writer.Seek(0, SEEK_CUR)); | |
212 } | |
213 | |
214 TEST(StringFileWriter, Seek) { | |
215 StringFileWriter writer; | |
216 | |
217 EXPECT_TRUE(writer.Write("abcd", 4)); | |
218 EXPECT_EQ(4u, writer.string().size()); | |
219 EXPECT_EQ("abcd", writer.string()); | |
220 EXPECT_EQ(4, writer.Seek(0, SEEK_CUR)); | |
221 | |
222 EXPECT_EQ(0, writer.Seek(0, SEEK_SET)); | |
223 EXPECT_TRUE(writer.Write("efgh", 4)); | |
224 EXPECT_EQ(4u, writer.string().size()); | |
225 EXPECT_EQ("efgh", writer.string()); | |
226 EXPECT_EQ(4, writer.Seek(0, SEEK_CUR)); | |
227 | |
228 EXPECT_EQ(0, writer.Seek(0, SEEK_SET)); | |
229 EXPECT_TRUE(writer.Write("ijk", 3)); | |
230 EXPECT_EQ(4u, writer.string().size()); | |
231 EXPECT_EQ("ijkh", writer.string()); | |
232 EXPECT_EQ(3, writer.Seek(0, SEEK_CUR)); | |
233 | |
234 EXPECT_EQ(0, writer.Seek(0, SEEK_SET)); | |
235 EXPECT_TRUE(writer.Write("lmnop", 5)); | |
236 EXPECT_EQ(5u, writer.string().size()); | |
237 EXPECT_EQ("lmnop", writer.string()); | |
238 EXPECT_EQ(5, writer.Seek(0, SEEK_CUR)); | |
239 | |
240 EXPECT_EQ(1, writer.Seek(1, SEEK_SET)); | |
241 EXPECT_TRUE(writer.Write("q", 1)); | |
242 EXPECT_EQ(5u, writer.string().size()); | |
243 EXPECT_EQ("lqnop", writer.string()); | |
244 EXPECT_EQ(2, writer.Seek(0, SEEK_CUR)); | |
245 | |
246 EXPECT_EQ(1, writer.Seek(-1, SEEK_CUR)); | |
247 EXPECT_TRUE(writer.Write("r", 1)); | |
248 EXPECT_EQ(5u, writer.string().size()); | |
249 EXPECT_EQ("lrnop", writer.string()); | |
250 EXPECT_EQ(2, writer.Seek(0, SEEK_CUR)); | |
251 | |
252 EXPECT_TRUE(writer.Write("s", 1)); | |
253 EXPECT_EQ(5u, writer.string().size()); | |
254 EXPECT_EQ("lrsop", writer.string()); | |
255 EXPECT_EQ(3, writer.Seek(0, SEEK_CUR)); | |
256 | |
257 EXPECT_EQ(2, writer.Seek(-1, SEEK_CUR)); | |
258 EXPECT_TRUE(writer.Write("t", 1)); | |
259 EXPECT_EQ(5u, writer.string().size()); | |
260 EXPECT_EQ("lrtop", writer.string()); | |
261 EXPECT_EQ(3, writer.Seek(0, SEEK_CUR)); | |
262 | |
263 EXPECT_EQ(4, writer.Seek(-1, SEEK_END)); | |
264 EXPECT_TRUE(writer.Write("u", 1)); | |
265 EXPECT_EQ(5u, writer.string().size()); | |
266 EXPECT_EQ("lrtou", writer.string()); | |
267 EXPECT_EQ(5, writer.Seek(0, SEEK_CUR)); | |
268 | |
269 EXPECT_EQ(0, writer.Seek(-5, SEEK_END)); | |
270 EXPECT_TRUE(writer.Write("v", 1)); | |
271 EXPECT_EQ(5u, writer.string().size()); | |
272 EXPECT_EQ("vrtou", writer.string()); | |
273 EXPECT_EQ(1, writer.Seek(0, SEEK_CUR)); | |
274 | |
275 EXPECT_EQ(5, writer.Seek(0, SEEK_END)); | |
276 EXPECT_TRUE(writer.Write("w", 1)); | |
277 EXPECT_EQ(6u, writer.string().size()); | |
278 EXPECT_EQ("vrtouw", writer.string()); | |
279 EXPECT_EQ(6, writer.Seek(0, SEEK_CUR)); | |
280 | |
281 EXPECT_EQ(8, writer.Seek(2, SEEK_END)); | |
282 EXPECT_EQ(6u, writer.string().size()); | |
283 EXPECT_EQ("vrtouw", writer.string()); | |
284 | |
285 EXPECT_EQ(6, writer.Seek(0, SEEK_END)); | |
286 EXPECT_TRUE(writer.Write("x", 1)); | |
287 EXPECT_EQ(7u, writer.string().size()); | |
288 EXPECT_EQ("vrtouwx", writer.string()); | |
289 EXPECT_EQ(7, writer.Seek(0, SEEK_CUR)); | |
290 } | |
291 | |
292 TEST(StringFileWriter, SeekSparse) { | |
293 StringFileWriter writer; | |
294 | |
295 EXPECT_EQ(3, writer.Seek(3, SEEK_SET)); | |
296 EXPECT_TRUE(writer.string().empty()); | |
297 EXPECT_EQ(3, writer.Seek(0, SEEK_CUR)); | |
298 | |
299 EXPECT_TRUE(writer.Write("abc", 3)); | |
300 EXPECT_EQ(6u, writer.string().size()); | |
301 EXPECT_EQ(std::string("\0\0\0abc", 6), writer.string()); | |
302 EXPECT_EQ(6, writer.Seek(0, SEEK_CUR)); | |
303 | |
304 EXPECT_EQ(9, writer.Seek(3, SEEK_END)); | |
305 EXPECT_EQ(6u, writer.string().size()); | |
306 EXPECT_EQ(9, writer.Seek(0, SEEK_CUR)); | |
307 EXPECT_TRUE(writer.Write("def", 3)); | |
308 EXPECT_EQ(12u, writer.string().size()); | |
309 EXPECT_EQ(std::string("\0\0\0abc\0\0\0def", 12), writer.string()); | |
310 EXPECT_EQ(12, writer.Seek(0, SEEK_CUR)); | |
311 | |
312 EXPECT_EQ(7, writer.Seek(-5, SEEK_END)); | |
313 EXPECT_EQ(12u, writer.string().size()); | |
314 EXPECT_EQ(7, writer.Seek(0, SEEK_CUR)); | |
315 EXPECT_TRUE(writer.Write("g", 1)); | |
316 EXPECT_EQ(12u, writer.string().size()); | |
317 EXPECT_EQ(std::string("\0\0\0abc\0g\0def", 12), writer.string()); | |
318 EXPECT_EQ(8, writer.Seek(0, SEEK_CUR)); | |
319 | |
320 EXPECT_EQ(15, writer.Seek(7, SEEK_CUR)); | |
321 EXPECT_EQ(12u, writer.string().size()); | |
322 EXPECT_EQ(15, writer.Seek(0, SEEK_CUR)); | |
323 EXPECT_TRUE(writer.Write("hij", 3)); | |
324 EXPECT_EQ(18u, writer.string().size()); | |
325 EXPECT_EQ(std::string("\0\0\0abc\0g\0def\0\0\0hij", 18), writer.string()); | |
326 EXPECT_EQ(18, writer.Seek(0, SEEK_CUR)); | |
327 | |
328 EXPECT_EQ(1, writer.Seek(-17, SEEK_CUR)); | |
329 EXPECT_EQ(18u, writer.string().size()); | |
330 EXPECT_EQ(1, writer.Seek(0, SEEK_CUR)); | |
331 EXPECT_TRUE(writer.Write("k", 1)); | |
332 EXPECT_EQ(18u, writer.string().size()); | |
333 EXPECT_EQ(std::string("\0k\0abc\0g\0def\0\0\0hij", 18), writer.string()); | |
334 EXPECT_EQ(2, writer.Seek(0, SEEK_CUR)); | |
335 | |
336 EXPECT_TRUE(writer.Write("l", 1)); | |
337 EXPECT_TRUE(writer.Write("mnop", 4)); | |
338 EXPECT_EQ(18u, writer.string().size()); | |
339 EXPECT_EQ(std::string("\0klmnopg\0def\0\0\0hij", 18), writer.string()); | |
340 EXPECT_EQ(7, writer.Seek(0, SEEK_CUR)); | |
341 } | |
342 | |
343 TEST(StringFileWriter, SeekInvalid) { | |
344 StringFileWriter writer; | |
345 | |
346 EXPECT_EQ(0, writer.Seek(0, SEEK_CUR)); | |
347 EXPECT_EQ(1, writer.Seek(1, SEEK_SET)); | |
348 EXPECT_EQ(1, writer.Seek(0, SEEK_CUR)); | |
349 EXPECT_LT(writer.Seek(-1, SEEK_SET), 0); | |
350 EXPECT_EQ(1, writer.Seek(0, SEEK_CUR)); | |
351 EXPECT_LT(writer.Seek(std::numeric_limits<ssize_t>::min(), SEEK_SET), 0); | |
352 EXPECT_EQ(1, writer.Seek(0, SEEK_CUR)); | |
353 EXPECT_LT(writer.Seek(std::numeric_limits<FileOffset>::min(), SEEK_SET), 0); | |
354 EXPECT_EQ(1, writer.Seek(0, SEEK_CUR)); | |
355 EXPECT_TRUE(writer.string().empty()); | |
356 | |
357 static_assert(SEEK_SET != 3 && SEEK_CUR != 3 && SEEK_END != 3, | |
358 "3 must be invalid for whence"); | |
359 EXPECT_LT(writer.Seek(0, 3), 0); | |
360 | |
361 writer.Reset(); | |
362 EXPECT_EQ(0, writer.Seek(0, SEEK_CUR)); | |
363 EXPECT_TRUE(writer.string().empty()); | |
364 | |
365 const FileOffset kMaxOffset = static_cast<FileOffset>( | |
366 std::min(implicit_cast<uint64_t>(std::numeric_limits<FileOffset>::max()), | |
367 implicit_cast<uint64_t>(std::numeric_limits<size_t>::max()))); | |
368 | |
369 EXPECT_EQ(kMaxOffset, writer.Seek(kMaxOffset, SEEK_SET)); | |
370 EXPECT_EQ(kMaxOffset, writer.Seek(0, SEEK_CUR)); | |
371 EXPECT_LT(writer.Seek(1, SEEK_CUR), 0); | |
372 | |
373 EXPECT_EQ(1, writer.Seek(1, SEEK_SET)); | |
374 EXPECT_EQ(1, writer.Seek(0, SEEK_CUR)); | |
375 EXPECT_LT(writer.Seek(kMaxOffset, SEEK_CUR), 0); | |
376 } | |
377 | |
378 } // namespace | |
379 } // namespace test | |
380 } // namespace crashpad | |
OLD | NEW |