Zip.hpp
Go to the documentation of this file.
1 // @formatter:off
2 //
3 // Balau core C++ library
4 //
5 // Copyright (C) 2008 Bora Software (contact@borasoftware.com)
6 //
7 // Licensed under the Boost Software License - Version 1.0 - August 17th, 2003.
8 // See the LICENSE file for the full license text.
9 //
10 
16 
17 #ifndef COM_BORA_SOFTWARE__BALAU_UTIL__ZIP
18 #define COM_BORA_SOFTWARE__BALAU_UTIL__ZIP
19 
21 #include <Balau/Resource/File.hpp>
22 #include <Balau/Util/DateTime.hpp>
23 #include <Balau/Util/Files.hpp>
24 
25 #include <boost/iostreams/categories.hpp>
26 #include <boost/iostreams/concepts.hpp>
27 #include <boost/iostreams/copy.hpp>
28 #include <boost/iostreams/device/file_descriptor.hpp>
29 #include <boost/iostreams/filter/gzip.hpp>
30 #include <boost/iostreams/filtering_stream.hpp>
31 #include <boost/iostreams/filtering_streambuf.hpp>
32 
33 #include <algorithm>
34 #include <chrono>
35 #include <iosfwd>
36 #include <sstream>
37 
38 namespace Balau {
39 
40 namespace Resource::Impl {
41 
42 class ZipEntrySource;
43 class ZipEntrySink;
44 
45 } // namespace Resource::Impl
46 
47 namespace Util {
48 
54 struct ZipEntryInfo {
58  std::string name;
59 
63  long long index;
64 
68  long long uncompressedSize;
69 
73  long long compressedSize;
74 
78  std::chrono::system_clock::time_point modificationTime;
79 
83  unsigned int crc;
84 
88  unsigned short compressionMethod;
89 
93  unsigned short encryptionMethod;
94 };
95 
96 inline bool operator == (const ZipEntryInfo & lhs, const ZipEntryInfo & rhs) {
97  return lhs.name == rhs.name
98  && lhs.index == rhs.index
100  && lhs.compressedSize == rhs.compressedSize
101  && lhs.modificationTime == rhs.modificationTime
102  && lhs.crc == rhs.crc
104  && lhs.encryptionMethod == rhs.encryptionMethod;
105 }
106 
112 template <typename AllocatorT>
114  return "{ " + Strings::join<AllocatorT>(
115  ", "
116  , info.name
117  , info.index
118  , info.uncompressedSize
119  , info.compressedSize
120  // TODO
121 // , info.modificationTime
122  , info.crc
123  , info.compressionMethod
124  , info.encryptionMethod
125  ) + " }";
126 }
127 
133 inline std::string toString(const ZipEntryInfo & info) {
134  return "{ " + Strings::join(
135  ", "
136  , info.name
137  , info.index
138  , info.uncompressedSize
139  , info.compressedSize
140  // TODO
141 // , info.modificationTime
142  , info.crc
143  , info.compressionMethod
144  , info.encryptionMethod
145  ) + " }";
146 }
147 
155 class Unzipper {
163  public: virtual void open(const Resource::File & path_, bool verify);
164 
173  public: virtual void open(const Resource::File & path_, bool verify, const std::string & pw);
174 
180  public: bool isOpen() const {
181  return archive != nullptr;
182  }
183 
189  public: Resource::File getPath() const {
190  return path;
191  }
192 
202  public: std::string readArchiveComment() const;
203 
213  public: long long entryCount() const;
214 
224  public: std::vector<std::string> entryNames() const;
225 
235  public: bool hasEntry(const std::string & name) const;
236 
245  public: long long getEntryIndex(const std::string & name) const;
246 
255  public: std::string getEntryName(long long index) const;
256 
267  public: void getEntryInfo(const std::string & name, ZipEntryInfo & info) const;
268 
277  public: void getEntryInfo(long long index, ZipEntryInfo & info) const;
278 
288  public: std::string readEntryComment(const std::string & name) const;
289 
298  public: std::string readEntryComment(long long index) const;
299 
310  public: std::vector<char> readEntryAsBytes(const std::string & name) const;
311 
320  public: std::vector<char> readEntryAsBytes(long long index) const;
321 
332  public: std::string readEntryAsString(const std::string & name) const;
333 
342  public: std::string readEntryAsString(long long index) const;
343 
353  public: virtual void close();
354 
358  public: virtual ~Unzipper();
359 
361 
362  friend class Resource::Impl::ZipEntrySource;
363  friend class Resource::Impl::ZipEntrySink;
364 
365  private: std::vector<char> readEntryAsBytesImpl(const ZipEntryInfo & info, const std::string & name) const;
366  private: std::string readEntryAsStringImpl(const ZipEntryInfo & info, const std::string & name) const;
367 
368  // Used in the cleanUpName method.
369  protected: enum class EntryType {
370  Directory, File, Either
371  };
372 
373  protected: void openImpl(const Resource::File & path_, bool verify, const std::string & pw, int mode);
374 
375  // Clean up the supplied name's separator characters.
376  protected: std::string cleanUpName(const std::string & name, EntryType entryType) const;
377 
378  protected: long long getEntryIndexClean(const std::string & cleanName) const;
379  protected: void throwZipException(const std::string & errorMessage) const;
380 
381  protected: void * archive;
382  protected: Resource::File path;
383 };
384 
399 class Zipper : public Unzipper {
413  public: void open(const Resource::File & path_, bool verify) override;
414 
429  public: void open(const Resource::File & path_, bool verify, const std::string & pw) override;
430 
438  public: void putArchiveComment(const std::string & text);
439 
446  public: void deleteComment();
447 
457  public: void putDirectory(const std::string & name);
458 
467  public: void putEntry(const std::string & name, const Resource::File & bytes);
468 
480  public: void putEntry(const std::string & name, const std::vector<char> & bytes);
481 
493  public: void putEntry(const std::string & name, const std::string & bytes);
494 
505  public: void renameEntry(const std::string & name, const std::string & newName);
506 
516  public: void deleteEntry(const std::string & name);
517 
531  public: void close() override;
532 
551  public: void commit();
552 
554 
555  // Common implementation for putEntry methods.
556  private: template <typename SourceFunctionT> void putEntry(const std::string & name, SourceFunctionT getSource);
557 
558  // Rename a directory entry and all its descendants.
559  private: void renameDirectory(const std::string & cleanName, const std::string & newCleanName);
560 
561  // Rename a file entry.
562  private: void renameFile(const std::string & cleanName, const std::string & newCleanName);
563 
564  // Delete a directory entry and all its descendants.
565  private: void deleteDirectory(const std::string & cleanName);
566 
567  // Delete a file entry.
568  private: void deleteFile(const std::string & cleanName);
569 };
570 
571 } // namespace Util
572 
573 } // namespace Balau
574 
575 #endif // COM_BORA_SOFTWARE__BALAU_UTIL__ZIP
unsigned short encryptionMethod
The encryption method used.
Definition: Zip.hpp:93
Random access to the entries in a zip archive.
Definition: Zip.hpp:155
std::string name
The name of the entry.
Definition: Zip.hpp:58
Utilities for files.
bool operator==(const UriComponents &lhs, const UriComponents &rhs)
Returns true if the two URI component instances are equal.
Definition: UriComponents.hpp:335
A file on the local file system.
Information about a zip archive entry (file or directory).
Definition: Zip.hpp:54
std::chrono::system_clock::time_point modificationTime
The last modification time.
Definition: Zip.hpp:78
The root Balau namespace.
Definition: ApplicationConfiguration.hpp:23
long long index
The entry index within the archive.
Definition: Zip.hpp:63
long long compressedSize
The compressed size of the entry.
Definition: Zip.hpp:73
Transactional modification of entries in a new or existing zip archive.
Definition: Zip.hpp:399
Balau::U8String< AllocatorT > toString(const File &file)
Print the file URI as a UTF-8 string.
Definition: File.hpp:724
A file on the local file system.
Definition: File.hpp:35
unsigned short compressionMethod
The compression method used.
Definition: Zip.hpp:88
Balau exceptions for resources.
std::basic_string< char, std::char_traits< char >, AllocatorT > U8String
UTF-8 string type with selectable allocator.
Definition: ToStringA.hpp:41
Resource::File getPath() const
Get the file URI that this unzipper accesses.
Definition: Zip.hpp:189
long long uncompressedSize
The uncompressed size of the entry.
Definition: Zip.hpp:68
unsigned int crc
The CRC of the entry&#39;s data.
Definition: Zip.hpp:83
Date and time utilities.
bool isOpen() const
Is an archive currently open?
Definition: Zip.hpp:180