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