• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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