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 73 // Prints Progress to output stream. 74 std::ostream& operator<<(std::ostream& out, const Progress& progress); 75 76 // Callback reporting the progress of a ZIP creation operation. 77 // 78 // This callback returns a boolean indicating whether the ZIP creation operation 79 // should continue. If it returns false once, then the ZIP creation operation is 80 // immediately cancelled and the callback won't be called again. 81 using ProgressCallback = base::RepeatingCallback<bool(const Progress&)>; 82 83 using FilterCallback = base::RepeatingCallback<bool(const base::FilePath&)>; 84 85 // ZIP creation parameters and options. 86 struct ZipParams { 87 // Source directory. Ignored if |file_accessor| is set. 88 base::FilePath src_dir; 89 90 // Abstraction around file system access used to read files. 91 // If left null, an implementation that accesses files directly is used. 92 FileAccessor* file_accessor = nullptr; // Not owned 93 94 // Destination file path. 95 // Either dest_file or dest_fd should be set, but not both. 96 base::FilePath dest_file; 97 98 #if defined(OS_POSIX) 99 // Destination file passed a file descriptor. 100 // Either dest_file or dest_fd should be set, but not both. 101 int dest_fd = base::kInvalidPlatformFile; 102 #endif 103 104 // The relative paths to the files and directories that should be included in 105 // the ZIP file. If this is empty, the whole contents of |src_dir| are 106 // included. 107 // 108 // These paths must be relative to |src_dir| and will be used as the file 109 // names in the created ZIP file. All files must be under |src_dir| in the 110 // file system hierarchy. 111 // 112 // All the paths in |src_files| are included in the created ZIP file, 113 // irrespective of |include_hidden_files| and |filter_callback|. 114 Paths src_files; 115 116 // Filter used to exclude files from the ZIP file. This is only taken in 117 // account when recursively adding subdirectory contents. 118 FilterCallback filter_callback; 119 120 // Optional progress reporting callback. 121 ProgressCallback progress_callback; 122 123 // Progress reporting period. The final callback is always called when the ZIP 124 // creation operation completes. 125 base::TimeDelta progress_period; 126 127 // Should add hidden files? This is only taken in account when recursively 128 // adding subdirectory contents. 129 bool include_hidden_files = true; 130 131 // Should recursively add subdirectory contents? 132 bool recursive = false; 133 }; 134 135 // Zip files specified into a ZIP archives. The source files and ZIP destination 136 // files (as well as other settings) are specified in |params|. 137 bool Zip(const ZipParams& params); 138 139 // Zip the contents of src_dir into dest_file. src_path must be a directory. 140 // An entry will *not* be created in the zip for the root folder -- children 141 // of src_dir will be at the root level of the created zip. For each file in 142 // src_dir, include it only if the callback |filter_cb| returns true. Otherwise 143 // omit it. 144 bool ZipWithFilterCallback(const base::FilePath& src_dir, 145 const base::FilePath& dest_file, 146 FilterCallback filter_cb); 147 148 // Convenience method for callers who don't need to set up the filter callback. 149 // If |include_hidden_files| is true, files starting with "." are included. 150 // Otherwise they are omitted. 151 bool Zip(const base::FilePath& src_dir, 152 const base::FilePath& dest_file, 153 bool include_hidden_files); 154 155 #if defined(OS_POSIX) 156 // Zips files listed in |src_relative_paths| to destination specified by file 157 // descriptor |dest_fd|, without taking ownership of |dest_fd|. The paths listed 158 // in |src_relative_paths| are relative to the |src_dir| and will be used as the 159 // file names in the created zip file. All source paths must be under |src_dir| 160 // in the file system hierarchy. 161 bool ZipFiles(const base::FilePath& src_dir, 162 Paths src_relative_paths, 163 int dest_fd); 164 #endif // defined(OS_POSIX) 165 166 // Unzip the contents of zip_file into dest_dir. 167 // For each file in zip_file, include it only if the callback |filter_cb| 168 // returns true. Otherwise omit it. 169 // If |log_skipped_files| is true, files skipped during extraction are printed 170 // to debug log. 171 bool UnzipWithFilterCallback(const base::FilePath& zip_file, 172 const base::FilePath& dest_dir, 173 FilterCallback filter_cb, 174 bool log_skipped_files); 175 176 // Unzip the contents of zip_file, using the writers provided by writer_factory. 177 // For each file in zip_file, include it only if the callback |filter_cb| 178 // returns true. Otherwise omit it. 179 // If |log_skipped_files| is true, files skipped during extraction are printed 180 // to debug log. 181 typedef base::RepeatingCallback<std::unique_ptr<WriterDelegate>( 182 const base::FilePath&)> 183 WriterFactory; 184 typedef base::RepeatingCallback<bool(const base::FilePath&)> DirectoryCreator; 185 bool UnzipWithFilterAndWriters(const base::PlatformFile& zip_file, 186 WriterFactory writer_factory, 187 DirectoryCreator directory_creator, 188 FilterCallback filter_cb, 189 bool log_skipped_files); 190 191 // Unzip the contents of zip_file into dest_dir. 192 bool Unzip(const base::FilePath& zip_file, const base::FilePath& dest_dir); 193 194 } // namespace zip 195 196 #endif // THIRD_PARTY_ZLIB_GOOGLE_ZIP_H_ 197