1*86ee64e7SAndroid Build Coastguard Worker // Copyright 2011 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_H_ 6*86ee64e7SAndroid Build Coastguard Worker #define THIRD_PARTY_ZLIB_GOOGLE_ZIP_H_ 7*86ee64e7SAndroid Build Coastguard Worker 8*86ee64e7SAndroid Build Coastguard Worker #include <cstdint> 9*86ee64e7SAndroid Build Coastguard Worker #include <ostream> 10*86ee64e7SAndroid Build Coastguard Worker #include <utility> 11*86ee64e7SAndroid Build Coastguard Worker #include <vector> 12*86ee64e7SAndroid Build Coastguard Worker 13*86ee64e7SAndroid Build Coastguard Worker #include "base/containers/span.h" 14*86ee64e7SAndroid Build Coastguard Worker #include "base/files/file_path.h" 15*86ee64e7SAndroid Build Coastguard Worker #include "base/files/platform_file.h" 16*86ee64e7SAndroid Build Coastguard Worker #include "base/functional/callback.h" 17*86ee64e7SAndroid Build Coastguard Worker #include "base/time/time.h" 18*86ee64e7SAndroid Build Coastguard Worker #include "build/build_config.h" 19*86ee64e7SAndroid Build Coastguard Worker 20*86ee64e7SAndroid Build Coastguard Worker namespace base { 21*86ee64e7SAndroid Build Coastguard Worker class File; 22*86ee64e7SAndroid Build Coastguard Worker } 23*86ee64e7SAndroid Build Coastguard Worker 24*86ee64e7SAndroid Build Coastguard Worker namespace zip { 25*86ee64e7SAndroid Build Coastguard Worker 26*86ee64e7SAndroid Build Coastguard Worker class WriterDelegate; 27*86ee64e7SAndroid Build Coastguard Worker 28*86ee64e7SAndroid Build Coastguard Worker // Paths passed as span to avoid copying them. 29*86ee64e7SAndroid Build Coastguard Worker using Paths = base::span<const base::FilePath>; 30*86ee64e7SAndroid Build Coastguard Worker 31*86ee64e7SAndroid Build Coastguard Worker // Abstraction for file access operation required by Zip(). 32*86ee64e7SAndroid Build Coastguard Worker // 33*86ee64e7SAndroid Build Coastguard Worker // Can be passed to the ZipParams for providing custom access to the files, 34*86ee64e7SAndroid Build Coastguard Worker // for example over IPC. 35*86ee64e7SAndroid Build Coastguard Worker // 36*86ee64e7SAndroid Build Coastguard Worker // All parameters paths are expected to be relative to the source directory. 37*86ee64e7SAndroid Build Coastguard Worker class FileAccessor { 38*86ee64e7SAndroid Build Coastguard Worker public: 39*86ee64e7SAndroid Build Coastguard Worker virtual ~FileAccessor() = default; 40*86ee64e7SAndroid Build Coastguard Worker 41*86ee64e7SAndroid Build Coastguard Worker struct Info { 42*86ee64e7SAndroid Build Coastguard Worker bool is_directory = false; 43*86ee64e7SAndroid Build Coastguard Worker base::Time last_modified; 44*86ee64e7SAndroid Build Coastguard Worker }; 45*86ee64e7SAndroid Build Coastguard Worker 46*86ee64e7SAndroid Build Coastguard Worker // Opens files specified in |paths|. 47*86ee64e7SAndroid Build Coastguard Worker // Directories should be mapped to invalid files. 48*86ee64e7SAndroid Build Coastguard Worker virtual bool Open(Paths paths, std::vector<base::File>* files) = 0; 49*86ee64e7SAndroid Build Coastguard Worker 50*86ee64e7SAndroid Build Coastguard Worker // Lists contents of a directory at |path|. 51*86ee64e7SAndroid Build Coastguard Worker virtual bool List(const base::FilePath& path, 52*86ee64e7SAndroid Build Coastguard Worker std::vector<base::FilePath>* files, 53*86ee64e7SAndroid Build Coastguard Worker std::vector<base::FilePath>* subdirs) = 0; 54*86ee64e7SAndroid Build Coastguard Worker 55*86ee64e7SAndroid Build Coastguard Worker // Gets info about a file or directory. 56*86ee64e7SAndroid Build Coastguard Worker virtual bool GetInfo(const base::FilePath& path, Info* info) = 0; 57*86ee64e7SAndroid Build Coastguard Worker }; 58*86ee64e7SAndroid Build Coastguard Worker 59*86ee64e7SAndroid Build Coastguard Worker // Progress of a ZIP creation operation. 60*86ee64e7SAndroid Build Coastguard Worker struct Progress { 61*86ee64e7SAndroid Build Coastguard Worker // Total number of bytes read from files getting zipped so far. 62*86ee64e7SAndroid Build Coastguard Worker std::int64_t bytes = 0; 63*86ee64e7SAndroid Build Coastguard Worker 64*86ee64e7SAndroid Build Coastguard Worker // Number of file entries added to the ZIP so far. 65*86ee64e7SAndroid Build Coastguard Worker // A file entry is added after its bytes have been processed. 66*86ee64e7SAndroid Build Coastguard Worker int files = 0; 67*86ee64e7SAndroid Build Coastguard Worker 68*86ee64e7SAndroid Build Coastguard Worker // Number of directory entries added to the ZIP so far. 69*86ee64e7SAndroid Build Coastguard Worker // A directory entry is added before items in it. 70*86ee64e7SAndroid Build Coastguard Worker int directories = 0; 71*86ee64e7SAndroid Build Coastguard Worker 72*86ee64e7SAndroid Build Coastguard Worker // Number of errors encountered so far (files that cannot be opened, 73*86ee64e7SAndroid Build Coastguard Worker // directories that cannot be listed). 74*86ee64e7SAndroid Build Coastguard Worker int errors = 0; 75*86ee64e7SAndroid Build Coastguard Worker }; 76*86ee64e7SAndroid Build Coastguard Worker 77*86ee64e7SAndroid Build Coastguard Worker // Prints Progress to output stream. 78*86ee64e7SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& out, const Progress& progress); 79*86ee64e7SAndroid Build Coastguard Worker 80*86ee64e7SAndroid Build Coastguard Worker // Callback reporting the progress of a ZIP creation operation. 81*86ee64e7SAndroid Build Coastguard Worker // 82*86ee64e7SAndroid Build Coastguard Worker // This callback returns a boolean indicating whether the ZIP creation operation 83*86ee64e7SAndroid Build Coastguard Worker // should continue. If it returns false once, then the ZIP creation operation is 84*86ee64e7SAndroid Build Coastguard Worker // immediately cancelled and the callback won't be called again. 85*86ee64e7SAndroid Build Coastguard Worker using ProgressCallback = base::RepeatingCallback<bool(const Progress&)>; 86*86ee64e7SAndroid Build Coastguard Worker 87*86ee64e7SAndroid Build Coastguard Worker using FilterCallback = base::RepeatingCallback<bool(const base::FilePath&)>; 88*86ee64e7SAndroid Build Coastguard Worker 89*86ee64e7SAndroid Build Coastguard Worker // ZIP creation parameters and options. 90*86ee64e7SAndroid Build Coastguard Worker struct ZipParams { 91*86ee64e7SAndroid Build Coastguard Worker // Source directory. Ignored if |file_accessor| is set. 92*86ee64e7SAndroid Build Coastguard Worker base::FilePath src_dir; 93*86ee64e7SAndroid Build Coastguard Worker 94*86ee64e7SAndroid Build Coastguard Worker // Abstraction around file system access used to read files. 95*86ee64e7SAndroid Build Coastguard Worker // If left null, an implementation that accesses files directly is used. 96*86ee64e7SAndroid Build Coastguard Worker FileAccessor* file_accessor = nullptr; // Not owned 97*86ee64e7SAndroid Build Coastguard Worker 98*86ee64e7SAndroid Build Coastguard Worker // Destination file path. 99*86ee64e7SAndroid Build Coastguard Worker // Either dest_file or dest_fd should be set, but not both. 100*86ee64e7SAndroid Build Coastguard Worker base::FilePath dest_file; 101*86ee64e7SAndroid Build Coastguard Worker 102*86ee64e7SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA) 103*86ee64e7SAndroid Build Coastguard Worker // Destination file passed a file descriptor. 104*86ee64e7SAndroid Build Coastguard Worker // Either dest_file or dest_fd should be set, but not both. 105*86ee64e7SAndroid Build Coastguard Worker int dest_fd = base::kInvalidPlatformFile; 106*86ee64e7SAndroid Build Coastguard Worker #endif 107*86ee64e7SAndroid Build Coastguard Worker 108*86ee64e7SAndroid Build Coastguard Worker // The relative paths to the files and directories that should be included in 109*86ee64e7SAndroid Build Coastguard Worker // the ZIP file. If this is empty, the whole contents of |src_dir| are 110*86ee64e7SAndroid Build Coastguard Worker // included. 111*86ee64e7SAndroid Build Coastguard Worker // 112*86ee64e7SAndroid Build Coastguard Worker // These paths must be relative to |src_dir| and will be used as the file 113*86ee64e7SAndroid Build Coastguard Worker // names in the created ZIP file. All files must be under |src_dir| in the 114*86ee64e7SAndroid Build Coastguard Worker // file system hierarchy. 115*86ee64e7SAndroid Build Coastguard Worker // 116*86ee64e7SAndroid Build Coastguard Worker // All the paths in |src_files| are included in the created ZIP file, 117*86ee64e7SAndroid Build Coastguard Worker // irrespective of |include_hidden_files| and |filter_callback|. 118*86ee64e7SAndroid Build Coastguard Worker Paths src_files; 119*86ee64e7SAndroid Build Coastguard Worker 120*86ee64e7SAndroid Build Coastguard Worker // Filter used to exclude files from the ZIP file. This is only taken in 121*86ee64e7SAndroid Build Coastguard Worker // account when recursively adding subdirectory contents. 122*86ee64e7SAndroid Build Coastguard Worker FilterCallback filter_callback; 123*86ee64e7SAndroid Build Coastguard Worker 124*86ee64e7SAndroid Build Coastguard Worker // Optional progress reporting callback. 125*86ee64e7SAndroid Build Coastguard Worker ProgressCallback progress_callback; 126*86ee64e7SAndroid Build Coastguard Worker 127*86ee64e7SAndroid Build Coastguard Worker // Progress reporting period. The final callback is always called when the ZIP 128*86ee64e7SAndroid Build Coastguard Worker // creation operation completes. 129*86ee64e7SAndroid Build Coastguard Worker base::TimeDelta progress_period; 130*86ee64e7SAndroid Build Coastguard Worker 131*86ee64e7SAndroid Build Coastguard Worker // Should add hidden files? This is only taken in account when recursively 132*86ee64e7SAndroid Build Coastguard Worker // adding subdirectory contents. 133*86ee64e7SAndroid Build Coastguard Worker bool include_hidden_files = true; 134*86ee64e7SAndroid Build Coastguard Worker 135*86ee64e7SAndroid Build Coastguard Worker // Should recursively add subdirectory contents? 136*86ee64e7SAndroid Build Coastguard Worker bool recursive = false; 137*86ee64e7SAndroid Build Coastguard Worker 138*86ee64e7SAndroid Build Coastguard Worker // Should ignore errors when discovering files and zipping them? 139*86ee64e7SAndroid Build Coastguard Worker bool continue_on_error = false; 140*86ee64e7SAndroid Build Coastguard Worker }; 141*86ee64e7SAndroid Build Coastguard Worker 142*86ee64e7SAndroid Build Coastguard Worker // Zip files specified into a ZIP archives. The source files and ZIP destination 143*86ee64e7SAndroid Build Coastguard Worker // files (as well as other settings) are specified in |params|. 144*86ee64e7SAndroid Build Coastguard Worker bool Zip(const ZipParams& params); 145*86ee64e7SAndroid Build Coastguard Worker 146*86ee64e7SAndroid Build Coastguard Worker // Zip the contents of src_dir into dest_file. src_path must be a directory. 147*86ee64e7SAndroid Build Coastguard Worker // An entry will *not* be created in the zip for the root folder -- children 148*86ee64e7SAndroid Build Coastguard Worker // of src_dir will be at the root level of the created zip. For each file in 149*86ee64e7SAndroid Build Coastguard Worker // src_dir, include it only if the callback |filter_cb| returns true. Otherwise 150*86ee64e7SAndroid Build Coastguard Worker // omit it. 151*86ee64e7SAndroid Build Coastguard Worker bool ZipWithFilterCallback(const base::FilePath& src_dir, 152*86ee64e7SAndroid Build Coastguard Worker const base::FilePath& dest_file, 153*86ee64e7SAndroid Build Coastguard Worker FilterCallback filter_cb); 154*86ee64e7SAndroid Build Coastguard Worker 155*86ee64e7SAndroid Build Coastguard Worker // Convenience method for callers who don't need to set up the filter callback. 156*86ee64e7SAndroid Build Coastguard Worker // If |include_hidden_files| is true, files starting with "." are included. 157*86ee64e7SAndroid Build Coastguard Worker // Otherwise they are omitted. 158*86ee64e7SAndroid Build Coastguard Worker bool Zip(const base::FilePath& src_dir, 159*86ee64e7SAndroid Build Coastguard Worker const base::FilePath& dest_file, 160*86ee64e7SAndroid Build Coastguard Worker bool include_hidden_files); 161*86ee64e7SAndroid Build Coastguard Worker 162*86ee64e7SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA) 163*86ee64e7SAndroid Build Coastguard Worker // Zips files listed in |src_relative_paths| to destination specified by file 164*86ee64e7SAndroid Build Coastguard Worker // descriptor |dest_fd|, without taking ownership of |dest_fd|. The paths listed 165*86ee64e7SAndroid Build Coastguard Worker // in |src_relative_paths| are relative to the |src_dir| and will be used as the 166*86ee64e7SAndroid Build Coastguard Worker // file names in the created zip file. All source paths must be under |src_dir| 167*86ee64e7SAndroid Build Coastguard Worker // in the file system hierarchy. 168*86ee64e7SAndroid Build Coastguard Worker bool ZipFiles(const base::FilePath& src_dir, 169*86ee64e7SAndroid Build Coastguard Worker Paths src_relative_paths, 170*86ee64e7SAndroid Build Coastguard Worker int dest_fd); 171*86ee64e7SAndroid Build Coastguard Worker #endif // defined(OS_POSIX) || defined(OS_FUCHSIA) 172*86ee64e7SAndroid Build Coastguard Worker 173*86ee64e7SAndroid Build Coastguard Worker // Callback reporting the number of bytes written during Unzip. 174*86ee64e7SAndroid Build Coastguard Worker using UnzipProgressCallback = base::RepeatingCallback<void(uint64_t bytes)>; 175*86ee64e7SAndroid Build Coastguard Worker 176*86ee64e7SAndroid Build Coastguard Worker // Options of the Unzip function, with valid default values. 177*86ee64e7SAndroid Build Coastguard Worker struct UnzipOptions { 178*86ee64e7SAndroid Build Coastguard Worker // Encoding of entry paths in the ZIP archive. By default, paths are assumed 179*86ee64e7SAndroid Build Coastguard Worker // to be in UTF-8. 180*86ee64e7SAndroid Build Coastguard Worker std::string encoding; 181*86ee64e7SAndroid Build Coastguard Worker 182*86ee64e7SAndroid Build Coastguard Worker // Only extract the entries for which |filter_cb| returns true. By default, 183*86ee64e7SAndroid Build Coastguard Worker // everything gets extracted. 184*86ee64e7SAndroid Build Coastguard Worker FilterCallback filter; 185*86ee64e7SAndroid Build Coastguard Worker 186*86ee64e7SAndroid Build Coastguard Worker // Callback to report bytes extracted from the ZIP. 187*86ee64e7SAndroid Build Coastguard Worker UnzipProgressCallback progress; 188*86ee64e7SAndroid Build Coastguard Worker 189*86ee64e7SAndroid Build Coastguard Worker // Password to decrypt the encrypted files. 190*86ee64e7SAndroid Build Coastguard Worker std::string password; 191*86ee64e7SAndroid Build Coastguard Worker 192*86ee64e7SAndroid Build Coastguard Worker // Should ignore errors when extracting files? 193*86ee64e7SAndroid Build Coastguard Worker bool continue_on_error = false; 194*86ee64e7SAndroid Build Coastguard Worker }; 195*86ee64e7SAndroid Build Coastguard Worker 196*86ee64e7SAndroid Build Coastguard Worker typedef base::RepeatingCallback<std::unique_ptr<WriterDelegate>( 197*86ee64e7SAndroid Build Coastguard Worker const base::FilePath&)> 198*86ee64e7SAndroid Build Coastguard Worker WriterFactory; 199*86ee64e7SAndroid Build Coastguard Worker 200*86ee64e7SAndroid Build Coastguard Worker typedef base::RepeatingCallback<bool(const base::FilePath&)> DirectoryCreator; 201*86ee64e7SAndroid Build Coastguard Worker 202*86ee64e7SAndroid Build Coastguard Worker // Unzips the contents of |zip_file|, using the writers provided by 203*86ee64e7SAndroid Build Coastguard Worker // |writer_factory|. 204*86ee64e7SAndroid Build Coastguard Worker bool Unzip(const base::PlatformFile& zip_file, 205*86ee64e7SAndroid Build Coastguard Worker WriterFactory writer_factory, 206*86ee64e7SAndroid Build Coastguard Worker DirectoryCreator directory_creator, 207*86ee64e7SAndroid Build Coastguard Worker UnzipOptions options = {}); 208*86ee64e7SAndroid Build Coastguard Worker 209*86ee64e7SAndroid Build Coastguard Worker // Unzips the contents of |zip_file| into |dest_dir|. 210*86ee64e7SAndroid Build Coastguard Worker // This function does not overwrite any existing file. 211*86ee64e7SAndroid Build Coastguard Worker // A filename collision will result in an error. 212*86ee64e7SAndroid Build Coastguard Worker // Therefore, |dest_dir| should initially be an empty directory. 213*86ee64e7SAndroid Build Coastguard Worker bool Unzip(const base::FilePath& zip_file, 214*86ee64e7SAndroid Build Coastguard Worker const base::FilePath& dest_dir, 215*86ee64e7SAndroid Build Coastguard Worker UnzipOptions options = {}); 216*86ee64e7SAndroid Build Coastguard Worker 217*86ee64e7SAndroid Build Coastguard Worker } // namespace zip 218*86ee64e7SAndroid Build Coastguard Worker 219*86ee64e7SAndroid Build Coastguard Worker #endif // THIRD_PARTY_ZLIB_GOOGLE_ZIP_H_ 220