1 // Copyright 2017 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef THIRD_PARTY_ZLIB_GOOGLE_ZIP_WRITER_H_ 6 #define THIRD_PARTY_ZLIB_GOOGLE_ZIP_WRITER_H_ 7 8 #include <memory> 9 #include <vector> 10 11 #include "base/files/file_path.h" 12 #include "base/time/time.h" 13 #include "build/build_config.h" 14 #include "third_party/zlib/google/zip.h" 15 16 #if defined(USE_SYSTEM_MINIZIP) 17 #include <minizip/unzip.h> 18 #include <minizip/zip.h> 19 #else 20 #include "third_party/zlib/contrib/minizip/unzip.h" 21 #include "third_party/zlib/contrib/minizip/zip.h" 22 #endif 23 24 namespace zip { 25 namespace internal { 26 27 // A class used to write entries to a ZIP file and buffering the reading of 28 // files to limit the number of calls to the FileAccessor. This is for 29 // performance reasons as these calls may be expensive when IPC based). 30 // This class is so far internal and only used by zip.cc, but could be made 31 // public if needed. 32 // 33 // All methods returning a bool return true on success and false on error. 34 class ZipWriter { 35 public: 36 // Creates a writer that will write a ZIP file to |zip_file_fd| or |zip_file| 37 // and which entries are relative to |file_accessor|'s source directory. 38 // All file reads are performed using |file_accessor|. 39 #if defined(OS_POSIX) || defined(OS_FUCHSIA) 40 static std::unique_ptr<ZipWriter> CreateWithFd(int zip_file_fd, 41 FileAccessor* file_accessor); 42 #endif 43 44 static std::unique_ptr<ZipWriter> Create(const base::FilePath& zip_file, 45 FileAccessor* file_accessor); 46 47 ZipWriter(const ZipWriter&) = delete; 48 ZipWriter& operator=(const ZipWriter&) = delete; 49 50 ~ZipWriter(); 51 52 // Sets the optional progress callback. The callback is called once for each 53 // time |period|. The final callback is always called when the ZIP operation 54 // completes. SetProgressCallback(ProgressCallback callback,base::TimeDelta period)55 void SetProgressCallback(ProgressCallback callback, base::TimeDelta period) { 56 progress_callback_ = std::move(callback); 57 progress_period_ = std::move(period); 58 } 59 60 // Should ignore missing files and directories? ContinueOnError(bool continue_on_error)61 void ContinueOnError(bool continue_on_error) { 62 continue_on_error_ = continue_on_error; 63 } 64 65 // Sets the recursive flag, indicating whether the contents of subdirectories 66 // should be included. SetRecursive(bool b)67 void SetRecursive(bool b) { recursive_ = b; } 68 69 // Sets the filter callback. SetFilterCallback(FilterCallback callback)70 void SetFilterCallback(FilterCallback callback) { 71 filter_callback_ = std::move(callback); 72 } 73 74 // Adds the contents of a directory. If the recursive flag is set, the 75 // contents of subdirectories are also added. 76 bool AddDirectoryContents(const base::FilePath& path); 77 78 // Adds the entries at |paths| to the ZIP file. These can be a mixed bag of 79 // files and directories. If the recursive flag is set, the contents of 80 // subdirectories is also added. 81 bool AddMixedEntries(Paths paths); 82 83 // Closes the ZIP file. 84 bool Close(); 85 86 private: 87 // Takes ownership of |zip_file|. 88 ZipWriter(zipFile zip_file, FileAccessor* file_accessor); 89 90 // Regularly called during processing to check whether zipping should continue 91 // or should be cancelled. 92 bool ShouldContinue(); 93 94 // Adds file content to currently open file entry. 95 bool AddFileContent(const base::FilePath& path, base::File file); 96 97 // Adds a file entry (including file contents). 98 bool AddFileEntry(const base::FilePath& path, base::File file); 99 100 // Adds file entries. All the paths should be existing files. 101 bool AddFileEntries(Paths paths); 102 103 // Adds a directory entry. If the recursive flag is set, the contents of this 104 // directory are also added. 105 bool AddDirectoryEntry(const base::FilePath& path); 106 107 // Adds directory entries. All the paths should be existing directories. If 108 // the recursive flag is set, the contents of these directories are also 109 // added. 110 bool AddDirectoryEntries(Paths paths); 111 112 // Opens a file or directory entry. 113 bool OpenNewFileEntry(const base::FilePath& path, 114 bool is_directory, 115 base::Time last_modified); 116 117 // Closes the currently open entry. 118 bool CloseNewFileEntry(); 119 120 // Filters entries. 121 void Filter(std::vector<base::FilePath>* paths); 122 123 // The actual zip file. 124 zipFile zip_file_; 125 126 // Abstraction over file access methods used to read files. 127 FileAccessor* const file_accessor_; 128 129 // Progress stats. 130 Progress progress_; 131 132 // Optional progress callback. 133 ProgressCallback progress_callback_; 134 135 // Optional progress reporting period. 136 base::TimeDelta progress_period_; 137 138 // Next time to report progress. 139 base::TimeTicks next_progress_report_time_ = base::TimeTicks::Now(); 140 141 // Filter used to exclude files from the ZIP file. 142 FilterCallback filter_callback_; 143 144 // Should recursively add directories? 145 bool recursive_ = false; 146 147 // Should ignore missing files and directories? 148 bool continue_on_error_ = false; 149 }; 150 151 } // namespace internal 152 } // namespace zip 153 154 #endif // THIRD_PARTY_ZLIB_GOOGLE_ZIP_WRITER_H_ 155