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