LMMS
Loading...
Searching...
No Matches
juce_ZipFile.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26inline uint16 readUnalignedLittleEndianShort (const void* buffer)
27{
28 auto data = readUnaligned<uint16> (buffer);
30}
31
32inline uint32 readUnalignedLittleEndianInt (const void* buffer)
33{
34 auto data = readUnaligned<uint32> (buffer);
36}
37
39{
40 ZipEntryHolder (const char* buffer, int fileNameLen)
41 {
43 entry.fileTime = parseFileTime (readUnalignedLittleEndianShort (buffer + 12),
44 readUnalignedLittleEndianShort (buffer + 14));
46 entry.uncompressedSize = (int64) readUnalignedLittleEndianInt (buffer + 24);
48
49 entry.externalFileAttributes = readUnalignedLittleEndianInt (buffer + 38);
50 auto fileType = (entry.externalFileAttributes >> 28) & 0xf;
51 entry.isSymbolicLink = (fileType == 0xA);
52
53 entry.filename = String::fromUTF8 (buffer + 46, fileNameLen);
54 }
55
56 static Time parseFileTime (uint32 time, uint32 date) noexcept
57 {
58 auto year = (int) (1980 + (date >> 9));
59 auto month = (int) (((date >> 5) & 15) - 1);
60 auto day = (int) (date & 31);
61 auto hours = (int) time >> 11;
62 auto minutes = (int) ((time >> 5) & 63);
63 auto seconds = (int) ((time & 31) << 1);
64
65 return { year, month, day, hours, minutes, seconds };
66 }
67
71};
72
73//==============================================================================
74static int64 findCentralDirectoryFileHeader (InputStream& input, int& numEntries)
75{
76 BufferedInputStream in (input, 8192);
77
78 in.setPosition (in.getTotalLength());
79 auto pos = in.getPosition();
80 auto lowestPos = jmax ((int64) 0, pos - 1048576);
81 char buffer[32] = {};
82
83 while (pos > lowestPos)
84 {
85 in.setPosition (pos - 22);
86 pos = in.getPosition();
87 memcpy (buffer + 22, buffer, 4);
88
89 if (in.read (buffer, 22) != 22)
90 return 0;
91
92 for (int i = 0; i < 22; ++i)
93 {
94 if (readUnalignedLittleEndianInt (buffer + i) == 0x06054b50)
95 {
96 in.setPosition (pos + i);
97 in.read (buffer, 22);
98 numEntries = readUnalignedLittleEndianShort (buffer + 10);
99 auto offset = (int64) readUnalignedLittleEndianInt (buffer + 16);
100
101 if (offset >= 4)
102 {
103 in.setPosition (offset);
104
105 // This is a workaround for some zip files which seem to contain the
106 // wrong offset for the central directory - instead of including the
107 // header, they point to the byte immediately after it.
108 if (in.readInt() != 0x02014b50)
109 {
110 in.setPosition (offset - 4);
111
112 if (in.readInt() == 0x02014b50)
113 offset -= 4;
114 }
115 }
116
117 return offset;
118 }
119 }
120 }
121
122 return 0;
123}
124
125static bool hasSymbolicPart (const File& root, const File& f)
126{
127 jassert (root == f || f.isAChildOf (root));
128
129 for (auto p = f; p != root; p = p.getParentDirectory())
130 {
131 if (p.isSymbolicLink())
132 return true;
133 }
134
135 return false;
136}
137
138//==============================================================================
140{
142 : file (zf),
143 zipEntryHolder (zei),
145 {
146 if (zf.inputSource != nullptr)
147 {
148 streamToDelete.reset (file.inputSource->createInputStream());
149 inputStream = streamToDelete.get();
150 }
151 else
152 {
153 #if JUCE_DEBUG
154 zf.streamCounter.numOpenStreams++;
155 #endif
156 }
157
158 char buffer[30];
159
160 if (inputStream != nullptr
161 && inputStream->setPosition (zei.streamOffset)
162 && inputStream->read (buffer, 30) == 30
163 && ByteOrder::littleEndianInt (buffer) == 0x04034b50)
164 {
165 headerSize = 30 + ByteOrder::littleEndianShort (buffer + 26)
166 + ByteOrder::littleEndianShort (buffer + 28);
167 }
168 }
169
171 {
172 #if JUCE_DEBUG
173 if (inputStream != nullptr && inputStream == file.inputStream)
174 file.streamCounter.numOpenStreams--;
175 #endif
176 }
177
179 {
180 return zipEntryHolder.compressedSize;
181 }
182
183 int read (void* buffer, int howMany) override
184 {
185 if (headerSize <= 0)
186 return 0;
187
188 howMany = (int) jmin ((int64) howMany, zipEntryHolder.compressedSize - pos);
189
190 if (inputStream == nullptr)
191 return 0;
192
193 int num;
194
195 if (inputStream == file.inputStream)
196 {
197 const ScopedLock sl (file.lock);
198 inputStream->setPosition (pos + zipEntryHolder.streamOffset + headerSize);
199 num = inputStream->read (buffer, howMany);
200 }
201 else
202 {
203 inputStream->setPosition (pos + zipEntryHolder.streamOffset + headerSize);
204 num = inputStream->read (buffer, howMany);
205 }
206
207 pos += num;
208 return num;
209 }
210
211 bool isExhausted() override
212 {
213 return headerSize <= 0 || pos >= zipEntryHolder.compressedSize;
214 }
215
217 {
218 return pos;
219 }
220
221 bool setPosition (int64 newPos) override
222 {
223 pos = jlimit ((int64) 0, zipEntryHolder.compressedSize, newPos);
224 return true;
225 }
226
227private:
231 int headerSize = 0;
233 std::unique_ptr<InputStream> streamToDelete;
234
236};
237
238
239//==============================================================================
240ZipFile::ZipFile (InputStream* stream, bool deleteStreamWhenDestroyed)
241 : inputStream (stream)
242{
243 if (deleteStreamWhenDestroyed)
245
246 init();
247}
248
250{
251 init();
252}
253
255{
256 init();
257}
258
260{
261 init();
262}
263
265{
266 entries.clear();
267}
268
269#if JUCE_DEBUG
270ZipFile::OpenStreamCounter::~OpenStreamCounter()
271{
272 /* If you hit this assertion, it means you've created a stream to read one of the items in the
273 zipfile, but you've forgotten to delete that stream object before deleting the file..
274 Streams can't be kept open after the file is deleted because they need to share the input
275 stream that is managed by the ZipFile object.
276 */
277 jassert (numOpenStreams == 0);
278}
279#endif
280
281//==============================================================================
283{
284 return entries.size();
285}
286
287const ZipFile::ZipEntry* ZipFile::getEntry (const int index) const noexcept
288{
289 if (auto* zei = entries[index])
290 return &(zei->entry);
291
292 return nullptr;
293}
294
295int ZipFile::getIndexOfFileName (const String& fileName, bool ignoreCase) const noexcept
296{
297 for (int i = 0; i < entries.size(); ++i)
298 {
299 auto& entryFilename = entries.getUnchecked (i)->entry.filename;
300
301 if (ignoreCase ? entryFilename.equalsIgnoreCase (fileName)
302 : entryFilename == fileName)
303 return i;
304 }
305
306 return -1;
307}
308
309const ZipFile::ZipEntry* ZipFile::getEntry (const String& fileName, bool ignoreCase) const noexcept
310{
311 return getEntry (getIndexOfFileName (fileName, ignoreCase));
312}
313
315{
316 InputStream* stream = nullptr;
317
318 if (auto* zei = entries[index])
319 {
320 stream = new ZipInputStream (*this, *zei);
321
322 if (zei->isCompressed)
323 {
324 stream = new GZIPDecompressorInputStream (stream, true,
326 zei->entry.uncompressedSize);
327
328 // (much faster to unzip in big blocks using a buffer..)
329 stream = new BufferedInputStream (stream, 32768, true);
330 }
331 }
332
333 return stream;
334}
335
337{
338 for (int i = 0; i < entries.size(); ++i)
339 if (&entries.getUnchecked (i)->entry == &entry)
340 return createStreamForEntry (i);
341
342 return nullptr;
343}
344
346{
347 std::sort (entries.begin(), entries.end(),
348 [] (const ZipEntryHolder* e1, const ZipEntryHolder* e2) { return e1->entry.filename < e2->entry.filename; });
349}
350
351//==============================================================================
353{
354 std::unique_ptr<InputStream> toDelete;
356
357 if (inputSource != nullptr)
358 {
359 in = inputSource->createInputStream();
360 toDelete.reset (in);
361 }
362
363 if (in != nullptr)
364 {
365 int numEntries = 0;
366 auto centralDirectoryPos = findCentralDirectoryFileHeader (*in, numEntries);
367
368 if (centralDirectoryPos >= 0 && centralDirectoryPos < in->getTotalLength())
369 {
370 auto size = (size_t) (in->getTotalLength() - centralDirectoryPos);
371
372 in->setPosition (centralDirectoryPos);
373 MemoryBlock headerData;
374
375 if (in->readIntoMemoryBlock (headerData, (ssize_t) size) == size)
376 {
377 size_t pos = 0;
378
379 for (int i = 0; i < numEntries; ++i)
380 {
381 if (pos + 46 > size)
382 break;
383
384 auto* buffer = static_cast<const char*> (headerData.getData()) + pos;
385 auto fileNameLen = readUnalignedLittleEndianShort (buffer + 28u);
386
387 if (pos + 46 + fileNameLen > size)
388 break;
389
390 entries.add (new ZipEntryHolder (buffer, fileNameLen));
391
392 pos += 46u + fileNameLen
393 + readUnalignedLittleEndianShort (buffer + 30u)
394 + readUnalignedLittleEndianShort (buffer + 32u);
395 }
396 }
397 }
398 }
399}
400
401Result ZipFile::uncompressTo (const File& targetDirectory,
402 const bool shouldOverwriteFiles)
403{
404 for (int i = 0; i < entries.size(); ++i)
405 {
406 auto result = uncompressEntry (i, targetDirectory, shouldOverwriteFiles);
407
408 if (result.failed())
409 return result;
410 }
411
412 return Result::ok();
413}
414
415Result ZipFile::uncompressEntry (int index, const File& targetDirectory, bool shouldOverwriteFiles)
416{
417 return uncompressEntry (index,
418 targetDirectory,
419 shouldOverwriteFiles ? OverwriteFiles::yes : OverwriteFiles::no,
421}
422
423Result ZipFile::uncompressEntry (int index, const File& targetDirectory, OverwriteFiles overwriteFiles, FollowSymlinks followSymlinks)
424{
425 auto* zei = entries.getUnchecked (index);
426
427 #if JUCE_WINDOWS
428 auto entryPath = zei->entry.filename;
429 #else
430 auto entryPath = zei->entry.filename.replaceCharacter ('\\', '/');
431 #endif
432
433 if (entryPath.isEmpty())
434 return Result::ok();
435
436 auto targetFile = targetDirectory.getChildFile (entryPath);
437
438 if (! targetFile.isAChildOf (targetDirectory))
439 return Result::fail ("Entry " + entryPath + " is outside the target directory");
440
441 if (entryPath.endsWithChar ('/') || entryPath.endsWithChar ('\\'))
442 return targetFile.createDirectory(); // (entry is a directory, not a file)
443
444 std::unique_ptr<InputStream> in (createStreamForEntry (index));
445
446 if (in == nullptr)
447 return Result::fail ("Failed to open the zip file for reading");
448
449 if (targetFile.exists())
450 {
451 if (overwriteFiles == OverwriteFiles::no)
452 return Result::ok();
453
454 if (! targetFile.deleteFile())
455 return Result::fail ("Failed to write to target file: " + targetFile.getFullPathName());
456 }
457
458 if (followSymlinks == FollowSymlinks::no && hasSymbolicPart (targetDirectory, targetFile.getParentDirectory()))
459 return Result::fail ("Parent directory leads through symlink for target file: " + targetFile.getFullPathName());
460
461 if (! targetFile.getParentDirectory().createDirectory())
462 return Result::fail ("Failed to create target folder: " + targetFile.getParentDirectory().getFullPathName());
463
464 if (zei->entry.isSymbolicLink)
465 {
466 String originalFilePath (in->readEntireStreamAsString()
467 .replaceCharacter (L'/', File::getSeparatorChar()));
468
469 if (! File::createSymbolicLink (targetFile, originalFilePath, true))
470 return Result::fail ("Failed to create symbolic link: " + originalFilePath);
471 }
472 else
473 {
474 FileOutputStream out (targetFile);
475
476 if (out.failedToOpen())
477 return Result::fail ("Failed to write to target file: " + targetFile.getFullPathName());
478
479 out << *in;
480 }
481
482 targetFile.setCreationTime (zei->entry.fileTime);
483 targetFile.setLastModificationTime (zei->entry.fileTime);
484 targetFile.setLastAccessTime (zei->entry.fileTime);
485
486 return Result::ok();
487}
488
489
490//==============================================================================
492{
493 Item (const File& f, InputStream* s, int compression, const String& storedPath, Time time)
494 : file (f), stream (s), storedPathname (storedPath), fileTime (time), compressionLevel (compression)
495 {
496 symbolicLink = (file.exists() && file.isSymbolicLink());
497 }
498
499 bool writeData (OutputStream& target, const int64 overallStartPosition)
500 {
501 MemoryOutputStream compressedData ((size_t) file.getSize());
502
503 if (symbolicLink)
504 {
505 auto relativePath = file.getNativeLinkedTarget().replaceCharacter (File::getSeparatorChar(), L'/');
506
507 uncompressedSize = relativePath.length();
508
509 checksum = zlibNamespace::crc32 (0, (uint8_t*) relativePath.toRawUTF8(), (unsigned int) uncompressedSize);
510 compressedData << relativePath;
511 }
512 else if (compressionLevel > 0)
513 {
514 GZIPCompressorOutputStream compressor (compressedData, compressionLevel,
516 if (! writeSource (compressor))
517 return false;
518 }
519 else
520 {
521 if (! writeSource (compressedData))
522 return false;
523 }
524
525 compressedSize = (int64) compressedData.getDataSize();
526 headerStart = target.getPosition() - overallStartPosition;
527
528 target.writeInt (0x04034b50);
529 writeFlagsAndSizes (target);
530 target << storedPathname
531 << compressedData;
532
533 return true;
534 }
535
537 {
538 target.writeInt (0x02014b50);
539 target.writeShort (symbolicLink ? 0x0314 : 0x0014);
540 writeFlagsAndSizes (target);
541 target.writeShort (0); // comment length
542 target.writeShort (0); // start disk num
543 target.writeShort (0); // internal attributes
544 target.writeInt ((int) (symbolicLink ? 0xA1ED0000 : 0)); // external attributes
545 target.writeInt ((int) (uint32) headerStart);
546 target << storedPathname;
547
548 return true;
549 }
550
551private:
552 const File file;
553 std::unique_ptr<InputStream> stream;
558 unsigned long checksum = 0;
559 bool symbolicLink = false;
560
561 static void writeTimeAndDate (OutputStream& target, Time t)
562 {
563 target.writeShort ((short) (t.getSeconds() + (t.getMinutes() << 5) + (t.getHours() << 11)));
564 target.writeShort ((short) (t.getDayOfMonth() + ((t.getMonth() + 1) << 5) + ((t.getYear() - 1980) << 9)));
565 }
566
568 {
569 if (stream == nullptr)
570 {
571 stream = file.createInputStream();
572
573 if (stream == nullptr)
574 return false;
575 }
576
577 checksum = 0;
579 const int bufferSize = 4096;
580 HeapBlock<unsigned char> buffer (bufferSize);
581
582 while (! stream->isExhausted())
583 {
584 auto bytesRead = stream->read (buffer, bufferSize);
585
586 if (bytesRead < 0)
587 return false;
588
589 checksum = zlibNamespace::crc32 (checksum, buffer, (unsigned int) bytesRead);
590 target.write (buffer, (size_t) bytesRead);
591 uncompressedSize += bytesRead;
592 }
593
594 stream.reset();
595 return true;
596 }
597
598 void writeFlagsAndSizes (OutputStream& target) const
599 {
600 target.writeShort (10); // version needed
601 target.writeShort ((short) (1 << 11)); // this flag indicates UTF-8 filename encoding
602 target.writeShort ((! symbolicLink && compressionLevel > 0) ? (short) 8 : (short) 0); //symlink target path is not compressed
603 writeTimeAndDate (target, fileTime);
604 target.writeInt ((int) checksum);
605 target.writeInt ((int) (uint32) compressedSize);
606 target.writeInt ((int) (uint32) uncompressedSize);
607 target.writeShort (static_cast<short> (storedPathname.toUTF8().sizeInBytes() - 1));
608 target.writeShort (0); // extra field length
609 }
610
612};
613
614//==============================================================================
617
618void ZipFile::Builder::addFile (const File& file, int compression, const String& path)
619{
620 items.add (new Item (file, nullptr, compression,
621 path.isEmpty() ? file.getFileName() : path,
622 file.getLastModificationTime()));
623}
624
625void ZipFile::Builder::addEntry (InputStream* stream, int compression, const String& path, Time time)
626{
627 jassert (stream != nullptr); // must not be null!
628 jassert (path.isNotEmpty());
629 items.add (new Item ({}, stream, compression, path, time));
630}
631
632bool ZipFile::Builder::writeToStream (OutputStream& target, double* const progress) const
633{
634 auto fileStart = target.getPosition();
635
636 for (int i = 0; i < items.size(); ++i)
637 {
638 if (progress != nullptr)
639 *progress = (i + 0.5) / items.size();
640
641 if (! items.getUnchecked (i)->writeData (target, fileStart))
642 return false;
643 }
644
645 auto directoryStart = target.getPosition();
646
647 for (auto* item : items)
648 if (! item->writeDirectoryEntry (target))
649 return false;
650
651 auto directoryEnd = target.getPosition();
652
653 target.writeInt (0x06054b50);
654 target.writeShort (0);
655 target.writeShort (0);
656 target.writeShort ((short) items.size());
657 target.writeShort ((short) items.size());
658 target.writeInt ((int) (directoryEnd - directoryStart));
659 target.writeInt ((int) (directoryStart - fileStart));
660 target.writeShort (0);
661
662 if (progress != nullptr)
663 *progress = 1.0;
664
665 return true;
666}
667
668
669//==============================================================================
670//==============================================================================
671#if JUCE_UNIT_TESTS
672
673struct ZIPTests : public UnitTest
674{
675 ZIPTests()
676 : UnitTest ("ZIP", UnitTestCategories::compression)
677 {}
678
679 static MemoryBlock createZipMemoryBlock (const StringArray& entryNames)
680 {
681 ZipFile::Builder builder;
683
684 for (auto& entryName : entryNames)
685 {
686 auto& block = blocks.getReference (entryName);
687 MemoryOutputStream mo (block, false);
688 mo << entryName;
689 mo.flush();
690 builder.addEntry (new MemoryInputStream (block, false), 9, entryName, Time::getCurrentTime());
691 }
692
694 MemoryOutputStream mo (data, false);
695 builder.writeToStream (mo, nullptr);
696
697 return data;
698 }
699
700 void runZipSlipTest()
701 {
702 const std::map<String, bool> testCases = { { "a", true },
703#if JUCE_WINDOWS
704 { "C:/b", false },
705#else
706 { "/b", false },
707#endif
708 { "c/d", true },
709 { "../e/f", false },
710 { "../../g/h", false },
711 { "i/../j", true },
712 { "k/l/../", true },
713 { "m/n/../../", false },
714 { "o/p/../../../", false } };
715
716 StringArray entryNames;
717
718 for (const auto& testCase : testCases)
719 entryNames.add (testCase.first);
720
721 TemporaryFile tmpDir;
722 tmpDir.getFile().createDirectory();
723 auto data = createZipMemoryBlock (entryNames);
724 MemoryInputStream mi (data, false);
725 ZipFile zip (mi);
726
727 for (int i = 0; i < zip.getNumEntries(); ++i)
728 {
729 const auto result = zip.uncompressEntry (i, tmpDir.getFile());
730 const auto caseIt = testCases.find (zip.getEntry (i)->filename);
731
732 if (caseIt != testCases.end())
733 {
734 expect (result.wasOk() == caseIt->second,
735 zip.getEntry (i)->filename + " was unexpectedly " + (result.wasOk() ? "OK" : "not OK"));
736 }
737 else
738 {
739 expect (false);
740 }
741 }
742 }
743
744 void runTest() override
745 {
746 beginTest ("ZIP");
747
748 StringArray entryNames { "first", "second", "third" };
749 auto data = createZipMemoryBlock (entryNames);
750 MemoryInputStream mi (data, false);
751 ZipFile zip (mi);
752
753 expectEquals (zip.getNumEntries(), entryNames.size());
754
755 for (auto& entryName : entryNames)
756 {
757 auto* entry = zip.getEntry (entryName);
758 std::unique_ptr<InputStream> input (zip.createStreamForEntry (*entry));
759 expectEquals (input->readEntireStreamAsString(), entryName);
760 }
761
762 beginTest ("ZipSlip");
763 runZipSlipTest();
764 }
765};
766
767static ZIPTests zipTests;
768
769#endif
770
771} // namespace juce
Type jmax(const Type a, const Type b)
Definition MathsFunctions.h:48
#define noexcept
Definition DistrhoDefines.h:72
static uint32 littleEndianInt(const void *bytes) noexcept
Definition ByteOrder.h:236
static uint16 littleEndianShort(const void *bytes) noexcept
Definition ByteOrder.h:238
Definition MemoryBlock.h:39
Definition MemoryOutputStream.h:42
static Result ok() noexcept
Definition Result.h:68
static Result fail(const std::string &errorMessage) noexcept
Definition Result.cpp:58
bool add(const String &stringToAdd)
Definition StringArray.cpp:108
int size() const noexcept
Definition StringArray.h:97
static String fromUTF8(const char *utf8buffer, int bufferSizeBytes=-1)
Definition String.cpp:1961
Definition juce_BufferedInputStream.h:37
static constexpr uint32 littleEndianInt(const void *bytes) noexcept
Definition juce_ByteOrder.h:203
Definition juce_File.h:45
File getChildFile(StringRef relativeOrAbsolutePath) const
Definition juce_File.cpp:412
bool createSymbolicLink(const File &linkFileToCreate, bool overwriteExisting) const
Definition juce_File.cpp:995
File getParentDirectory() const
Definition juce_File.cpp:358
static juce_wchar getSeparatorChar()
Definition juce_posix_SharedCode.h:113
Definition juce_FileInputSource.h:35
Definition juce_FileOutputStream.h:35
Definition juce_GZIPCompressorOutputStream.h:39
@ windowBitsRaw
Definition juce_GZIPCompressorOutputStream.h:94
Definition juce_GZIPDecompressorInputStream.h:39
@ deflateFormat
Definition juce_GZIPDecompressorInputStream.h:44
Definition juce_HashMap.h:104
ValueType & getReference(KeyTypeParameter keyToLookFor)
Definition juce_HashMap.h:185
Definition juce_HeapBlock.h:87
Definition juce_InputSource.h:38
Definition juce_InputStream.h:37
InputStream()=default
Definition juce_MemoryBlock.h:33
void * getData() noexcept
Definition juce_MemoryBlock.h:91
Definition juce_MemoryInputStream.h:36
Definition juce_MemoryOutputStream.h:36
size_t getDataSize() const noexcept
Definition juce_MemoryOutputStream.h:80
Definition juce_OutputStream.h:38
virtual bool write(const void *dataToWrite, size_t numberOfBytes)=0
virtual int64 getPosition()=0
virtual bool writeShort(short value)
Definition juce_OutputStream.cpp:97
virtual bool writeInt(int value)
Definition juce_OutputStream.cpp:109
Definition juce_Result.h:57
Definition juce_StringArray.h:35
Definition juce_String.h:53
bool isEmpty() const noexcept
Definition juce_String.h:310
bool isNotEmpty() const noexcept
Definition juce_String.h:316
Definition juce_Time.h:37
static Time JUCE_CALLTYPE getCurrentTime() noexcept
Definition juce_Time.cpp:233
Definition juce_UnitTest.h:70
Definition juce_ZipFile.h:209
Builder()
Definition juce_ZipFile.cpp:615
void addEntry(InputStream *streamToRead, int compressionLevel, const String &storedPathName, Time fileModificationTime)
Definition juce_ZipFile.cpp:625
bool writeToStream(OutputStream &target, double *progress) const
Definition juce_ZipFile.cpp:632
void addFile(const File &fileToAdd, int compressionLevel, const String &storedPathName=String())
Definition juce_ZipFile.cpp:618
OwnedArray< Item > items
Definition juce_ZipFile.h:252
~Builder()
Definition juce_ZipFile.cpp:616
Result uncompressTo(const File &targetDirectory, bool shouldOverwriteFiles=true)
Definition juce_ZipFile.cpp:401
InputStream * createStreamForEntry(int index)
Definition juce_ZipFile.cpp:314
const ZipEntry * getEntry(int index) const noexcept
Definition juce_ZipFile.cpp:287
~ZipFile()
Definition juce_ZipFile.cpp:264
int getNumEntries() const noexcept
Definition juce_ZipFile.cpp:282
std::unique_ptr< InputSource > inputSource
Definition juce_ZipFile.h:266
InputStream * inputStream
Definition juce_ZipFile.h:264
OwnedArray< ZipEntryHolder > entries
Definition juce_ZipFile.h:262
void init()
Definition juce_ZipFile.cpp:352
ZipFile(const File &file)
Definition juce_ZipFile.cpp:254
OverwriteFiles
Definition juce_ZipFile.h:182
@ no
Definition juce_ZipFile.h:182
@ yes
Definition juce_ZipFile.h:182
Result uncompressEntry(int index, const File &targetDirectory, bool shouldOverwriteFiles=true)
Definition juce_ZipFile.cpp:415
int getIndexOfFileName(const String &fileName, bool ignoreCase=false) const noexcept
Definition juce_ZipFile.cpp:295
void sortEntriesByFilename()
Definition juce_ZipFile.cpp:345
std::unique_ptr< InputStream > streamToDelete
Definition juce_ZipFile.h:265
FollowSymlinks
Definition juce_ZipFile.h:183
@ no
Definition juce_ZipFile.h:183
struct huft * t
Definition inflate.c:943
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
unsigned f
Definition inflate.c:1572
JSAMPIMAGE data
Definition jpeglib.h:945
#define jassert(expression)
#define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className)
float in
Definition lilv_test.c:1460
float out
Definition lilv_test.c:1461
unsigned char uint8_t
Definition mid.cpp:98
Definition juce_UnitTestCategories.h:27
Definition carla_juce.cpp:31
static int64 findCentralDirectoryFileHeader(InputStream &input, int &numEntries)
Definition juce_ZipFile.cpp:74
CriticalSection::ScopedLockType ScopedLock
Definition juce_CriticalSection.h:186
unsigned short uint16
Definition juce_MathsFunctions.h:41
constexpr Type jmin(Type a, Type b)
Definition juce_MathsFunctions.h:106
unsigned int uint32
Definition juce_MathsFunctions.h:45
uint32 readUnalignedLittleEndianInt(const void *buffer)
Definition juce_ZipFile.cpp:32
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Definition juce_MathsFunctions.h:262
static bool hasSymbolicPart(const File &root, const File &f)
Definition juce_ZipFile.cpp:125
long long int64
Definition juce_MathsFunctions.h:54
Type readUnaligned(const void *srcPtr) noexcept
Definition juce_Memory.h:65
uint16 readUnalignedLittleEndianShort(const void *buffer)
Definition juce_ZipFile.cpp:26
Definition juce_ZipFile.cpp:492
bool writeDirectoryEntry(OutputStream &target)
Definition juce_ZipFile.cpp:536
int64 uncompressedSize
Definition juce_ZipFile.cpp:556
int compressionLevel
Definition juce_ZipFile.cpp:557
Item(const File &f, InputStream *s, int compression, const String &storedPath, Time time)
Definition juce_ZipFile.cpp:493
bool symbolicLink
Definition juce_ZipFile.cpp:559
std::unique_ptr< InputStream > stream
Definition juce_ZipFile.cpp:553
void writeFlagsAndSizes(OutputStream &target) const
Definition juce_ZipFile.cpp:598
Time fileTime
Definition juce_ZipFile.cpp:555
int64 headerStart
Definition juce_ZipFile.cpp:556
String storedPathname
Definition juce_ZipFile.cpp:554
static void writeTimeAndDate(OutputStream &target, Time t)
Definition juce_ZipFile.cpp:561
const File file
Definition juce_ZipFile.cpp:552
unsigned long checksum
Definition juce_ZipFile.cpp:558
bool writeSource(OutputStream &target)
Definition juce_ZipFile.cpp:567
int64 compressedSize
Definition juce_ZipFile.cpp:556
bool writeData(OutputStream &target, const int64 overallStartPosition)
Definition juce_ZipFile.cpp:499
Definition juce_ZipFile.cpp:39
static Time parseFileTime(uint32 time, uint32 date) noexcept
Definition juce_ZipFile.cpp:56
bool isCompressed
Definition juce_ZipFile.cpp:70
int64 streamOffset
Definition juce_ZipFile.cpp:69
ZipEntryHolder(const char *buffer, int fileNameLen)
Definition juce_ZipFile.cpp:40
int64 compressedSize
Definition juce_ZipFile.cpp:69
ZipEntry entry
Definition juce_ZipFile.cpp:68
Definition juce_ZipFile.h:73
Definition juce_ZipFile.cpp:140
int read(void *buffer, int howMany) override
Definition juce_ZipFile.cpp:183
ZipInputStream(ZipFile &zf, const ZipFile::ZipEntryHolder &zei)
Definition juce_ZipFile.cpp:141
~ZipInputStream() override
Definition juce_ZipFile.cpp:170
ZipEntryHolder zipEntryHolder
Definition juce_ZipFile.cpp:229
ZipFile & file
Definition juce_ZipFile.cpp:228
bool isExhausted() override
Definition juce_ZipFile.cpp:211
bool setPosition(int64 newPos) override
Definition juce_ZipFile.cpp:221
InputStream * inputStream
Definition juce_ZipFile.cpp:232
int64 pos
Definition juce_ZipFile.cpp:230
std::unique_ptr< InputStream > streamToDelete
Definition juce_ZipFile.cpp:233
int64 getTotalLength() override
Definition juce_ZipFile.cpp:178
int headerSize
Definition juce_ZipFile.cpp:231
int64 getPosition() override
Definition juce_ZipFile.cpp:216
uch * p
Definition crypt.c:594
memcpy(hh, h, RAND_HEAD_LEN)
if(GLOBAL(newzip))
Definition crypt.c:475
ZCONST uch * init
Definition extract.c:2392
ulg size
Definition extract.c:2350
int result
Definition process.c:1455
typedef int(UZ_EXP MsgFn)()
struct zdirent * file
Definition win32.c:1500
mo
Definition zipinfo.c:2287
static ZCONST char Far month[12][4]
Definition zipinfo.c:2243
#define const
Definition zconf.h:137