OpenShot Library | libopenshot-audio  0.2.0
juce_ZipFile.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
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 
23 namespace juce
24 {
25 
26 inline uint16 readUnalignedLittleEndianShort (const void* buffer)
27 {
28  auto data = readUnaligned<uint16> (buffer);
29  return ByteOrder::littleEndianShort (&data);
30 }
31 
32 inline uint32 readUnalignedLittleEndianInt (const void* buffer)
33 {
34  auto data = readUnaligned<uint32> (buffer);
35  return ByteOrder::littleEndianInt (&data);
36 }
37 
39 {
40  ZipEntryHolder (const char* buffer, int fileNameLen)
41  {
42  isCompressed = readUnalignedLittleEndianShort (buffer + 10) != 0;
43  entry.fileTime = parseFileTime (readUnalignedLittleEndianShort (buffer + 12),
44  readUnalignedLittleEndianShort (buffer + 14));
45  compressedSize = (int64) readUnalignedLittleEndianInt (buffer + 20);
46  entry.uncompressedSize = (int64) readUnalignedLittleEndianInt (buffer + 24);
47  streamOffset = (int64) readUnalignedLittleEndianInt (buffer + 42);
48 
49  auto externalFileAttributes = (int32) readUnalignedLittleEndianInt (buffer + 38);
50  auto fileType = (externalFileAttributes >> 28) & 0xf;
51 
52  entry.isSymbolicLink = (fileType == 0xA);
53  entry.filename = String::fromUTF8 (buffer + 46, fileNameLen);
54  }
55 
56  static Time parseFileTime (uint32 time, uint32 date) noexcept
57  {
58  int year = 1980 + (date >> 9);
59  int month = ((date >> 5) & 15) - 1;
60  int day = date & 31;
61  int hours = time >> 11;
62  int minutes = (time >> 5) & 63;
63  int seconds = (int) ((time & 31) << 1);
64 
65  return { year, month, day, hours, minutes, seconds };
66  }
67 
68  ZipEntry entry;
69  int64 streamOffset, compressedSize;
70  bool isCompressed;
71 };
72 
73 //==============================================================================
74 static 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 
125 //==============================================================================
127 {
129  : file (zf),
130  zipEntryHolder (zei),
131  inputStream (zf.inputStream)
132  {
133  if (zf.inputSource != nullptr)
134  {
135  streamToDelete.reset (file.inputSource->createInputStream());
136  inputStream = streamToDelete.get();
137  }
138  else
139  {
140  #if JUCE_DEBUG
141  zf.streamCounter.numOpenStreams++;
142  #endif
143  }
144 
145  char buffer[30];
146 
147  if (inputStream != nullptr
148  && inputStream->setPosition (zei.streamOffset)
149  && inputStream->read (buffer, 30) == 30
150  && ByteOrder::littleEndianInt (buffer) == 0x04034b50)
151  {
152  headerSize = 30 + ByteOrder::littleEndianShort (buffer + 26)
153  + ByteOrder::littleEndianShort (buffer + 28);
154  }
155  }
156 
157  ~ZipInputStream() override
158  {
159  #if JUCE_DEBUG
160  if (inputStream != nullptr && inputStream == file.inputStream)
161  file.streamCounter.numOpenStreams--;
162  #endif
163  }
164 
165  int64 getTotalLength() override
166  {
167  return zipEntryHolder.compressedSize;
168  }
169 
170  int read (void* buffer, int howMany) override
171  {
172  if (headerSize <= 0)
173  return 0;
174 
175  howMany = (int) jmin ((int64) howMany, zipEntryHolder.compressedSize - pos);
176 
177  if (inputStream == nullptr)
178  return 0;
179 
180  int num;
181 
182  if (inputStream == file.inputStream)
183  {
184  const ScopedLock sl (file.lock);
185  inputStream->setPosition (pos + zipEntryHolder.streamOffset + headerSize);
186  num = inputStream->read (buffer, howMany);
187  }
188  else
189  {
190  inputStream->setPosition (pos + zipEntryHolder.streamOffset + headerSize);
191  num = inputStream->read (buffer, howMany);
192  }
193 
194  pos += num;
195  return num;
196  }
197 
198  bool isExhausted() override
199  {
200  return headerSize <= 0 || pos >= zipEntryHolder.compressedSize;
201  }
202 
203  int64 getPosition() override
204  {
205  return pos;
206  }
207 
208  bool setPosition (int64 newPos) override
209  {
210  pos = jlimit ((int64) 0, zipEntryHolder.compressedSize, newPos);
211  return true;
212  }
213 
214 private:
215  ZipFile& file;
216  ZipEntryHolder zipEntryHolder;
217  int64 pos = 0;
218  int headerSize = 0;
219  InputStream* inputStream;
220  std::unique_ptr<InputStream> streamToDelete;
221 
222  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ZipInputStream)
223 };
224 
225 
226 //==============================================================================
227 ZipFile::ZipFile (InputStream* stream, bool deleteStreamWhenDestroyed)
228  : inputStream (stream)
229 {
230  if (deleteStreamWhenDestroyed)
231  streamToDelete.reset (inputStream);
232 
233  init();
234 }
235 
236 ZipFile::ZipFile (InputStream& stream) : inputStream (&stream)
237 {
238  init();
239 }
240 
241 ZipFile::ZipFile (const File& file) : inputSource (new FileInputSource (file))
242 {
243  init();
244 }
245 
246 ZipFile::ZipFile (InputSource* source) : inputSource (source)
247 {
248  init();
249 }
250 
252 {
253  entries.clear();
254 }
255 
256 #if JUCE_DEBUG
257 ZipFile::OpenStreamCounter::~OpenStreamCounter()
258 {
259  /* If you hit this assertion, it means you've created a stream to read one of the items in the
260  zipfile, but you've forgotten to delete that stream object before deleting the file..
261  Streams can't be kept open after the file is deleted because they need to share the input
262  stream that is managed by the ZipFile object.
263  */
264  jassert (numOpenStreams == 0);
265 }
266 #endif
267 
268 //==============================================================================
269 int ZipFile::getNumEntries() const noexcept
270 {
271  return entries.size();
272 }
273 
274 const ZipFile::ZipEntry* ZipFile::getEntry (const int index) const noexcept
275 {
276  if (auto* zei = entries[index])
277  return &(zei->entry);
278 
279  return nullptr;
280 }
281 
282 int ZipFile::getIndexOfFileName (const String& fileName, bool ignoreCase) const noexcept
283 {
284  for (int i = 0; i < entries.size(); ++i)
285  {
286  auto& entryFilename = entries.getUnchecked (i)->entry.filename;
287 
288  if (ignoreCase ? entryFilename.equalsIgnoreCase (fileName)
289  : entryFilename == fileName)
290  return i;
291  }
292 
293  return -1;
294 }
295 
296 const ZipFile::ZipEntry* ZipFile::getEntry (const String& fileName, bool ignoreCase) const noexcept
297 {
298  return getEntry (getIndexOfFileName (fileName, ignoreCase));
299 }
300 
302 {
303  InputStream* stream = nullptr;
304 
305  if (auto* zei = entries[index])
306  {
307  stream = new ZipInputStream (*this, *zei);
308 
309  if (zei->isCompressed)
310  {
311  stream = new GZIPDecompressorInputStream (stream, true,
312  GZIPDecompressorInputStream::deflateFormat,
313  zei->entry.uncompressedSize);
314 
315  // (much faster to unzip in big blocks using a buffer..)
316  stream = new BufferedInputStream (stream, 32768, true);
317  }
318  }
319 
320  return stream;
321 }
322 
324 {
325  for (int i = 0; i < entries.size(); ++i)
326  if (&entries.getUnchecked (i)->entry == &entry)
327  return createStreamForEntry (i);
328 
329  return nullptr;
330 }
331 
333 {
334  std::sort (entries.begin(), entries.end(),
335  [] (const ZipEntryHolder* e1, const ZipEntryHolder* e2) { return e1->entry.filename < e2->entry.filename; });
336 }
337 
338 //==============================================================================
339 void ZipFile::init()
340 {
341  std::unique_ptr<InputStream> toDelete;
342  InputStream* in = inputStream;
343 
344  if (inputSource != nullptr)
345  {
346  in = inputSource->createInputStream();
347  toDelete.reset (in);
348  }
349 
350  if (in != nullptr)
351  {
352  int numEntries = 0;
353  auto centralDirectoryPos = findCentralDirectoryFileHeader (*in, numEntries);
354 
355  if (centralDirectoryPos >= 0 && centralDirectoryPos < in->getTotalLength())
356  {
357  auto size = (size_t) (in->getTotalLength() - centralDirectoryPos);
358 
359  in->setPosition (centralDirectoryPos);
360  MemoryBlock headerData;
361 
362  if (in->readIntoMemoryBlock (headerData, (ssize_t) size) == size)
363  {
364  size_t pos = 0;
365 
366  for (int i = 0; i < numEntries; ++i)
367  {
368  if (pos + 46 > size)
369  break;
370 
371  auto* buffer = static_cast<const char*> (headerData.getData()) + pos;
372  auto fileNameLen = readUnalignedLittleEndianShort (buffer + 28);
373 
374  if (pos + 46 + fileNameLen > size)
375  break;
376 
377  entries.add (new ZipEntryHolder (buffer, fileNameLen));
378 
379  pos += 46 + fileNameLen
380  + readUnalignedLittleEndianShort (buffer + 30)
381  + readUnalignedLittleEndianShort (buffer + 32);
382  }
383  }
384  }
385  }
386 }
387 
388 Result ZipFile::uncompressTo (const File& targetDirectory,
389  const bool shouldOverwriteFiles)
390 {
391  for (int i = 0; i < entries.size(); ++i)
392  {
393  auto result = uncompressEntry (i, targetDirectory, shouldOverwriteFiles);
394 
395  if (result.failed())
396  return result;
397  }
398 
399  return Result::ok();
400 }
401 
402 Result ZipFile::uncompressEntry (int index, const File& targetDirectory, bool shouldOverwriteFiles)
403 {
404  auto* zei = entries.getUnchecked (index);
405 
406  #if JUCE_WINDOWS
407  auto entryPath = zei->entry.filename;
408  #else
409  auto entryPath = zei->entry.filename.replaceCharacter ('\\', '/');
410  #endif
411 
412  if (entryPath.isEmpty())
413  return Result::ok();
414 
415  auto targetFile = targetDirectory.getChildFile (entryPath);
416 
417  if (entryPath.endsWithChar ('/') || entryPath.endsWithChar ('\\'))
418  return targetFile.createDirectory(); // (entry is a directory, not a file)
419 
420  std::unique_ptr<InputStream> in (createStreamForEntry (index));
421 
422  if (in == nullptr)
423  return Result::fail ("Failed to open the zip file for reading");
424 
425  if (targetFile.exists())
426  {
427  if (! shouldOverwriteFiles)
428  return Result::ok();
429 
430  if (! targetFile.deleteFile())
431  return Result::fail ("Failed to write to target file: " + targetFile.getFullPathName());
432  }
433 
434  if (! targetFile.getParentDirectory().createDirectory())
435  return Result::fail ("Failed to create target folder: " + targetFile.getParentDirectory().getFullPathName());
436 
437  if (zei->entry.isSymbolicLink)
438  {
439  String originalFilePath (in->readEntireStreamAsString()
440  .replaceCharacter (L'/', File::getSeparatorChar()));
441 
442  if (! File::createSymbolicLink (targetFile, originalFilePath, true))
443  return Result::fail ("Failed to create symbolic link: " + originalFilePath);
444  }
445  else
446  {
447  FileOutputStream out (targetFile);
448 
449  if (out.failedToOpen())
450  return Result::fail ("Failed to write to target file: " + targetFile.getFullPathName());
451 
452  out << *in;
453  }
454 
455  targetFile.setCreationTime (zei->entry.fileTime);
456  targetFile.setLastModificationTime (zei->entry.fileTime);
457  targetFile.setLastAccessTime (zei->entry.fileTime);
458 
459  return Result::ok();
460 }
461 
462 
463 //==============================================================================
465 {
466  Item (const File& f, InputStream* s, int compression, const String& storedPath, Time time)
467  : file (f), stream (s), storedPathname (storedPath), fileTime (time), compressionLevel (compression)
468  {
469  symbolicLink = (file.exists() && file.isSymbolicLink());
470  }
471 
472  bool writeData (OutputStream& target, const int64 overallStartPosition)
473  {
474  MemoryOutputStream compressedData ((size_t) file.getSize());
475 
476  if (symbolicLink)
477  {
478  auto relativePath = file.getNativeLinkedTarget().replaceCharacter (File::getSeparatorChar(), L'/');
479 
480  uncompressedSize = relativePath.length();
481 
482  checksum = zlibNamespace::crc32 (0, (uint8_t*) relativePath.toRawUTF8(), (unsigned int) uncompressedSize);
483  compressedData << relativePath;
484  }
485  else if (compressionLevel > 0)
486  {
487  GZIPCompressorOutputStream compressor (compressedData, compressionLevel,
488  GZIPCompressorOutputStream::windowBitsRaw);
489  if (! writeSource (compressor))
490  return false;
491  }
492  else
493  {
494  if (! writeSource (compressedData))
495  return false;
496  }
497 
498  compressedSize = (int64) compressedData.getDataSize();
499  headerStart = target.getPosition() - overallStartPosition;
500 
501  target.writeInt (0x04034b50);
502  writeFlagsAndSizes (target);
503  target << storedPathname
504  << compressedData;
505 
506  return true;
507  }
508 
509  bool writeDirectoryEntry (OutputStream& target)
510  {
511  target.writeInt (0x02014b50);
512  target.writeShort (symbolicLink ? 0x0314 : 0x0014);
513  writeFlagsAndSizes (target);
514  target.writeShort (0); // comment length
515  target.writeShort (0); // start disk num
516  target.writeShort (0); // internal attributes
517  target.writeInt ((int) (symbolicLink ? 0xA1ED0000 : 0)); // external attributes
518  target.writeInt ((int) (uint32) headerStart);
519  target << storedPathname;
520 
521  return true;
522  }
523 
524 private:
525  const File file;
526  std::unique_ptr<InputStream> stream;
527  String storedPathname;
528  Time fileTime;
529  int64 compressedSize = 0, uncompressedSize = 0, headerStart = 0;
530  int compressionLevel = 0;
531  unsigned long checksum = 0;
532  bool symbolicLink = false;
533 
534  static void writeTimeAndDate (OutputStream& target, Time t)
535  {
536  target.writeShort ((short) (t.getSeconds() + (t.getMinutes() << 5) + (t.getHours() << 11)));
537  target.writeShort ((short) (t.getDayOfMonth() + ((t.getMonth() + 1) << 5) + ((t.getYear() - 1980) << 9)));
538  }
539 
540  bool writeSource (OutputStream& target)
541  {
542  if (stream == nullptr)
543  {
544  stream.reset (file.createInputStream());
545 
546  if (stream == nullptr)
547  return false;
548  }
549 
550  checksum = 0;
551  uncompressedSize = 0;
552  const int bufferSize = 4096;
553  HeapBlock<unsigned char> buffer (bufferSize);
554 
555  while (! stream->isExhausted())
556  {
557  auto bytesRead = stream->read (buffer, bufferSize);
558 
559  if (bytesRead < 0)
560  return false;
561 
562  checksum = zlibNamespace::crc32 (checksum, buffer, (unsigned int) bytesRead);
563  target.write (buffer, (size_t) bytesRead);
564  uncompressedSize += bytesRead;
565  }
566 
567  stream.reset();
568  return true;
569  }
570 
571  void writeFlagsAndSizes (OutputStream& target) const
572  {
573  target.writeShort (10); // version needed
574  target.writeShort ((short) (1 << 11)); // this flag indicates UTF-8 filename encoding
575  target.writeShort ((! symbolicLink && compressionLevel > 0) ? (short) 8 : (short) 0); //symlink target path is not compressed
576  writeTimeAndDate (target, fileTime);
577  target.writeInt ((int) checksum);
578  target.writeInt ((int) (uint32) compressedSize);
579  target.writeInt ((int) (uint32) uncompressedSize);
580  target.writeShort ((short) storedPathname.toUTF8().sizeInBytes() - 1);
581  target.writeShort (0); // extra field length
582  }
583 
584  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Item)
585 };
586 
587 //==============================================================================
590 
591 void ZipFile::Builder::addFile (const File& file, int compression, const String& path)
592 {
593  items.add (new Item (file, nullptr, compression,
594  path.isEmpty() ? file.getFileName() : path,
595  file.getLastModificationTime()));
596 }
597 
598 void ZipFile::Builder::addEntry (InputStream* stream, int compression, const String& path, Time time)
599 {
600  jassert (stream != nullptr); // must not be null!
601  jassert (path.isNotEmpty());
602  items.add (new Item ({}, stream, compression, path, time));
603 }
604 
605 bool ZipFile::Builder::writeToStream (OutputStream& target, double* const progress) const
606 {
607  auto fileStart = target.getPosition();
608 
609  for (int i = 0; i < items.size(); ++i)
610  {
611  if (progress != nullptr)
612  *progress = (i + 0.5) / items.size();
613 
614  if (! items.getUnchecked (i)->writeData (target, fileStart))
615  return false;
616  }
617 
618  auto directoryStart = target.getPosition();
619 
620  for (auto* item : items)
621  if (! item->writeDirectoryEntry (target))
622  return false;
623 
624  auto directoryEnd = target.getPosition();
625 
626  target.writeInt (0x06054b50);
627  target.writeShort (0);
628  target.writeShort (0);
629  target.writeShort ((short) items.size());
630  target.writeShort ((short) items.size());
631  target.writeInt ((int) (directoryEnd - directoryStart));
632  target.writeInt ((int) (directoryStart - fileStart));
633  target.writeShort (0);
634 
635  if (progress != nullptr)
636  *progress = 1.0;
637 
638  return true;
639 }
640 
641 //==============================================================================
642 #if JUCE_UNIT_TESTS
643 
644 struct ZIPTests : public UnitTest
645 {
646  ZIPTests() : UnitTest ("ZIP") {}
647 
648  void runTest() override
649  {
650  beginTest ("ZIP");
651 
652  ZipFile::Builder builder;
653  StringArray entryNames { "first", "second", "third" };
654  HashMap<String, MemoryBlock> blocks;
655 
656  for (auto& entryName : entryNames)
657  {
658  auto& block = blocks.getReference (entryName);
659  MemoryOutputStream mo (block, false);
660  mo << entryName;
661  mo.flush();
662  builder.addEntry (new MemoryInputStream (block, false), 9, entryName, Time::getCurrentTime());
663  }
664 
665  MemoryBlock data;
666  MemoryOutputStream mo (data, false);
667  builder.writeToStream (mo, nullptr);
668  MemoryInputStream mi (data, false);
669 
670  ZipFile zip (mi);
671 
672  expectEquals (zip.getNumEntries(), entryNames.size());
673 
674  for (auto& entryName : entryNames)
675  {
676  auto* entry = zip.getEntry (entryName);
677  std::unique_ptr<InputStream> input (zip.createStreamForEntry (*entry));
678  expectEquals (input->readEntireStreamAsString(), entryName);
679  }
680  }
681 };
682 
683 static ZIPTests zipTests;
684 
685 #endif
686 
687 } // namespace juce
juce::Time::getDayOfMonth
int getDayOfMonth() const noexcept
Returns the day of the month (in this machine's local timezone).
Definition: juce_Time.cpp:336
juce::Time::getYear
int getYear() const noexcept
Returns the year (in this machine's local timezone).
Definition: juce_Time.cpp:333
juce::StringArray
A special array for holding a list of strings.
Definition: juce_StringArray.h:38
juce::StringArray::getReference
String & getReference(int index) noexcept
Returns a reference to one of the strings in the array.
Definition: juce_StringArray.cpp:130
juce::File::getFileName
String getFileName() const
Returns the last section of the pathname.
Definition: juce_File.cpp:346
juce::ByteOrder::littleEndianShort
static JUCE_CONSTEXPR uint16 littleEndianShort(const void *bytes) noexcept
Turns 2 bytes into a little-endian integer.
Definition: juce_ByteOrder.h:202
juce::ZipFile::ZipEntry::fileTime
Time fileTime
The last time the file was modified.
Definition: juce_ZipFile.h:85
juce::Time::getMinutes
int getMinutes() const noexcept
Returns the number of minutes, 0 to 59 (in this machine's local timezone).
Definition: juce_Time.cpp:339
juce::String::toUTF8
CharPointer_UTF8 toUTF8() const
Returns a pointer to a UTF-8 version of this string.
Definition: juce_String.cpp:2068
juce::HeapBlock
Very simple container class to hold a pointer to some data on the heap.
Definition: juce_HeapBlock.h:90
juce::ZipFile
Decodes a ZIP file from a stream.
Definition: juce_ZipFile.h:39
juce::Result
Represents the 'success' or 'failure' of an operation, and holds an associated error message to descr...
Definition: juce_Result.h:60
juce::ZipFile::Builder::Item
Definition: juce_ZipFile.cpp:464
juce::FileOutputStream::failedToOpen
bool failedToOpen() const noexcept
Returns true if the stream couldn't be opened for some reason.
Definition: juce_FileOutputStream.h:90
juce::Time::getSeconds
int getSeconds() const noexcept
Returns the number of seconds, 0 to 59.
Definition: juce_Time.cpp:340
juce::GZIPCompressorOutputStream
A stream which uses zlib to compress the data written into it.
Definition: juce_GZIPCompressorOutputStream.h:42
juce::MemoryOutputStream
Writes data to an internal memory buffer, which grows as required.
Definition: juce_MemoryOutputStream.h:39
juce::InputStream
The base class for streams that read data.
Definition: juce_InputStream.h:40
juce::InputStream::read
virtual int read(void *destBuffer, int maxBytesToRead)=0
Reads some data from the stream into a memory buffer.
juce::ZipFile::ZipInputStream
Definition: juce_ZipFile.cpp:126
juce::ZipFile::getNumEntries
int getNumEntries() const noexcept
Returns the number of items in the zip file.
Definition: juce_ZipFile.cpp:269
juce::ZipFile::ZipInputStream::setPosition
bool setPosition(int64 newPos) override
Tries to move the current read position of the stream.
Definition: juce_ZipFile.cpp:208
juce::File::createDirectory
Result createDirectory() const
Creates a new directory for this filename.
Definition: juce_File.cpp:493
juce::InputSource
A lightweight object that can create a stream to read some kind of resource.
Definition: juce_InputSource.h:41
juce::Time::getCurrentTime
static Time JUCE_CALLTYPE getCurrentTime() noexcept
Returns a Time object that is set to the current system time.
Definition: juce_Time.cpp:218
juce::ZipFile::ZipEntry::filename
String filename
The name of the file, which may also include a partial pathname.
Definition: juce_ZipFile.h:79
juce::OutputStream::write
virtual bool write(const void *dataToWrite, size_t numberOfBytes)=0
Writes a block of data to the stream.
juce::InputStream::setPosition
virtual bool setPosition(int64 newPosition)=0
Tries to move the current read position of the stream.
juce::Time::getMonth
int getMonth() const noexcept
Returns the number of the month (in this machine's local timezone).
Definition: juce_Time.cpp:334
juce::OutputStream
The base class for streams that write data to some kind of destination.
Definition: juce_OutputStream.h:41
juce::ZipFile::uncompressEntry
Result uncompressEntry(int index, const File &targetDirectory, bool shouldOverwriteFiles=true)
Uncompresses one of the entries from the zip file.
Definition: juce_ZipFile.cpp:402
juce::File
Represents a local file or directory.
Definition: juce_File.h:44
juce::ZipFile::sortEntriesByFilename
void sortEntriesByFilename()
Sorts the list of entries, based on the filename.
Definition: juce_ZipFile.cpp:332
juce::BufferedInputStream
Wraps another input stream, and reads from it using an intermediate buffer.
Definition: juce_BufferedInputStream.h:40
juce::ZipFile::Builder::addEntry
void addEntry(InputStream *streamToRead, int compressionLevel, const String &storedPathName, Time fileModificationTime)
Adds a stream to the list of items which will be added to the archive.
Definition: juce_ZipFile.cpp:598
juce::String::replaceCharacter
String replaceCharacter(juce_wchar characterToReplace, juce_wchar characterToInsertInstead) const
Returns a string with all occurrences of a character replaced with a different one.
Definition: juce_String.cpp:1350
juce::OutputStream::writeShort
virtual bool writeShort(short value)
Writes a 16-bit integer to the stream in a little-endian byte order.
Definition: juce_OutputStream.cpp:86
juce::File::exists
bool exists() const
Checks whether the file actually exists.
juce::ZipFile::~ZipFile
~ZipFile()
Destructor.
Definition: juce_ZipFile.cpp:251
juce::File::getLastModificationTime
Time getLastModificationTime() const
Returns the last modification time of this file.
Definition: juce_File.cpp:512
juce::ZipFile::ZipEntry
Contains information about one of the entries in a ZipFile.
Definition: juce_ZipFile.h:76
juce::Time
Holds an absolute date and time.
Definition: juce_Time.h:40
juce::File::isSymbolicLink
bool isSymbolicLink() const
Returns true if this file is a link or alias that can be followed using getLinkedTarget().
juce::File::createInputStream
FileInputStream * createInputStream() const
Creates a stream to read from this file.
Definition: juce_File.cpp:709
juce::CharPointer_UTF8::sizeInBytes
size_t sizeInBytes() const noexcept
Returns the number of bytes that are used to represent this string.
Definition: juce_CharPointer_UTF8.h:279
juce::InputStream::readEntireStreamAsString
virtual String readEntireStreamAsString()
Tries to read the whole stream and turn it into a string.
Definition: juce_InputStream.cpp:209
juce::GenericScopedLock
Automatically locks and unlocks a mutex object.
Definition: juce_ScopedLock.h:58
juce::OutputStream::writeInt
virtual bool writeInt(int value)
Writes a 32-bit integer to the stream in a little-endian byte order.
Definition: juce_OutputStream.cpp:98
juce::String::isEmpty
bool isEmpty() const noexcept
Returns true if the string contains no characters.
Definition: juce_String.h:300
juce::ZipFile::ZipInputStream::getTotalLength
int64 getTotalLength() override
Returns the total number of bytes available for reading in this stream.
Definition: juce_ZipFile.cpp:165
juce::ZipFile::ZipInputStream::read
int read(void *buffer, int howMany) override
Reads some data from the stream into a memory buffer.
Definition: juce_ZipFile.cpp:170
juce::File::createSymbolicLink
bool createSymbolicLink(const File &linkFileToCreate, bool overwriteExisting) const
Tries to create a symbolic link and returns a boolean to indicate success.
Definition: juce_File.cpp:978
juce::ZipFile::ZipEntry::uncompressedSize
int64 uncompressedSize
The file's original size.
Definition: juce_ZipFile.h:82
juce::ZipFile::uncompressTo
Result uncompressTo(const File &targetDirectory, bool shouldOverwriteFiles=true)
Uncompresses all of the files in the zip file.
Definition: juce_ZipFile.cpp:388
juce::ZipFile::Builder
Used to create a new zip file.
Definition: juce_ZipFile.h:187
juce::InputStream::getTotalLength
virtual int64 getTotalLength()=0
Returns the total number of bytes available for reading in this stream.
juce::UnitTest
This is a base class for classes that perform a unit test.
Definition: juce_UnitTest.h:73
juce::ZipFile::Builder::Builder
Builder()
Creates an empty builder object.
Definition: juce_ZipFile.cpp:588
juce::String::isNotEmpty
bool isNotEmpty() const noexcept
Returns true if the string contains at least one character.
Definition: juce_String.h:306
juce::Time::getHours
int getHours() const noexcept
Returns the number of hours since midnight (in this machine's local timezone).
Definition: juce_Time.cpp:338
juce::ZipFile::getIndexOfFileName
int getIndexOfFileName(const String &fileName, bool ignoreCase=false) const noexcept
Returns the index of the first entry with a given filename.
Definition: juce_ZipFile.cpp:282
juce::File::getSeparatorChar
static juce_wchar getSeparatorChar()
The system-specific file separator character.
juce::ZipFile::ZipInputStream::isExhausted
bool isExhausted() override
Returns true if the stream has no more data to read.
Definition: juce_ZipFile.cpp:198
juce::String
The JUCE String class!
Definition: juce_String.h:42
juce::ZipFile::Builder::writeToStream
bool writeToStream(OutputStream &target, double *progress) const
Generates the zip file, writing it to the specified stream.
Definition: juce_ZipFile.cpp:605
juce::ZipFile::Builder::~Builder
~Builder()
Destructor.
Definition: juce_ZipFile.cpp:589
juce::GZIPDecompressorInputStream
This stream will decompress a source-stream using zlib.
Definition: juce_GZIPDecompressorInputStream.h:42
juce::Result::ok
static Result ok() noexcept
Creates and returns a 'successful' result.
Definition: juce_Result.h:65
juce::FileInputSource
A type of InputSource that represents a normal file.
Definition: juce_FileInputSource.h:38
juce::ZipFile::ZipEntryHolder
Definition: juce_ZipFile.cpp:38
juce::OutputStream::getPosition
virtual int64 getPosition()=0
Returns the stream's current position.
juce::FileOutputStream
An output stream that writes into a local file.
Definition: juce_FileOutputStream.h:38
juce::MemoryOutputStream::getDataSize
size_t getDataSize() const noexcept
Returns the number of bytes of data that have been written to the stream.
Definition: juce_MemoryOutputStream.h:84
juce::String::fromUTF8
static String fromUTF8(const char *utf8buffer, int bufferSizeBytes=-1)
Creates a String from a UTF-8 encoded buffer.
Definition: juce_String.cpp:2123
juce::File::getSize
int64 getSize() const
Returns the size of the file in bytes.
juce::ZipFile::getEntry
const ZipEntry * getEntry(int index) const noexcept
Returns a structure that describes one of the entries in the zip file.
Definition: juce_ZipFile.cpp:274
juce::ZipFile::Builder::addFile
void addFile(const File &fileToAdd, int compressionLevel, const String &storedPathName=String())
Adds a file to the list of items which will be added to the archive.
Definition: juce_ZipFile.cpp:591
juce::Result::fail
static Result fail(const String &errorMessage) noexcept
Creates a 'failure' result.
Definition: juce_Result.cpp:65
juce::ByteOrder::littleEndianInt
static JUCE_CONSTEXPR uint32 littleEndianInt(const void *bytes) noexcept
Turns 4 bytes into a little-endian integer.
Definition: juce_ByteOrder.h:203
juce::File::getNativeLinkedTarget
String getNativeLinkedTarget() const
This returns the native path that the symbolic link points to.
juce::ZipFile::ZipInputStream::getPosition
int64 getPosition() override
Returns the offset of the next byte that will be read from the stream.
Definition: juce_ZipFile.cpp:203
juce::ZipFile::ZipEntry::isSymbolicLink
bool isSymbolicLink
True if the zip entry is a symbolic link.
Definition: juce_ZipFile.h:88
juce::ZipFile::createStreamForEntry
InputStream * createStreamForEntry(int index)
Creates a stream that can read from one of the zip file's entries.
Definition: juce_ZipFile.cpp:301
juce::File::getChildFile
File getChildFile(StringRef relativeOrAbsolutePath) const
Returns a file that represents a relative (or absolute) sub-path of the current one.
Definition: juce_File.cpp:394
juce::ZipFile::ZipFile
ZipFile(const File &file)
Creates a ZipFile to read a specific file.
Definition: juce_ZipFile.cpp:241
juce::InputStream::readIntoMemoryBlock
virtual size_t readIntoMemoryBlock(MemoryBlock &destBlock, ssize_t maxNumBytesToRead=-1)
Reads from the stream and appends the data to a MemoryBlock.
Definition: juce_InputStream.cpp:203