1 
2 /*
3   libzippp.h -- exported declarations.
4   Copyright (C) 2013 Cédric Tabin
5 
6   This file is part of libzippp, a library that wraps libzip for manipulating easily
7   ZIP files in C++.
8   The author can be contacted on http://www.astorm.ch/blog/index.php?contact
9 
10   Redistribution and use in source and binary forms, with or without
11   modification, are permitted provided that the following conditions
12   are met:
13   1. Redistributions of source code must retain the above copyright
14      notice, this list of conditions and the following disclaimer.
15   2. Redistributions in binary form must reproduce the above copyright
16      notice, this list of conditions and the following disclaimer in
17      the documentation and/or other materials provided with the
18      distribution.
19   3. The names of the authors may not be used to endorse or promote
20      products derived from this software without specific prior
21      written permission.
22 
23   THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
24   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
27   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
31   IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33   IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35 
36 #include <assert.h>
37 #include <string.h>
38 #include <iostream>
39 #include <iterator>
40 #include <cstdio>
41 #include <cstdlib>
42 #include <fstream>
43 #include <string>
44 
45 #include "libzippp.h"
46 
47 using namespace std;
48 using namespace libzippp;
49 
50 class SimpleProgressListener : public ZipProgressListener {
51 public:
SimpleProgressListener(void)52     SimpleProgressListener(void) : firstValue(-1), lastValue(-1) {}
~SimpleProgressListener(void)53     virtual ~SimpleProgressListener(void) {}
54 
55     double firstValue;
56     double lastValue;
57 
progression(double p)58     void progression(double p) {
59         cout << "-- Progression: " << p << endl;
60         if(firstValue<0) { firstValue = p; }
61         lastValue = p;
62     }
63 };
64 
test1()65 void test1() {
66     cout << "Running test 1...";
67 
68     ZipArchive z1("test.zip");
69     assert(!z1.isOpen());
70     assert(!z1.isMutable());
71     z1.open(ZipArchive::Write);
72     assert(z1.isOpen());
73     assert(z1.isMutable());
74     bool result = z1.addEntry("folder/subfolder/finalfolder/");
75     assert(result);
76     assert(z1.close() == LIBZIPPP_OK);
77     assert(!z1.isOpen());
78     assert(!z1.isMutable());
79 
80     ZipArchive z2("test.zip");
81     z2.open(ZipArchive::ReadOnly);
82     assert(z2.isOpen());
83     assert(!z2.isMutable());
84     int nbEntries = z2.getNbEntries();
85     assert(nbEntries==3);
86     assert(z2.hasEntry("folder/"));
87     assert(z2.hasEntry("folder/subfolder/"));
88     assert(z2.hasEntry("folder/subfolder/finalfolder/"));
89     assert(z2.close() == LIBZIPPP_OK);
90     assert(z2.unlink());
91 
92     cout << " done." << endl;
93 }
94 
test2()95 void test2() {
96     cout << "Running test 2...";
97 
98     const char* txtFile = "this is some data";
99     int len = strlen(txtFile);
100 
101     ZipArchive z1("test.zip");
102     z1.open(ZipArchive::Write);
103     z1.addData("somedata", txtFile, len);
104 
105     ZipEntry z1e1 = z1.getEntry("somedata");
106     z1e1.setCompressionEnabled(true);
107 
108     z1.close();
109 
110     ZipArchive z2("test.zip");
111     z2.open(ZipArchive::ReadOnly);
112     assert(z2.getNbEntries()==1);
113     assert(z2.hasEntry("somedata"));
114 
115     ZipEntry entry = z2.getEntry("somedata");
116     assert(!entry.isNull());
117     assert(entry.isCompressionEnabled());
118 
119     string data = entry.readAsText();
120     int clen = data.size();
121     assert(clen==len);
122     assert(strncmp(txtFile, data.c_str(), len)==0);
123 
124     z2.close();
125     z2.unlink();
126 
127     cout << " done." << endl;
128 }
129 
test3()130 void test3() {
131     cout << "Running test 3...";
132 
133     const char* txtFile = "this is some data";
134     int len = strlen(txtFile);
135 
136     ZipArchive z1("test.zip");
137     z1.open(ZipArchive::Write);
138     z1.addData("somedata/in/subfolder/data.txt", txtFile, len);
139     assert(z1.addEntry("somedata/"));
140     assert(z1.addEntry("in/"));
141     assert(z1.addEntry("in/subfolder/"));
142     z1.close();
143 
144     ZipArchive z2("test.zip");
145     z2.open(ZipArchive::ReadOnly);
146     assert(z2.getNbEntries()==6);
147     assert(z2.hasEntry("somedata/in/subfolder/data.txt"));
148 
149     ZipEntry entry = z2.getEntry("somedata/in/subfolder/data.txt");
150     assert(!entry.isNull());
151     assert(!entry.isCompressionEnabled());
152 
153     string data = entry.readAsText();
154     int clen = data.size();
155     assert(clen==len);
156     assert(strncmp(txtFile, data.c_str(), len)==0);
157 
158     z2.close();
159     z2.unlink();
160 
161     cout << " done." << endl;
162 }
163 
test4()164 void test4() {
165     cout << "Running test 4...";
166 
167     const char* txtFile = "this is some data";
168     int len = strlen(txtFile);
169 
170     ZipArchive z1("test.zip");
171     z1.open(ZipArchive::Write);
172     z1.addData("somedata/test.txt", txtFile, len);
173     z1.close();
174 
175     ZipArchive z2("test.zip");
176     z2.open(ZipArchive::Write);
177     assert(z2.getNbEntries()==2);
178 
179     ZipEntry d = z2.getEntry("somedata/test.txt");
180     assert(!d.isNull() && d.isFile());
181     assert(z2.deleteEntry(d)==1);
182     z2.close();
183     z2.unlink();
184 
185     cout << " done." << endl;
186 }
187 
test5()188 void test5() {
189     cout << "Running test 5...";
190 
191     const char* txtFile = "this is some data";
192     int len = strlen(txtFile);
193 
194     ZipArchive z1("test.zip");
195     z1.open(ZipArchive::Write);
196     z1.addData("somedata/in/subfolders/test.txt", txtFile, len);
197     z1.close();
198 
199     ZipArchive z2("test.zip");
200     z2.open(ZipArchive::Write);
201     assert(z2.getNbEntries()==4);
202 
203     ZipEntry d = z2.getEntry("somedata/in/");
204     assert(!d.isNull() && d.isDirectory());
205     assert(z2.deleteEntry(d)==3);
206     z2.close();
207     z2.unlink();
208 
209     cout << " done." << endl;
210 }
211 
test6()212 void test6() {
213     cout << "Running test 6...";
214 
215     const char* txtFile = "this is some data";
216     int len = strlen(txtFile);
217 
218     ZipArchive z1("test.zip");
219     z1.open(ZipArchive::Write);
220     z1.addData("somedata/in/subfolders/test.txt", txtFile, len);
221     z1.close();
222 
223     ZipArchive z2("test.zip");
224     z2.open(ZipArchive::Write);
225     assert(z2.getNbEntries()==4);
226 
227     ZipEntry d = z2.getEntry("somedata/in/");
228     assert(!d.isNull() && d.isDirectory());
229     assert(z2.renameEntry(d, "somedata/out/")==3);
230     z2.close();
231     z2.unlink();
232 
233     cout << " done." << endl;
234 }
235 
test7()236 void test7() {
237     cout << "Running test 7...";
238 
239     const char* txtFile = "this is some data";
240     int len = strlen(txtFile);
241 
242     ZipArchive z1("test.zip");
243     z1.open(ZipArchive::Write);
244     z1.addData("somedata/in/subfolders/test.txt", txtFile, len);
245     z1.close();
246 
247     ZipArchive z2("test.zip");
248     z2.open(ZipArchive::Write);
249     assert(z2.getNbEntries()==4);
250 
251     ZipEntry d = z2.getEntry("somedata/in/");
252     assert(!d.isNull() && d.isDirectory());
253     assert(z2.renameEntry(d, "somedata/in/subfolder/")==3);
254     z2.close();
255 
256     ZipArchive z3("test.zip");
257     z3.open(ZipArchive::ReadOnly);
258     assert(z3.getNbEntries()==5);
259     z3.close();
260     z3.unlink();
261 
262     cout << " done." << endl;
263 }
264 
test8()265 void test8() {
266     cout << "Running test 8...";
267 
268     const char* txtFile = "this is some data";
269     int len = strlen(txtFile);
270 
271     ZipArchive z1("test.zip");
272     z1.open(ZipArchive::Write);
273     z1.addData("somedata/in/subfolders/test.txt", txtFile, len);
274     z1.close();
275 
276     ZipArchive z2("test.zip");
277     z2.open(ZipArchive::Write);
278     assert(z2.getNbEntries()==4);
279 
280     ZipEntry d = z2.getEntry("somedata/in/");
281     assert(!d.isNull() && d.isDirectory());
282     assert(z2.renameEntry(d, "newdata/out/subfolders/")==3);
283     z2.close();
284 
285     ZipArchive z3("test.zip");
286     z3.open(ZipArchive::ReadOnly);
287     assert(z3.getNbEntries()==6);
288     z3.close();
289     z3.unlink();
290 
291     cout << " done." << endl;
292 }
293 
test9()294 void test9() {
295     cout << "Running test 9...";
296 
297     const char* txtFile = "this is some data";
298     int len = strlen(txtFile);
299 
300     ZipArchive z1("test.zip");
301     z1.open(ZipArchive::Write);
302     z1.addData("somedata/in/subfolders/test.txt", txtFile, len);
303     z1.addData("somedata/out/subfolders/other.txt", txtFile, len);
304     z1.close();
305 
306     ZipArchive z2("test.zip");
307     z2.open(ZipArchive::Write);
308     assert(z2.getNbEntries()==7);
309 
310     ZipEntry d = z2.getEntry("somedata/in/");
311     assert(!d.isNull() && d.isDirectory());
312     assert(z2.renameEntry(d, "root/")==3);
313     z2.close();
314 
315     ZipArchive z3("test.zip");
316     z3.open(ZipArchive::ReadOnly);
317     assert(z3.getNbEntries()==7);
318     z3.close();
319     z3.unlink();
320 
321     cout << " done." << endl;
322 }
323 
test10()324 void test10() {
325     cout << "Running test 10...";
326 
327     const char* txtFile = "this is some data";
328     int len = strlen(txtFile);
329 
330     ZipArchive z1("test.zip");
331     z1.open(ZipArchive::Write);
332     z1.addData("somedata/in/subfolders/test.txt", txtFile, len);
333     z1.close();
334 
335     ZipArchive z2("test.zip");
336     z2.open(ZipArchive::Write);
337     assert(z2.getNbEntries()==4);
338 
339     ZipEntry d = z2.getEntry("somedata/in/");
340     assert(!d.isNull() && d.isDirectory());
341     assert(z2.renameEntry(d, "newdata/out/subfolders/")==3);
342     z2.discard();
343 
344     ZipArchive z3("test.zip");
345     z3.open(ZipArchive::ReadOnly);
346     assert(z3.getNbEntries()==4);
347     z3.close();
348     z3.unlink();
349 
350     cout << " done." << endl;
351 }
352 
test11()353 void test11() {
354     cout << "Running test 11...";
355 
356     string c = "a basic comment";
357 
358     ZipArchive z1("test.zip");
359     z1.open(ZipArchive::Write);
360     z1.addEntry("test/");
361     z1.setComment(c);
362     z1.close();
363 
364     ZipArchive z2("test.zip");
365     z2.open(ZipArchive::ReadOnly);
366     string str = z2.getComment();
367     assert(str == c);
368     z2.close();
369 
370     ZipArchive z3("test.zip");
371     z3.open(ZipArchive::Write);
372     z3.removeComment();
373     z3.close();
374 
375     ZipArchive z4("test.zip");
376     z4.open(ZipArchive::ReadOnly);
377     string str2 = z4.getComment();
378     assert(str2.empty());
379     z4.close();
380     z4.unlink();
381 
382     cout << " done." << endl;
383 }
384 
test12()385 void test12() {
386     cout << "Running test 12...";
387 
388     string c = "a basic comment";
389 
390     ZipArchive z1("test.zip");
391     z1.open(ZipArchive::Write);
392     z1.addEntry("test/");
393     z1.addData("file/data.txt", c.c_str(), c.length());
394     z1.close();
395 
396     ZipArchive z2("test.zip");
397     z2.open(ZipArchive::Write);
398     z2.addEntry("content/new/");
399     z2.addData("newfile.txt", c.c_str(), c.length());
400     assert(z2.getNbEntries(ZipArchive::Current)==6);
401     assert(z2.getNbEntries(ZipArchive::Original)==3);
402     z2.close();
403     z2.unlink();
404 
405     cout << " done." << endl;
406 }
407 
test13()408 void test13() {
409     cout << "Running test 13...";
410 
411     string c = "some example of text";
412 
413     ZipArchive z1("test.zip");
414     z1.open(ZipArchive::Write);
415     z1.addEntry("test/");
416     z1.addData("file/data.txt", c.c_str(), c.length());
417     z1.close();
418 
419     ZipArchive z2("test.zip");
420     z2.open(ZipArchive::Write);
421     z2.renameEntry(z2.getEntry("file/data.txt"), "file/subdir/data.txt");
422     assert(z2.getNbEntries(ZipArchive::Current)==4);
423     assert(z2.getNbEntries(ZipArchive::Original)==3);
424     z2.close();
425     z2.unlink();
426 
427     cout << " done." << endl;
428 }
429 
test14()430 void test14() {
431     cout << "Running test 14...";
432 
433     string c = "some example of text";
434 
435     ZipArchive z1("test.zip");
436     z1.open(ZipArchive::Write);
437     z1.addEntry("test/");
438     z1.addData("file/data.txt", c.c_str(), c.length());
439     z1.close();
440 
441     ZipArchive z2("test.zip");
442     z2.open(ZipArchive::Write);
443     z2.renameEntry(z2.getEntry("file/data.txt"), "content/data/file.txt");
444     assert(z2.getNbEntries(ZipArchive::Current)==5);
445     assert(z2.getNbEntries(ZipArchive::Original)==3);
446     z2.close();
447     z2.unlink();
448 
449     cout << " done." << endl;
450 }
451 
test15()452 void test15() {
453     cout << "Running test 15...";
454 
455     const char* txtFile = "this is some data";
456     int len = strlen(txtFile);
457 
458     ZipArchive z1("test.zip");
459     z1.open(ZipArchive::Write);
460     z1.addData("somedata/in/subfolder/data.txt", txtFile, len);
461     assert(z1.addEntry("somedata/"));
462     assert(z1.addEntry("in/"));
463     assert(z1.addEntry("in/subfolder/"));
464     z1.close();
465 
466     ZipArchive z2("test.zip");
467     z2.open(ZipArchive::ReadOnly);
468     assert(z2.getNbEntries()==6);
469     assert(z2.hasEntry("somedata/in/subfolder/data.txt"));
470 
471     char* data = (char*)z2.readEntry("somedata/in/subfolder/data.txt", true);
472     int clen = strlen(data);
473     assert(clen==len);
474     assert(strncmp(txtFile, data, len)==0);
475 
476     delete[] data;
477 
478     z2.close();
479     z2.unlink();
480 
481     cout << " done." << endl;
482 }
483 
test16()484 void test16() {
485     cout << "Running test 16...";
486 
487     string c = "some example of text";
488 
489     ZipArchive z1("test.zip");
490     z1.open(ZipArchive::Write);
491     z1.addEntry("dir/");
492     z1.addData("file.txt", c.c_str(), c.length());
493 
494     ZipEntry e1 = z1.getEntry("dir/");
495     ZipEntry e2 = z1.getEntry("file.txt");
496     assert(e1.setComment("commentDir"));
497     assert(e2.setComment("commentFile"));
498     z1.close();
499 
500     ZipArchive z2("test.zip");
501     z2.open(ZipArchive::ReadOnly);
502     ZipEntry e12 = z2.getEntry("dir/");
503     ZipEntry e22 = z2.getEntry("file.txt");
504     assert(e12.getComment() == "commentDir");
505     assert(e22.getComment() == "commentFile");
506     z2.close();
507     z2.unlink();
508 
509     cout << " done." << endl;
510 }
511 
test17()512 void test17() {
513     cout << "Running test 17...";
514 
515     ZipArchive z1("test.zip");
516     assert(z1.open(ZipArchive::ReadOnly) == false);
517     void* nil1 = z1.readEntry("an/absent/file.txt", true);
518     void* nil2 = z1.readEntry("an/absent/file.txt", true);
519     assert(nil1 == NULL);
520     assert(nil2 == NULL);
521     z1.close();
522     z1.unlink();
523 
524     cout << " done." << endl;
525 }
526 
test18()527 void test18() {
528     cout << "Running test 18...";
529 
530     string entry1("a/földér/with/sûbâènts/");
531     string entry2("fïle/iñ/sûbfôlder/dàtÄ.txt");
532     string text("File wiôth sömè tîxt");
533 
534     ZipArchive z1("test.zip");
535     z1.open(ZipArchive::Write);
536     assert(z1.addEntry(entry1));
537     assert(z1.addData(entry2, text.c_str(), text.length()));
538     z1.close();
539 
540     ZipArchive z2("test.zip");
541     z2.open(ZipArchive::ReadOnly);
542     ZipEntry e1 = z2.getEntry(entry1);
543     assert(!e1.isNull());
544     assert(e1.getName() == entry1);
545 
546     ZipEntry e2 = z2.getEntry(entry2);
547     assert(!e2.isNull());
548     assert(e2.getName() == entry2);
549     assert(e2.readAsText() == text);
550 
551     z2.close();
552     z2.unlink();
553 
554     cout << " done." << endl;
555 }
556 
test19()557 void test19() {
558     cout << "Running test 19...";
559 
560     const char* txtFile = "this is some data";
561     int len = strlen(txtFile);
562 
563     ZipArchive z1("test.zip");
564     z1.open(ZipArchive::Write);
565     z1.addData("somedata", txtFile, len);
566     z1.close();
567 
568     ZipArchive z2("test.zip");
569     z2.open(ZipArchive::ReadOnly);
570     assert(z2.getNbEntries()==1);
571     assert(z2.hasEntry("somedata"));
572 
573     ZipEntry entry = z2.getEntry("somedata");
574     assert(!entry.isNull());
575 
576     string data = entry.readAsText(ZipArchive::Current, 4);
577     int clen = data.size();
578     assert(clen==4);
579     assert(strncmp("this", data.c_str(), 4)==0);
580 
581     string data2 = entry.readAsText(ZipArchive::Current, 1);
582     int clen2 = data2.size();
583     assert(clen2==1);
584     assert(strncmp("t", data2.c_str(), 1)==0);
585 
586     string data3 = entry.readAsText(ZipArchive::Current, 999);
587     int clen3 = data3.size();
588     assert(clen3==len);
589     assert(strncmp("this is some data", data3.c_str(), len)==0);
590 
591     z2.close();
592     z2.unlink();
593 
594     cout << " done." << endl;
595 }
596 
test20()597 void test20() {
598     cout << "Running test 20...";
599 
600     const char* txtFile = "this is some data";   // 17 Bytes
601     const char* txtFile2 = "this is some data!"; // 18 Bytes
602     int len = strlen(txtFile);
603     int len2 = strlen(txtFile2);
604 
605     ZipArchive z1("test.zip");
606     z1.open(ZipArchive::Write);
607     z1.addData("somedata", txtFile, len);
608     z1.addData("somedata2", txtFile2, len2);
609     z1.close();
610 
611     ZipArchive z2("test.zip");
612     z2.open(ZipArchive::ReadOnly);
613     assert(z2.getNbEntries()==2);
614     assert(z2.hasEntry("somedata"));
615     assert(z2.hasEntry("somedata2"));
616 
617     ZipEntry entry = z2.getEntry("somedata");
618     ZipEntry entry2 = z2.getEntry("somedata2");
619     assert(!entry.isNull());
620     assert(!entry2.isNull());
621 
622     {
623 		// Extract somedata with chunk of 2 bytes, which is not divisible by the file size (17 Bytes)
624 		std::ofstream ofUnzippedFile("somedata.txt");
625 		assert(static_cast<bool>(ofUnzippedFile));
626 		assert(entry.readContent(ofUnzippedFile, ZipArchive::Current, 2) == 0);
627 		ofUnzippedFile.close();
628 
629 		std::ifstream ifUnzippedFile("somedata.txt");
630 		assert(static_cast<bool>(ifUnzippedFile));
631 		std::string strSomedataText((std::istreambuf_iterator<char>(ifUnzippedFile)), std::istreambuf_iterator<char>());
632 		assert(strSomedataText.compare(txtFile) == 0);
633 		ifUnzippedFile.close();
634 		assert(remove("somedata.txt") == 0);
635     }
636 
637     {
638 		// Extract somedata with chunk of 0 bytes (will be defaulted to 512KB).
639 		std::ofstream ofUnzippedFile("somedata.txt");
640 		assert(static_cast<bool>(ofUnzippedFile));
641 		assert(entry.readContent(ofUnzippedFile, ZipArchive::Current, 0) == 0);
642 		ofUnzippedFile.close();
643 
644 		std::ifstream ifUnzippedFile("somedata.txt");
645 		assert(static_cast<bool>(ifUnzippedFile));
646 		std::string strSomedataText((std::istreambuf_iterator<char>(ifUnzippedFile)), std::istreambuf_iterator<char>());
647 		assert(strSomedataText.compare(txtFile) == 0);
648 		ifUnzippedFile.close();
649 		assert(remove("somedata.txt") == 0);
650     }
651 
652     {
653 		// Extract somedata2 with a chunk which is divisible by the size of the file (18 Bytes) to check that the modulo branch
654 		// is not accessed !
655 		std::ofstream ofUnzippedFile("somedata2.txt");
656 		assert(static_cast<bool>(ofUnzippedFile));
657 		assert(entry2.readContent(ofUnzippedFile, ZipArchive::Current, 2) == 0);
658 		ofUnzippedFile.close();
659 
660 		std::ifstream ifUnzippedFile("somedata2.txt");
661 		assert(static_cast<bool>(ifUnzippedFile));
662 		std::string strSomedataText((std::istreambuf_iterator<char>(ifUnzippedFile)), std::istreambuf_iterator<char>());
663 		assert(strSomedataText.compare(txtFile2) == 0);
664 		ifUnzippedFile.close();
665 		assert(remove("somedata2.txt") == 0);
666     }
667 
668     z2.close();
669     z2.unlink();
670 
671     cout << " done." << endl;
672 }
673 
test21()674 void test21() {
675     cout << "Running test 21...";
676     const char* txtFile = "this is some data";   // 17 Bytes
677     const char* txtFile2 = "this is some data!"; // 18 Bytes
678     int len = strlen(txtFile);
679     int len2 = strlen(txtFile2);
680 
681     ZipArchive z1("test.zip");
682     z1.open(ZipArchive::Write);
683     z1.addData("somedata", txtFile, len);
684     z1.addData("somedata2", txtFile2, len2);
685     z1.close();
686 
687     std::ifstream ifs("test.zip", std::ios::binary);
688     ifs.seekg(0, std::ifstream::end);
689     libzippp_uint32 bufferSize = (libzippp_uint32)ifs.tellg();
690     char* buffer = (char*)malloc(bufferSize);
691     ifs.seekg(std::ifstream::beg);
692     ifs.read(buffer, bufferSize);
693     ifs.close();
694 
695     z1.unlink();
696 
697     ZipArchive* z2 = ZipArchive::fromBuffer(buffer, bufferSize);
698     assert(z2->getNbEntries() == 2);
699     assert(z2->hasEntry("somedata"));
700     assert(z2->hasEntry("somedata2"));
701 
702     ZipEntry entry = z2->getEntry("somedata");
703     ZipEntry entry2 = z2->getEntry("somedata2");
704     assert(!entry.isNull());
705     assert(!entry2.isNull());
706 
707     z2->close();
708     delete z2;
709 
710     free(buffer);
711 
712     cout << " done." << endl;
713 }
714 
test22()715 void test22() {
716     cout << "Running test 22..." << endl;
717     const char* content1 = "This is some text that is a little bit longer, so I can test how the progression callback is invoked.";
718     const char* content2 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sed metus mollis, facilisis orci vitae, eleifend velit. Quisque et dolor vel nisl gravida vulputate. In iaculis viverra vehicula. Donec viverra euismod odio, sit amet tincidunt nisl aliquam sed. Integer lacinia augue vitae odio varius, at convallis diam molestie. Sed ac nisl at arcu convallis ultricies. Etiam eu metus interdum libero semper vulputate. Proin gravida malesuada justo vel ultrices. Etiam tellus ligula, maximus sed efficitur vitae, iaculis at turpis."
719                            "Aliquam eu finibus orci. Quisque maximus enim quis imperdiet vulputate. In vitae velit vel diam scelerisque sollicitudin ac et libero. Donec elit nisi, feugiat ut augue semper, cursus egestas libero. Nullam sed euismod ante. Integer gravida risus nulla, quis vestibulum lacus elementum a. Duis quis vulputate est. Ut elit ipsum, aliquet sit amet gravida et, porttitor quis metus. Vivamus vulputate sed ex ac vulputate. Donec venenatis auctor nulla, quis tempus lorem elementum vel. Suspendisse potenti. In sodales arcu enim, vitae imperdiet quam condimentum sagittis."
720                            "Fusce rutrum enim massa, eget ultricies nisi iaculis eu. Quisque erat metus, tempus at volutpat nec, interdum in ligula. Curabitur ullamcorper risus non lobortis vehicula. Proin leo sapien, congue vel metus quis, consectetur lacinia mi. Nunc suscipit erat ipsum, varius commodo risus finibus non. Nam viverra vulputate massa vel pulvinar. Quisque nec quam at lectus sagittis eleifend. Fusce vehicula lectus orci, eu rutrum risus finibus ac. Aenean sit amet mi in velit aliquet faucibus. Donec sit amet diam eget nisl rhoncus posuere eu sodales metus. Integer condimentum placerat neque vitae feugiat. Suspendisse metus velit, faucibus nec hendrerit cursus, pellentesque ut nibh. Duis accumsan mollis elit eget molestie. Donec sit amet congue nibh, quis iaculis lectus. Curabitur placerat sem ex, quis elementum leo sollicitudin sed. Etiam pulvinar turpis vitae ante consequat, vitae eleifend risus dapibus."
721                            "Fusce sollicitudin lorem consequat viverra blandit. Praesent feugiat eleifend nibh at eleifend. Etiam quis augue id tortor volutpat placerat. Curabitur id dolor aliquet, consequat eros nec, aliquet velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla ut nunc ex. Quisque finibus tincidunt sem, sit amet cursus enim hendrerit ut. Donec non interdum augue. Nunc vehicula viverra sem, at scelerisque sapien venenatis vel. Aliquam pretium, enim vel sodales condimentum, quam erat vehicula arcu, et tincidunt tortor justo aliquet lacus. Nulla dignissim pharetra nibh, at varius arcu tincidunt et. Vestibulum viverra velit tristique risus elementum, eu facilisis sapien sollicitudin. Nullam posuere imperdiet nibh sit amet malesuada. Cras ut dolor blandit, interdum lorem auctor, rhoncus dui. Sed mollis, mauris consequat malesuada pulvinar, dui elit pretium est, id euismod est quam in ex."
722                            "Ut euismod nisi in leo tempor fringilla. Praesent vel elit et dui facilisis sollicitudin sed non lacus. Etiam tempor ante a tortor pharetra sollicitudin. Nulla facilisi. Sed tincidunt justo urna, sed porttitor dolor aliquam ac. Duis id enim congue, consequat mauris eget, placerat elit. Maecenas eu leo quis tellus eleifend mattis. Suspendisse porttitor suscipit nunc non facilisis. Pellentesque mollis sapien nec purus consectetur interdum. Nunc efficitur neque rhoncus gravida vestibulum. Nullam at aliquet lorem.";
723     int len1 = strlen(content1);
724     int len2 = strlen(content2);
725 
726     ZipArchive z1("test.zip");
727     assert(z1.getProgressPrecision() == LIBZIPPP_DEFAULT_PROGRESSION_PRECISION);
728 
729     SimpleProgressListener spl;
730     z1.setProgressPrecision(0);
731     z1.addProgressListener(&spl);
732     assert(z1.getProgressListeners().size() == 1);
733 
734     z1.open(ZipArchive::Write);
735     z1.addData("somedata", content1, len1);
736     z1.addData("somedata2", content2, len2);
737     z1.addData("somedata3", content2, len2);
738     z1.addData("somedata4", content1, len1);
739     z1.addData("somedata5", content1, len1);
740     z1.addData("somedata6", content2, len2);
741     z1.close();
742 
743     assert(z1.getProgressListeners().size() == 1);
744     z1.removeProgressListener(&spl);
745     assert(z1.getProgressListeners().size() == 0);
746 
747     assert(spl.firstValue==0);
748     assert(spl.lastValue=1);
749 
750     z1.unlink();
751 
752     cout << "complete." << endl;
753 }
754 
test23()755 void test23() {
756     cout << "Running test 23...";
757     const char* txtFile = "this is some data";   // 17 Bytes
758     const char* txtFile2 = "this is some data!"; // 18 Bytes
759     int len = strlen(txtFile);
760     int len2 = strlen(txtFile2);
761 
762     char* buffer = new char[4096];
763     for(int i=0 ; i<4096; ++i) {
764         buffer[i] = '\0';
765     }
766 
767     ZipArchive* z1 = ZipArchive::fromBuffer(buffer, 4096, ZipArchive::New);
768     assert(z1!=nullptr);
769     z1->addData("somedata", txtFile, len);
770     z1->addData("somedata2", txtFile2, len2);
771     int rst = z1->close();
772     assert(rst==LIBZIPPP_OK);
773 
774     /*cout << endl;
775     cout << "Buffer data: " << endl;
776     for(int i=0 ; i<4096; ++i) {
777         char c = buffer[i];
778         if(c == '\0') { c = '0'; }
779 
780         cout << c;
781         if((i+1)%8==0) cout << " ";
782         if((i+1)%64==0) cout << endl;
783     }*/
784 
785     int newLength = z1->getBufferLength();
786     delete z1;
787 
788     ZipArchive* z2 = ZipArchive::fromBuffer(buffer, newLength, ZipArchive::ReadOnly, true);
789     assert(z2!=nullptr);
790     assert(z2->getNbEntries() == 2);
791     assert(z2->hasEntry("somedata"));
792     assert(z2->hasEntry("somedata2"));
793     delete z2;
794 
795     ZipArchive* z3 = new ZipArchive("within.zip");
796     z3->open(ZipArchive::New);
797     z3->addData("inside.zip", buffer, newLength);
798     z3->close();
799     z3->unlink();
800 
801     delete z3;
802 
803     delete[] buffer;
804 
805     cout << " done." << endl;
806 
807     /*char buffer[4096] = {};
808     for(int i=0 ; i<4096; ++i) {
809         buffer[i] = '\0';
810     }
811 
812     zip_error_t error;
813     zip_source_t *zs = zip_source_buffer_create(buffer, sizeof(buffer), 0, &error);
814     assert(zs!=nullptr);
815 
816     zip_source_keep(zs);
817 
818     zip_t * zip = zip_open_from_source(zs, ZIP_TRUNCATE, &error);
819     assert(zip!=nullptr);
820 
821     zip_add_dir(zip, "mydir");
822 
823     zip_close(zip);
824 
825     zip_source_open(zs);
826     zip_source_read(zs, buffer, sizeof(buffer));
827     zip_source_close(zs);
828 
829     cout << "Buffer data: " << endl;
830     for(int i=0 ; i<4096; ++i) {
831         char c = buffer[i];
832         cout << (int)c;
833         if((i+1)%8==0) cout << " ";
834         if((i+1)%64==0) cout << endl;
835     }*/
836 }
837 
main(int argc,char ** argv)838 int main(int argc, char** argv) {
839     test1();  test2();  test3();  test4();  test5();
840     test6();  test7();  test8();  test9();  test10();
841     test11(); test12(); test13(); test14(); test15();
842     test16(); test17(); test18(); test19(); test20();
843     test21(); test22(); test23();
844     return 0;
845 }
846 
847 
848