Line data Source code
1 : /*
2 : Zipios -- a small C++ library that provides easy access to .zip files.
3 :
4 : Copyright (C) 2000-2007 Thomas Sondergaard
5 : Copyright (c) 2015-2022 Made to Order Software Corp. All Rights Reserved
6 :
7 : This library is free software; you can redistribute it and/or
8 : modify it under the terms of the GNU Lesser General Public
9 : License as published by the Free Software Foundation; either
10 : version 2.1 of the License, or (at your option) any later version.
11 :
12 : This library is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : Lesser General Public License for more details.
16 :
17 : You should have received a copy of the GNU Lesser General Public
18 : License along with this library; if not, write to the Free Software
19 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 : */
21 :
22 : /** \file
23 : *
24 : * Zipios unit tests for the DirectoryCollection class.
25 : */
26 :
27 : #include "catch_main.hpp"
28 :
29 : #include <zipios/directorycollection.hpp>
30 : #include <zipios/zipiosexceptions.hpp>
31 : #include <zipios/dosdatetime.hpp>
32 :
33 : #include <fstream>
34 : #include <memory>
35 : #include <vector>
36 :
37 : #include <unistd.h>
38 : #include <string.h>
39 :
40 :
41 :
42 :
43 :
44 2 : CATCH_SCENARIO("DirectoryCollection with invalid paths", "[DirectoryCollection] [FileCollection]")
45 : {
46 2 : CATCH_GIVEN("an empty directory collection")
47 : {
48 2 : zipios::DirectoryCollection dc;
49 :
50 : // first, check that the object is setup as expected
51 2 : CATCH_START_SECTION("verify that the object looks as expected")
52 : {
53 1 : CATCH_REQUIRE(dc.isValid());
54 1 : CATCH_REQUIRE_FALSE(dc.entries().empty());
55 1 : CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
56 1 : CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
57 1 : CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
58 1 : CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
59 1 : CATCH_REQUIRE(dc.getName() == "-"); // default name is "-"
60 1 : CATCH_REQUIRE(dc.size() == 1);
61 1 : dc.mustBeValid();
62 :
63 1 : zipios::DirectoryCollection copy_constructor(dc);
64 1 : CATCH_REQUIRE(copy_constructor.isValid());
65 1 : CATCH_REQUIRE_FALSE(copy_constructor.entries().empty());
66 1 : CATCH_REQUIRE_FALSE(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
67 1 : CATCH_REQUIRE_FALSE(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
68 1 : CATCH_REQUIRE_FALSE(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
69 1 : CATCH_REQUIRE_FALSE(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
70 1 : CATCH_REQUIRE(copy_constructor.getName() == "-"); // copy name as is
71 1 : CATCH_REQUIRE(copy_constructor.size() == 1);
72 1 : copy_constructor.mustBeValid();
73 :
74 1 : zipios::DirectoryCollection copy_assignment;
75 1 : copy_assignment = dc;
76 1 : CATCH_REQUIRE(copy_assignment.isValid());
77 1 : CATCH_REQUIRE_FALSE(copy_assignment.entries().empty());
78 1 : CATCH_REQUIRE_FALSE(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
79 1 : CATCH_REQUIRE_FALSE(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
80 1 : CATCH_REQUIRE_FALSE(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
81 1 : CATCH_REQUIRE_FALSE(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
82 1 : CATCH_REQUIRE(copy_assignment.getName() == "-"); // copy name as is
83 1 : CATCH_REQUIRE(copy_assignment.size() == 1);
84 1 : copy_assignment.mustBeValid();
85 :
86 1 : zipios::FileCollection::pointer_t clone(dc.clone());
87 1 : CATCH_REQUIRE(dynamic_cast<zipios::DirectoryCollection *>(clone.get()));
88 1 : CATCH_REQUIRE(clone->isValid());
89 1 : CATCH_REQUIRE_FALSE(clone->entries().empty());
90 1 : CATCH_REQUIRE_FALSE(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
91 1 : CATCH_REQUIRE_FALSE(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
92 1 : CATCH_REQUIRE_FALSE(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
93 1 : CATCH_REQUIRE_FALSE(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
94 1 : CATCH_REQUIRE(clone->getName() == "-"); // copy name as is
95 1 : CATCH_REQUIRE(clone->size() == 1);
96 1 : clone->mustBeValid();
97 1 : }
98 2 : CATCH_END_SECTION()
99 :
100 2 : CATCH_WHEN("closing the directory")
101 : {
102 1 : dc.close();
103 :
104 1 : CATCH_THEN("it is still the same")
105 : {
106 1 : CATCH_REQUIRE_FALSE(dc.isValid());
107 1 : CATCH_REQUIRE_THROWS_AS(dc.entries().empty(), zipios::InvalidStateException);
108 3 : CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
109 3 : CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
110 3 : CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
111 3 : CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
112 1 : CATCH_REQUIRE_THROWS_AS(dc.getName(), zipios::InvalidStateException); // default name is "-"
113 1 : CATCH_REQUIRE_THROWS_AS(dc.size(), zipios::InvalidStateException);
114 1 : CATCH_REQUIRE_THROWS_AS(dc.mustBeValid(), zipios::InvalidStateException);
115 :
116 1 : zipios::DirectoryCollection copy_constructor(dc);
117 1 : CATCH_REQUIRE_FALSE(copy_constructor.isValid());
118 1 : CATCH_REQUIRE_THROWS_AS(copy_constructor.entries().empty(), zipios::InvalidStateException);
119 3 : CATCH_REQUIRE_THROWS_AS(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
120 3 : CATCH_REQUIRE_THROWS_AS(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
121 3 : CATCH_REQUIRE_THROWS_AS(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
122 3 : CATCH_REQUIRE_THROWS_AS(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
123 1 : CATCH_REQUIRE_THROWS_AS(copy_constructor.getName(), zipios::InvalidStateException); // copy name as is
124 1 : CATCH_REQUIRE_THROWS_AS(copy_constructor.size(), zipios::InvalidStateException);
125 1 : CATCH_REQUIRE_THROWS_AS(copy_constructor.mustBeValid(), zipios::InvalidStateException);
126 :
127 1 : zipios::DirectoryCollection copy_assignment;
128 1 : copy_assignment = dc;
129 1 : CATCH_REQUIRE_FALSE(copy_assignment.isValid());
130 1 : CATCH_REQUIRE_THROWS_AS(copy_assignment.entries().empty(), zipios::InvalidStateException);
131 3 : CATCH_REQUIRE_THROWS_AS(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
132 3 : CATCH_REQUIRE_THROWS_AS(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
133 3 : CATCH_REQUIRE_THROWS_AS(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
134 3 : CATCH_REQUIRE_THROWS_AS(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
135 1 : CATCH_REQUIRE_THROWS_AS(copy_assignment.getName(), zipios::InvalidStateException); // copy name as is
136 1 : CATCH_REQUIRE_THROWS_AS(copy_assignment.size(), zipios::InvalidStateException);
137 1 : CATCH_REQUIRE_THROWS_AS(copy_assignment.mustBeValid(), zipios::InvalidStateException);
138 :
139 1 : zipios::FileCollection::pointer_t clone(dc.clone());
140 1 : CATCH_REQUIRE(dynamic_cast<zipios::DirectoryCollection *>(clone.get()));
141 1 : CATCH_REQUIRE_FALSE(clone->isValid());
142 1 : CATCH_REQUIRE_THROWS_AS(clone->entries().empty(), zipios::InvalidStateException);
143 3 : CATCH_REQUIRE_THROWS_AS(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
144 3 : CATCH_REQUIRE_THROWS_AS(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
145 3 : CATCH_REQUIRE_THROWS_AS(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
146 3 : CATCH_REQUIRE_THROWS_AS(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
147 1 : CATCH_REQUIRE_THROWS_AS(clone->getName(), zipios::InvalidStateException); // copy name as is
148 1 : CATCH_REQUIRE_THROWS_AS(clone->size(), zipios::InvalidStateException);
149 1 : CATCH_REQUIRE_THROWS_AS(clone->mustBeValid(), zipios::InvalidStateException);
150 2 : }
151 2 : }
152 4 : }
153 2 : }
154 :
155 :
156 2 : CATCH_TEST_CASE("DirectoryCollection_with_a_valid_file_but_no_directory", "[DirectoryCollection][FileCollection]")
157 : {
158 2 : zipios_test::safe_chdir cwd(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
159 4 : zipios_test::auto_unlink_t auto_unlink("directory-collection-test.txt", true);
160 :
161 : // create a small random file
162 2 : int const file_size(rand() % 100 + 20);
163 : {
164 : // create a file
165 2 : std::ofstream f("directory-collection-test.txt", std::ios::out | std::ios::binary);
166 76 : for(int j(0); j < file_size; ++j)
167 : {
168 74 : char const c(rand());
169 74 : f << c;
170 : }
171 2 : }
172 :
173 2 : CATCH_START_SECTION("verify that the object looks as expected in recursive mode")
174 : {
175 : // recursive reading
176 2 : zipios::DirectoryCollection dc("directory-collection-test.txt", true);
177 :
178 : // not valid because it is not a directory
179 1 : CATCH_REQUIRE(dc.isValid());
180 1 : CATCH_REQUIRE_FALSE(dc.entries().empty());
181 1 : CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
182 1 : CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
183 1 : CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
184 1 : CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
185 1 : CATCH_REQUIRE(dc.getName() == "directory-collection-test.txt");
186 1 : CATCH_REQUIRE(dc.size() == 1);
187 1 : dc.mustBeValid();
188 :
189 1 : dc.close();
190 :
191 : // not valid because it is not a directory
192 1 : CATCH_REQUIRE_FALSE(dc.isValid());
193 1 : CATCH_REQUIRE_THROWS_AS(dc.entries().empty(), zipios::InvalidStateException);
194 3 : CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
195 3 : CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
196 3 : CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
197 3 : CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
198 1 : CATCH_REQUIRE_THROWS_AS(dc.getName(), zipios::InvalidStateException);
199 1 : CATCH_REQUIRE_THROWS_AS(dc.size(), zipios::InvalidStateException);
200 1 : CATCH_REQUIRE_THROWS_AS(dc.mustBeValid(), zipios::InvalidStateException);
201 1 : }
202 2 : CATCH_END_SECTION()
203 :
204 2 : CATCH_START_SECTION("verify that the object looks as expected in non-recursive mode")
205 : {
206 : // recursive reading
207 2 : zipios::DirectoryCollection dc("directory-collection-test.txt", false);
208 :
209 : // not valid because it is not a directory
210 1 : CATCH_REQUIRE(dc.isValid());
211 1 : CATCH_REQUIRE_FALSE(dc.entries().empty());
212 1 : CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
213 1 : CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
214 1 : CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
215 1 : CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
216 1 : CATCH_REQUIRE(dc.getName() == "directory-collection-test.txt");
217 1 : CATCH_REQUIRE(dc.size() == 1);
218 1 : dc.mustBeValid();
219 :
220 1 : dc.close();
221 :
222 : // not valid because it is not a directory
223 1 : CATCH_REQUIRE_FALSE(dc.isValid());
224 1 : CATCH_REQUIRE_THROWS_AS(dc.entries().empty(), zipios::InvalidStateException);
225 3 : CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
226 3 : CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
227 3 : CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
228 3 : CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
229 1 : CATCH_REQUIRE_THROWS_AS(dc.getName(), zipios::InvalidStateException);
230 1 : CATCH_REQUIRE_THROWS_AS(dc.size(), zipios::InvalidStateException);
231 1 : CATCH_REQUIRE_THROWS_AS(dc.mustBeValid(), zipios::InvalidStateException);
232 1 : }
233 2 : CATCH_END_SECTION()
234 2 : }
235 :
236 :
237 1 : CATCH_TEST_CASE("DirectoryCollection_with_valid_trees_of_files", "[DirectoryCollection][FileCollection]")
238 : {
239 1 : zipios_test::safe_chdir cwd(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
240 :
241 7 : for(int i(0); i < 6; ++i)
242 : {
243 : // create a directory tree starting in "tree"
244 6 : CATCH_REQUIRE(system("rm -rf tree") == 0); // clean up, just in case
245 6 : size_t const start_count(rand() % 40 + 80);
246 12 : zipios_test::file_t tree(zipios_test::file_t::type_t::DIRECTORY, start_count, "tree");
247 :
248 : {
249 12 : zipios::DirectoryCollection dc(zipios::DirectoryCollection("tree", true));
250 :
251 : {
252 6 : CATCH_REQUIRE(dc.isValid());
253 6 : CATCH_REQUIRE_FALSE(dc.entries().empty());
254 6 : CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
255 6 : CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
256 6 : CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
257 6 : CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
258 6 : CATCH_REQUIRE(dc.getName() == "tree");
259 6 : CATCH_REQUIRE(dc.size() == tree.size());
260 6 : dc.mustBeValid(); // not throwing
261 :
262 : {
263 6 : std::ostringstream expected_output;
264 6 : expected_output << "collection 'tree' {";
265 6 : zipios::FileEntry::vector_t v(dc.entries());
266 7145 : for(auto it(v.begin()); it != v.end(); ++it)
267 : {
268 7139 : zipios::FileEntry::pointer_t entry(*it);
269 :
270 7139 : if(it != v.begin())
271 : {
272 7133 : expected_output << ", ";
273 : }
274 7139 : expected_output << entry->getName();
275 :
276 : // verify that our tree knows about this file
277 7139 : zipios_test::file_t::type_t t(tree.find(entry->getName()));
278 7139 : CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
279 :
280 : struct stat file_stats;
281 7139 : CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
282 :
283 7139 : CATCH_REQUIRE((*it)->getComment().empty());
284 7139 : CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
285 7139 : CATCH_REQUIRE((*it)->getCrc() == 0);
286 7139 : CATCH_REQUIRE((*it)->getEntryOffset() == 0);
287 7139 : CATCH_REQUIRE((*it)->getExtra().empty());
288 7139 : CATCH_REQUIRE((*it)->getHeaderSize() == 0);
289 7139 : CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
290 : //CATCH_REQUIRE((*it)->getName() == ...);
291 : //CATCH_REQUIRE((*it)->getFileName() == ...);
292 7139 : zipios::DOSDateTime dt;
293 7139 : dt.setUnixTimestamp(file_stats.st_mtime);
294 7139 : CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
295 7139 : CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
296 7139 : CATCH_REQUIRE_FALSE((*it)->hasCrc());
297 7139 : if(t == zipios_test::file_t::type_t::DIRECTORY)
298 : {
299 732 : CATCH_REQUIRE((*it)->isDirectory());
300 732 : CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
301 : }
302 : else
303 : {
304 6407 : CATCH_REQUIRE_FALSE((*it)->isDirectory());
305 6407 : CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
306 : }
307 7139 : CATCH_REQUIRE((*it)->isValid());
308 : //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
309 :
310 7139 : CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
311 7139 : CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
312 7139 : }
313 6 : expected_output << "}";
314 :
315 6 : std::ostringstream output;
316 6 : output << dc;
317 6 : CATCH_REQUIRE(expected_output.str() == output.str());
318 6 : }
319 : }
320 :
321 : {
322 6 : zipios::DirectoryCollection copy_constructor(dc);
323 6 : CATCH_REQUIRE(copy_constructor.isValid());
324 6 : CATCH_REQUIRE_FALSE(copy_constructor.entries().empty());
325 6 : CATCH_REQUIRE_FALSE(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
326 6 : CATCH_REQUIRE_FALSE(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
327 6 : CATCH_REQUIRE_FALSE(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
328 6 : CATCH_REQUIRE_FALSE(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
329 6 : CATCH_REQUIRE(copy_constructor.getName() == "tree");
330 6 : CATCH_REQUIRE(copy_constructor.size() == tree.size());
331 6 : copy_constructor.mustBeValid();
332 :
333 : {
334 6 : zipios::FileEntry::vector_t v(copy_constructor.entries());
335 7145 : for(auto it(v.begin()); it != v.end(); ++it)
336 : {
337 7139 : zipios::FileEntry::pointer_t entry(*it);
338 :
339 : // verify that our tree knows about this file
340 7139 : zipios_test::file_t::type_t t(tree.find(entry->getName()));
341 7139 : CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
342 :
343 : struct stat file_stats;
344 7139 : CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
345 :
346 7139 : CATCH_REQUIRE((*it)->getComment().empty());
347 7139 : CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
348 7139 : CATCH_REQUIRE((*it)->getCrc() == 0);
349 7139 : CATCH_REQUIRE((*it)->getEntryOffset() == 0);
350 7139 : CATCH_REQUIRE((*it)->getExtra().empty());
351 7139 : CATCH_REQUIRE((*it)->getHeaderSize() == 0);
352 7139 : CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
353 : //CATCH_REQUIRE((*it)->getName() == ...);
354 : //CATCH_REQUIRE((*it)->getFileName() == ...);
355 7139 : zipios::DOSDateTime dt;
356 7139 : dt.setUnixTimestamp(file_stats.st_mtime);
357 7139 : CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
358 7139 : CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
359 7139 : CATCH_REQUIRE_FALSE((*it)->hasCrc());
360 7139 : if(t == zipios_test::file_t::type_t::DIRECTORY)
361 : {
362 732 : CATCH_REQUIRE((*it)->isDirectory());
363 732 : CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
364 : }
365 : else
366 : {
367 6407 : CATCH_REQUIRE_FALSE((*it)->isDirectory());
368 6407 : CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
369 : }
370 7139 : CATCH_REQUIRE((*it)->isValid());
371 : //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
372 :
373 7139 : CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
374 7139 : CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
375 7139 : }
376 6 : }
377 6 : }
378 :
379 : {
380 6 : zipios::DirectoryCollection copy_assignment;
381 6 : copy_assignment = dc;
382 6 : CATCH_REQUIRE(copy_assignment.isValid());
383 6 : CATCH_REQUIRE_FALSE(copy_assignment.entries().empty());
384 6 : CATCH_REQUIRE_FALSE(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
385 6 : CATCH_REQUIRE_FALSE(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
386 6 : CATCH_REQUIRE_FALSE(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
387 6 : CATCH_REQUIRE_FALSE(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
388 6 : CATCH_REQUIRE(copy_assignment.getName() == "tree"); // copy name as is
389 6 : CATCH_REQUIRE(copy_assignment.size() == tree.size());
390 6 : copy_assignment.mustBeValid();
391 :
392 : {
393 6 : zipios::FileEntry::vector_t v(copy_assignment.entries());
394 7145 : for(auto it(v.begin()); it != v.end(); ++it)
395 : {
396 7139 : zipios::FileEntry::pointer_t entry(*it);
397 :
398 : // verify that our tree knows about this file
399 7139 : zipios_test::file_t::type_t t(tree.find(entry->getName()));
400 7139 : CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
401 :
402 : struct stat file_stats;
403 7139 : CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
404 :
405 7139 : CATCH_REQUIRE((*it)->getComment().empty());
406 7139 : CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
407 7139 : CATCH_REQUIRE((*it)->getCrc() == 0);
408 7139 : CATCH_REQUIRE((*it)->getEntryOffset() == 0);
409 7139 : CATCH_REQUIRE((*it)->getExtra().empty());
410 7139 : CATCH_REQUIRE((*it)->getHeaderSize() == 0);
411 7139 : CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
412 : //CATCH_REQUIRE((*it)->getName() == ...);
413 : //CATCH_REQUIRE((*it)->getFileName() == ...);
414 7139 : zipios::DOSDateTime dt;
415 7139 : dt.setUnixTimestamp(file_stats.st_mtime);
416 7139 : CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
417 7139 : CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
418 7139 : CATCH_REQUIRE_FALSE((*it)->hasCrc());
419 7139 : if(t == zipios_test::file_t::type_t::DIRECTORY)
420 : {
421 732 : CATCH_REQUIRE((*it)->isDirectory());
422 732 : CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
423 : }
424 : else
425 : {
426 6407 : CATCH_REQUIRE_FALSE((*it)->isDirectory());
427 6407 : CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
428 : }
429 7139 : CATCH_REQUIRE((*it)->isValid());
430 : //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
431 :
432 7139 : CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
433 7139 : CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
434 7139 : }
435 6 : }
436 6 : }
437 :
438 : {
439 6 : zipios::FileCollection::pointer_t clone(dc.clone());
440 6 : CATCH_REQUIRE(dynamic_cast<zipios::DirectoryCollection *>(clone.get()));
441 6 : CATCH_REQUIRE(clone->isValid());
442 6 : CATCH_REQUIRE_FALSE(clone->entries().empty());
443 6 : CATCH_REQUIRE_FALSE(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
444 6 : CATCH_REQUIRE_FALSE(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
445 6 : CATCH_REQUIRE_FALSE(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
446 6 : CATCH_REQUIRE_FALSE(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
447 6 : CATCH_REQUIRE(clone->getName() == "tree");
448 6 : CATCH_REQUIRE(clone->size() == tree.size());
449 6 : clone->mustBeValid();
450 :
451 : {
452 6 : zipios::FileEntry::vector_t v(clone->entries());
453 7145 : for(auto it(v.begin()); it != v.end(); ++it)
454 : {
455 7139 : zipios::FileEntry::pointer_t entry(*it);
456 :
457 : // verify that our tree knows about this file
458 7139 : zipios_test::file_t::type_t t(tree.find(entry->getName()));
459 7139 : CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
460 :
461 : struct stat file_stats;
462 7139 : CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
463 :
464 7139 : CATCH_REQUIRE((*it)->getComment().empty());
465 7139 : CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
466 7139 : CATCH_REQUIRE((*it)->getCrc() == 0);
467 7139 : CATCH_REQUIRE((*it)->getEntryOffset() == 0);
468 7139 : CATCH_REQUIRE((*it)->getExtra().empty());
469 7139 : CATCH_REQUIRE((*it)->getHeaderSize() == 0);
470 7139 : CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
471 : //CATCH_REQUIRE((*it)->getName() == ...);
472 : //CATCH_REQUIRE((*it)->getFileName() == ...);
473 7139 : zipios::DOSDateTime dt;
474 7139 : dt.setUnixTimestamp(file_stats.st_mtime);
475 7139 : CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
476 7139 : CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
477 7139 : CATCH_REQUIRE_FALSE((*it)->hasCrc());
478 7139 : if(t == zipios_test::file_t::type_t::DIRECTORY)
479 : {
480 732 : CATCH_REQUIRE((*it)->isDirectory());
481 732 : CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
482 : }
483 : else
484 : {
485 6407 : CATCH_REQUIRE_FALSE((*it)->isDirectory());
486 6407 : CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
487 : }
488 7139 : CATCH_REQUIRE((*it)->isValid());
489 : //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
490 :
491 7139 : CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
492 7139 : CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
493 7139 : }
494 6 : }
495 6 : }
496 :
497 : {
498 : // this one is recursive so we get ALL the files in
499 : // the collection
500 6 : zipios_test::file_t::filenames_t all_files(tree.get_all_filenames());
501 :
502 7145 : for(auto it(all_files.begin()); it != all_files.end(); ++it)
503 : {
504 7139 : std::string const name(*it);
505 :
506 7139 : if(!name.empty() && name.back() == '/') // Directory?
507 : {
508 : // directories cannot be attached to an istream
509 732 : zipios::DirectoryCollection::stream_pointer_t is1(dc.getInputStream(name));
510 732 : CATCH_REQUIRE_FALSE(is1);
511 :
512 : // also test without the ending '/', just in case
513 732 : zipios::DirectoryCollection::stream_pointer_t is2(dc.getInputStream(name.substr(0, name.length() - 1)));
514 732 : CATCH_REQUIRE_FALSE(is2);
515 :
516 : // now also test the getEntry() which works with MATCH
517 : // or IGNORE -- prove it!
518 732 : zipios::FileEntry::pointer_t entry_match(dc.getEntry(name.substr(0, name.length() - 1), zipios::FileCollection::MatchPath::MATCH));
519 732 : CATCH_REQUIRE(entry_match);
520 :
521 732 : std::string::size_type pos(name.rfind('/', name.length() - 2));
522 732 : if(pos == std::string::npos)
523 : {
524 6 : pos = 0;
525 : }
526 : else
527 : {
528 726 : ++pos;
529 : }
530 732 : zipios::FileEntry::pointer_t entry_ignore(dc.getEntry(name.substr(pos, name.length() - 1 - pos), zipios::FileCollection::MatchPath::IGNORE));
531 732 : CATCH_REQUIRE(entry_ignore);
532 732 : }
533 : else
534 : {
535 : // files must all work and we can read them and
536 : // compare with the "real thing" and it is equal
537 6407 : zipios::FileCollection::stream_pointer_t is(dc.getInputStream(name));
538 6407 : CATCH_REQUIRE(is);
539 :
540 6407 : std::ifstream in(name, std::ios::in | std::ios::binary);
541 :
542 49786 : while(in && *is)
543 : {
544 : char buf1[BUFSIZ], buf2[BUFSIZ];
545 :
546 43379 : in.read(buf1, sizeof(buf1));
547 43379 : std::streamsize sz1(in.gcount());
548 :
549 43379 : is->read(buf2, sizeof(buf2));
550 43379 : std::streamsize sz2(is->gcount());
551 :
552 43379 : CATCH_REQUIRE(sz1 == sz2);
553 43379 : CATCH_REQUIRE(memcmp(buf1, buf2, sz1) == 0);
554 : }
555 :
556 6407 : CATCH_REQUIRE_FALSE(in);
557 6407 : CATCH_REQUIRE_FALSE(*is);
558 :
559 : // now also test the getEntry() which works with MATCH
560 : // or IGNORE -- prove it!
561 6407 : zipios::FileEntry::pointer_t entry_match(dc.getEntry(name, zipios::FileCollection::MatchPath::MATCH));
562 6407 : CATCH_REQUIRE(entry_match);
563 :
564 6407 : std::string::size_type pos(name.rfind('/'));
565 6407 : if(pos == std::string::npos)
566 : {
567 : pos = 0; // LCOV_EXCL_LINE
568 : }
569 : else
570 : {
571 6407 : ++pos;
572 : }
573 6407 : zipios::FileEntry::pointer_t entry_ignore(dc.getEntry(name.substr(pos, name.length() - pos), zipios::FileCollection::MatchPath::IGNORE));
574 6407 : CATCH_REQUIRE(entry_ignore);
575 6407 : }
576 7139 : }
577 6 : }
578 :
579 : {
580 6 : dc.close();
581 :
582 : // not valid because it was closed
583 6 : CATCH_REQUIRE_FALSE(dc.isValid());
584 6 : CATCH_REQUIRE_THROWS_AS(dc.entries().empty(), zipios::InvalidStateException);
585 18 : CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
586 18 : CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
587 18 : CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
588 18 : CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
589 6 : CATCH_REQUIRE_THROWS_AS(dc.getName(), zipios::InvalidStateException);
590 6 : CATCH_REQUIRE_THROWS_AS(dc.size(), zipios::InvalidStateException);
591 6 : CATCH_REQUIRE_THROWS_AS(dc.mustBeValid(), zipios::InvalidStateException);
592 : }
593 6 : }
594 :
595 : {
596 12 : zipios::DirectoryCollection dc(zipios::DirectoryCollection("tree", false));
597 :
598 : {
599 6 : CATCH_REQUIRE(dc.isValid());
600 6 : CATCH_REQUIRE_FALSE(dc.entries().empty());
601 6 : CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
602 6 : CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
603 6 : CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
604 6 : CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
605 6 : CATCH_REQUIRE(dc.getName() == "tree");
606 6 : CATCH_REQUIRE(dc.size() == tree.children().size() + 1);
607 6 : dc.mustBeValid(); // not throwing
608 :
609 : {
610 6 : zipios::FileEntry::vector_t v(dc.entries());
611 651 : for(auto it(v.begin()); it != v.end(); ++it)
612 : {
613 645 : zipios::FileEntry::pointer_t entry(*it);
614 :
615 : // verify that our tree knows about this file
616 645 : zipios_test::file_t::type_t t(tree.find(entry->getName()));
617 645 : CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
618 :
619 : struct stat file_stats;
620 645 : CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
621 :
622 645 : CATCH_REQUIRE((*it)->getComment().empty());
623 645 : CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
624 645 : CATCH_REQUIRE((*it)->getCrc() == 0);
625 645 : CATCH_REQUIRE((*it)->getEntryOffset() == 0);
626 645 : CATCH_REQUIRE((*it)->getExtra().empty());
627 645 : CATCH_REQUIRE((*it)->getHeaderSize() == 0);
628 645 : CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
629 : //CATCH_REQUIRE((*it)->getName() == ...);
630 : //CATCH_REQUIRE((*it)->getFileName() == ...);
631 645 : zipios::DOSDateTime dt;
632 645 : dt.setUnixTimestamp(file_stats.st_mtime);
633 645 : CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
634 645 : CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
635 645 : CATCH_REQUIRE_FALSE((*it)->hasCrc());
636 645 : if(t == zipios_test::file_t::type_t::DIRECTORY)
637 : {
638 77 : CATCH_REQUIRE((*it)->isDirectory());
639 77 : CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
640 : }
641 : else
642 : {
643 568 : CATCH_REQUIRE_FALSE((*it)->isDirectory());
644 568 : CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
645 : }
646 645 : CATCH_REQUIRE((*it)->isValid());
647 : //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
648 :
649 645 : CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
650 645 : CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
651 645 : }
652 6 : }
653 :
654 6 : zipios::DirectoryCollection copy_constructor(dc);
655 6 : CATCH_REQUIRE(copy_constructor.isValid());
656 6 : CATCH_REQUIRE_FALSE(copy_constructor.entries().empty());
657 6 : CATCH_REQUIRE_FALSE(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
658 6 : CATCH_REQUIRE_FALSE(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
659 6 : CATCH_REQUIRE_FALSE(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
660 6 : CATCH_REQUIRE_FALSE(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
661 6 : CATCH_REQUIRE(copy_constructor.getName() == "tree");
662 6 : CATCH_REQUIRE(copy_constructor.size() == tree.children().size() + 1);
663 6 : copy_constructor.mustBeValid();
664 :
665 : {
666 6 : zipios::FileEntry::vector_t v(copy_constructor.entries());
667 651 : for(auto it(v.begin()); it != v.end(); ++it)
668 : {
669 645 : zipios::FileEntry::pointer_t entry(*it);
670 :
671 : // verify that our tree knows about this file
672 645 : zipios_test::file_t::type_t t(tree.find(entry->getName()));
673 645 : CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
674 :
675 : struct stat file_stats;
676 645 : CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
677 :
678 645 : CATCH_REQUIRE((*it)->getComment().empty());
679 645 : CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
680 645 : CATCH_REQUIRE((*it)->getCrc() == 0);
681 645 : CATCH_REQUIRE((*it)->getEntryOffset() == 0);
682 645 : CATCH_REQUIRE((*it)->getExtra().empty());
683 645 : CATCH_REQUIRE((*it)->getHeaderSize() == 0);
684 645 : CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
685 : //CATCH_REQUIRE((*it)->getName() == ...);
686 : //CATCH_REQUIRE((*it)->getFileName() == ...);
687 645 : zipios::DOSDateTime dt;
688 645 : dt.setUnixTimestamp(file_stats.st_mtime);
689 645 : CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
690 645 : CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
691 645 : CATCH_REQUIRE_FALSE((*it)->hasCrc());
692 645 : if(t == zipios_test::file_t::type_t::DIRECTORY)
693 : {
694 77 : CATCH_REQUIRE((*it)->isDirectory());
695 77 : CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
696 : }
697 : else
698 : {
699 568 : CATCH_REQUIRE_FALSE((*it)->isDirectory());
700 568 : CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
701 : }
702 645 : CATCH_REQUIRE((*it)->isValid());
703 : //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
704 :
705 645 : CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
706 645 : CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
707 645 : }
708 6 : }
709 :
710 6 : zipios::DirectoryCollection copy_assignment;
711 6 : copy_assignment = dc;
712 6 : CATCH_REQUIRE(copy_assignment.isValid());
713 6 : CATCH_REQUIRE_FALSE(copy_assignment.entries().empty());
714 6 : CATCH_REQUIRE_FALSE(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
715 6 : CATCH_REQUIRE_FALSE(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
716 6 : CATCH_REQUIRE_FALSE(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
717 6 : CATCH_REQUIRE_FALSE(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
718 6 : CATCH_REQUIRE(copy_assignment.getName() == "tree"); // copy name as is
719 6 : CATCH_REQUIRE(copy_assignment.size() == tree.children().size() + 1);
720 6 : copy_assignment.mustBeValid();
721 :
722 : {
723 6 : zipios::FileEntry::vector_t v(copy_assignment.entries());
724 651 : for(auto it(v.begin()); it != v.end(); ++it)
725 : {
726 645 : zipios::FileEntry::pointer_t entry(*it);
727 :
728 : // verify that our tree knows about this file
729 645 : zipios_test::file_t::type_t t(tree.find(entry->getName()));
730 645 : CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
731 :
732 : struct stat file_stats;
733 645 : CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
734 :
735 645 : CATCH_REQUIRE((*it)->getComment().empty());
736 645 : CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
737 645 : CATCH_REQUIRE((*it)->getCrc() == 0);
738 645 : CATCH_REQUIRE((*it)->getEntryOffset() == 0);
739 645 : CATCH_REQUIRE((*it)->getExtra().empty());
740 645 : CATCH_REQUIRE((*it)->getHeaderSize() == 0);
741 645 : CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
742 : //CATCH_REQUIRE((*it)->getName() == ...);
743 : //CATCH_REQUIRE((*it)->getFileName() == ...);
744 645 : zipios::DOSDateTime dt;
745 645 : dt.setUnixTimestamp(file_stats.st_mtime);
746 645 : CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
747 645 : CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
748 645 : CATCH_REQUIRE_FALSE((*it)->hasCrc());
749 645 : if(t == zipios_test::file_t::type_t::DIRECTORY)
750 : {
751 77 : CATCH_REQUIRE((*it)->isDirectory());
752 77 : CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
753 : }
754 : else
755 : {
756 568 : CATCH_REQUIRE_FALSE((*it)->isDirectory());
757 568 : CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
758 : }
759 645 : CATCH_REQUIRE((*it)->isValid());
760 : //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
761 :
762 645 : CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
763 645 : CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
764 645 : }
765 6 : }
766 :
767 6 : zipios::FileCollection::pointer_t clone(dc.clone());
768 6 : CATCH_REQUIRE(dynamic_cast<zipios::DirectoryCollection *>(clone.get()));
769 6 : CATCH_REQUIRE(clone->isValid());
770 6 : CATCH_REQUIRE_FALSE(clone->entries().empty());
771 6 : CATCH_REQUIRE_FALSE(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
772 6 : CATCH_REQUIRE_FALSE(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
773 6 : CATCH_REQUIRE_FALSE(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
774 6 : CATCH_REQUIRE_FALSE(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
775 6 : CATCH_REQUIRE(clone->getName() == "tree");
776 6 : CATCH_REQUIRE(clone->size() == tree.children().size() + 1);
777 6 : clone->mustBeValid();
778 :
779 : {
780 6 : zipios::FileEntry::vector_t v(clone->entries());
781 651 : for(auto it(v.begin()); it != v.end(); ++it)
782 : {
783 645 : zipios::FileEntry::pointer_t entry(*it);
784 :
785 : // verify that our tree knows about this file
786 645 : zipios_test::file_t::type_t t(tree.find(entry->getName()));
787 645 : CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
788 :
789 : struct stat file_stats;
790 645 : CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
791 :
792 645 : CATCH_REQUIRE((*it)->getComment().empty());
793 645 : CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
794 645 : CATCH_REQUIRE((*it)->getCrc() == 0);
795 645 : CATCH_REQUIRE((*it)->getEntryOffset() == 0);
796 645 : CATCH_REQUIRE((*it)->getExtra().empty());
797 645 : CATCH_REQUIRE((*it)->getHeaderSize() == 0);
798 645 : CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
799 : //CATCH_REQUIRE((*it)->getName() == ...);
800 : //CATCH_REQUIRE((*it)->getFileName() == ...);
801 645 : zipios::DOSDateTime dt;
802 645 : dt.setUnixTimestamp(file_stats.st_mtime);
803 645 : CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
804 645 : CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
805 645 : CATCH_REQUIRE_FALSE((*it)->hasCrc());
806 645 : if(t == zipios_test::file_t::type_t::DIRECTORY)
807 : {
808 77 : CATCH_REQUIRE((*it)->isDirectory());
809 77 : CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
810 : }
811 : else
812 : {
813 568 : CATCH_REQUIRE_FALSE((*it)->isDirectory());
814 568 : CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
815 : }
816 645 : CATCH_REQUIRE((*it)->isValid());
817 : //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
818 :
819 645 : CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
820 645 : CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
821 645 : }
822 6 : }
823 6 : }
824 :
825 : {
826 : // in this case the DirectoryCollection is not recursive
827 : // so only the top children are available
828 6 : zipios_test::file_t::vector_t all_files(tree.children());
829 :
830 645 : for(auto it(all_files.begin()); it != all_files.end(); ++it)
831 : {
832 639 : zipios_test::file_t::pointer_t f(*it);
833 :
834 639 : if(f->type() == zipios_test::file_t::type_t::DIRECTORY) // Directory?
835 : {
836 : // directories cannot be attached to an istream
837 71 : zipios::DirectoryCollection::stream_pointer_t is1(dc.getInputStream(f->filename()));
838 71 : CATCH_REQUIRE_FALSE(is1);
839 71 : }
840 : else
841 : {
842 : // WARNING: in this case we get a "bare" filename
843 : // from the file_t object
844 : //
845 : // files must all work and we can read them and
846 : // compare with the "real thing" and it is equal
847 :
848 : // "tree/" missing...
849 568 : zipios::DirectoryCollection::stream_pointer_t bad_is(dc.getInputStream(f->filename(), zipios::FileCollection::MatchPath::MATCH));
850 568 : CATCH_REQUIRE_FALSE(bad_is);
851 :
852 : // in this case we ignore to see that we can indeed
853 : // get the file... unfortunately it could be another
854 : // file with the same name (although unlikely, it
855 : // is very much possible)
856 568 : zipios::DirectoryCollection::stream_pointer_t is(dc.getInputStream(f->filename(), zipios::FileCollection::MatchPath::IGNORE));
857 568 : CATCH_REQUIRE(is);
858 :
859 : // So here we verify that it find the correct
860 : // entry, if so then we can compare the files
861 568 : zipios::FileEntry::pointer_t entry_match(dc.getEntry("tree/" + f->filename(), zipios::FileCollection::MatchPath::MATCH));
862 568 : zipios::FileEntry::pointer_t entry_ignore(dc.getEntry(f->filename(), zipios::FileCollection::MatchPath::IGNORE));
863 568 : if(entry_match == entry_ignore)
864 : {
865 568 : std::ifstream in("tree/" + f->filename(), std::ios::in | std::ios::binary);
866 :
867 4390 : while(in && *is)
868 : {
869 : char buf1[BUFSIZ], buf2[BUFSIZ];
870 :
871 3822 : in.read(buf1, sizeof(buf1));
872 3822 : std::streamsize sz1(in.gcount());
873 :
874 3822 : is->read(buf2, sizeof(buf2));
875 3822 : std::streamsize sz2(is->gcount());
876 :
877 3822 : CATCH_REQUIRE(sz1 == sz2);
878 3822 : CATCH_REQUIRE(memcmp(buf1, buf2, sz1) == 0);
879 : }
880 :
881 568 : CATCH_REQUIRE_FALSE(in);
882 568 : CATCH_REQUIRE_FALSE(*is);
883 568 : }
884 568 : }
885 639 : }
886 6 : }
887 :
888 : {
889 6 : dc.close();
890 :
891 : // not valid because it is not a directory
892 6 : CATCH_REQUIRE_FALSE(dc.isValid());
893 6 : CATCH_REQUIRE_THROWS_AS(dc.entries().empty(), zipios::InvalidStateException);
894 18 : CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
895 18 : CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
896 18 : CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
897 18 : CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
898 6 : CATCH_REQUIRE_THROWS_AS(dc.getName(), zipios::InvalidStateException);
899 6 : CATCH_REQUIRE_THROWS_AS(dc.size(), zipios::InvalidStateException);
900 6 : CATCH_REQUIRE_THROWS_AS(dc.mustBeValid(), zipios::InvalidStateException);
901 : }
902 6 : }
903 6 : }
904 1 : }
905 :
906 :
907 1 : CATCH_TEST_CASE("DirectoryCollection with an existing directory that gets deleted", "[DirectoryCollection] [FileCollection]")
908 : {
909 1 : zipios_test::safe_chdir cwd(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
910 :
911 : // create a directory
912 1 : CATCH_REQUIRE(system("rm -rf tree") == 0); // clean up, just in case
913 1 : CATCH_REQUIRE(mkdir("tree", 0777) == 0);
914 :
915 : // the initialization works as expected!
916 2 : zipios::DirectoryCollection dc(zipios::DirectoryCollection("tree", false));
917 1 : CATCH_REQUIRE(dc.isValid());
918 :
919 : // now we delete that directory!
920 1 : CATCH_REQUIRE(rmdir("tree") == 0);
921 :
922 : // attempt the get the size, it throws
923 1 : CATCH_REQUIRE_THROWS_AS(dc.size(), zipios::IOException);
924 1 : CATCH_REQUIRE_FALSE(dc.isValid());
925 1 : }
926 :
927 :
928 1 : CATCH_TEST_CASE("DirectoryCollection with an empty directory", "[DirectoryCollection] [FileCollection]")
929 : {
930 1 : zipios_test::safe_chdir cwd(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
931 :
932 : // create a directory
933 1 : CATCH_REQUIRE(system("rm -rf tree") == 0); // clean up, just in case
934 1 : CATCH_REQUIRE(mkdir("tree", 0777) == 0);
935 :
936 1 : CATCH_START_SECTION("verify that the object looks as expected")
937 : {
938 2 : zipios::DirectoryCollection dc(zipios::DirectoryCollection("tree", true));
939 :
940 1 : CATCH_REQUIRE(dc.isValid());
941 1 : CATCH_REQUIRE_FALSE(dc.entries().empty());
942 1 : CATCH_REQUIRE(dc.entries().size() == 1);
943 1 : CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
944 1 : CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
945 1 : CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
946 1 : CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
947 1 : CATCH_REQUIRE(dc.getName() == "tree");
948 1 : CATCH_REQUIRE(dc.size() == 1);
949 1 : dc.mustBeValid(); // not throwing
950 :
951 : {
952 1 : zipios::FileEntry::vector_t v(dc.entries());
953 2 : for(auto it(v.begin()); it != v.end(); ++it)
954 : {
955 1 : zipios::FileEntry::pointer_t entry(*it);
956 :
957 : // verify that our tree knows about this file
958 1 : CATCH_REQUIRE(entry->getName() == "tree");
959 :
960 : struct stat file_stats;
961 1 : CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
962 :
963 1 : CATCH_REQUIRE((*it)->getComment().empty());
964 1 : CATCH_REQUIRE((*it)->getCompressedSize() == 0);
965 1 : CATCH_REQUIRE((*it)->getCrc() == 0);
966 1 : CATCH_REQUIRE((*it)->getEntryOffset() == 0);
967 1 : CATCH_REQUIRE((*it)->getExtra().empty());
968 1 : CATCH_REQUIRE((*it)->getHeaderSize() == 0);
969 1 : CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
970 1 : CATCH_REQUIRE((*it)->getName() == "tree");
971 1 : CATCH_REQUIRE((*it)->getFileName() == "tree");
972 1 : zipios::DOSDateTime t;
973 1 : t.setUnixTimestamp(file_stats.st_mtime);
974 1 : CATCH_REQUIRE((*it)->getTime() == t.getDOSDateTime());
975 1 : CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
976 1 : CATCH_REQUIRE_FALSE((*it)->hasCrc());
977 1 : CATCH_REQUIRE((*it)->isDirectory());
978 1 : CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
979 1 : CATCH_REQUIRE((*it)->isValid());
980 1 : CATCH_REQUIRE((*it)->toString() == "tree (directory)");
981 :
982 : // using the << operator to a stream we get the toString() value
983 1 : std::ostringstream output;
984 1 : output << **it;
985 1 : CATCH_REQUIRE(output.str() == "tree (directory)");
986 :
987 1 : CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
988 1 : CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
989 1 : }
990 1 : }
991 1 : }
992 1 : CATCH_END_SECTION()
993 :
994 1 : rmdir("tree");
995 1 : }
996 :
997 :
998 : // Local Variables:
999 : // mode: cpp
1000 : // indent-tabs-mode: nil
1001 : // c-basic-offset: 4
1002 : // tab-width: 4
1003 : // End:
1004 :
1005 : // vim: ts=4 sw=4 et
|