• 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 <vector>
9 
10 #include "base/callback.h"
11 #include "base/files/file_path.h"
12 #include "base/files/platform_file.h"
13 #include "base/time/time.h"
14 #include "build/build_config.h"
15 
16 namespace base {
17 class File;
18 }
19 
20 namespace zip {
21 
22 class WriterDelegate;
23 
24 // Abstraction for file access operation required by Zip().
25 // Can be passed to the ZipParams for providing custom access to the files,
26 // for example over IPC.
27 // If none is provided, the files are accessed directly.
28 // All parameters paths are expected to be absolute.
29 class FileAccessor {
30  public:
31   virtual ~FileAccessor() = default;
32 
33   struct DirectoryContentEntry {
DirectoryContentEntryDirectoryContentEntry34     DirectoryContentEntry(const base::FilePath& path, bool is_directory)
35         : path(path), is_directory(is_directory) {}
36     base::FilePath path;
37     bool is_directory = false;
38   };
39 
40   // Opens files specified in |paths|.
41   // Directories should be mapped to invalid files.
42   virtual std::vector<base::File> OpenFilesForReading(
43       const std::vector<base::FilePath>& paths) = 0;
44 
45   virtual bool DirectoryExists(const base::FilePath& path) = 0;
46   virtual std::vector<DirectoryContentEntry> ListDirectoryContent(
47       const base::FilePath& dir_path) = 0;
48   virtual base::Time GetLastModifiedTime(const base::FilePath& path) = 0;
49 };
50 
51 class ZipParams {
52  public:
53   ZipParams(const base::FilePath& src_dir, const base::FilePath& dest_file);
54 #if defined(OS_POSIX)
55   // Does not take ownership of |dest_fd|.
56   ZipParams(const base::FilePath& src_dir, int dest_fd);
57 
dest_fd()58   int dest_fd() const { return dest_fd_; }
59 #endif
60 
src_dir()61   const base::FilePath& src_dir() const { return src_dir_; }
62 
dest_file()63   const base::FilePath& dest_file() const { return dest_file_; }
64 
65   // Restricts the files actually zipped to the paths listed in
66   // |src_relative_paths|. They must be relative to the |src_dir| passed in the
67   // constructor and will be used as the file names in the created zip file. All
68   // source paths must be under |src_dir| in the file system hierarchy.
set_files_to_zip(const std::vector<base::FilePath> & src_relative_paths)69   void set_files_to_zip(const std::vector<base::FilePath>& src_relative_paths) {
70     src_files_ = src_relative_paths;
71   }
files_to_zip()72   const std::vector<base::FilePath>& files_to_zip() const { return src_files_; }
73 
74   using FilterCallback = base::RepeatingCallback<bool(const base::FilePath&)>;
set_filter_callback(FilterCallback filter_callback)75   void set_filter_callback(FilterCallback filter_callback) {
76     filter_callback_ = filter_callback;
77   }
filter_callback()78   const FilterCallback& filter_callback() const { return filter_callback_; }
79 
set_include_hidden_files(bool include_hidden_files)80   void set_include_hidden_files(bool include_hidden_files) {
81     include_hidden_files_ = include_hidden_files;
82   }
include_hidden_files()83   bool include_hidden_files() const { return include_hidden_files_; }
84 
85   // Sets a custom file accessor for file operations. Default is to directly
86   // access the files (with fopen and the rest).
87   // Useful in cases where running in a sandbox process and file access has to
88   // go through IPC, for example.
set_file_accessor(std::unique_ptr<FileAccessor> file_accessor)89   void set_file_accessor(std::unique_ptr<FileAccessor> file_accessor) {
90     file_accessor_ = std::move(file_accessor);
91   }
file_accessor()92   FileAccessor* file_accessor() const { return file_accessor_.get(); }
93 
94  private:
95   base::FilePath src_dir_;
96 
97   base::FilePath dest_file_;
98 #if defined(OS_POSIX)
99   int dest_fd_ = base::kInvalidPlatformFile;
100 #endif
101 
102   // The relative paths to the files that should be included in the zip file. If
103   // this is empty, all files in |src_dir_| are included.
104   std::vector<base::FilePath> src_files_;
105 
106   // Filter used to exclude files from the ZIP file. Only effective when
107   // |src_files_| is empty.
108   FilterCallback filter_callback_;
109 
110   // Whether hidden files should be included in the ZIP file. Only effective
111   // when |src_files_| is empty.
112   bool include_hidden_files_ = true;
113 
114   // Abstraction around file system access used to read files. An implementation
115   // that accesses files directly is provided by default.
116   std::unique_ptr<FileAccessor> file_accessor_;
117 };
118 
119 // Zip files specified into a ZIP archives. The source files and ZIP destination
120 // files (as well as other settings) are specified in |params|.
121 bool Zip(const ZipParams& params);
122 
123 // Zip the contents of src_dir into dest_file. src_path must be a directory.
124 // An entry will *not* be created in the zip for the root folder -- children
125 // of src_dir will be at the root level of the created zip. For each file in
126 // src_dir, include it only if the callback |filter_cb| returns true. Otherwise
127 // omit it.
128 using FilterCallback = base::RepeatingCallback<bool(const base::FilePath&)>;
129 bool ZipWithFilterCallback(const base::FilePath& src_dir,
130                            const base::FilePath& dest_file,
131                            const FilterCallback& filter_cb);
132 
133 // Convenience method for callers who don't need to set up the filter callback.
134 // If |include_hidden_files| is true, files starting with "." are included.
135 // Otherwise they are omitted.
136 bool Zip(const base::FilePath& src_dir, const base::FilePath& dest_file,
137          bool include_hidden_files);
138 
139 #if defined(OS_POSIX)
140 // Zips files listed in |src_relative_paths| to destination specified by file
141 // descriptor |dest_fd|, without taking ownership of |dest_fd|. The paths listed
142 // in |src_relative_paths| are relative to the |src_dir| and will be used as the
143 // file names in the created zip file. All source paths must be under |src_dir|
144 // in the file system hierarchy.
145 bool ZipFiles(const base::FilePath& src_dir,
146               const std::vector<base::FilePath>& src_relative_paths,
147               int dest_fd);
148 #endif  // defined(OS_POSIX)
149 
150 // Unzip the contents of zip_file into dest_dir.
151 // For each file in zip_file, include it only if the callback |filter_cb|
152 // returns true. Otherwise omit it.
153 // If |log_skipped_files| is true, files skipped during extraction are printed
154 // to debug log.
155 using FilterCallback = base::RepeatingCallback<bool(const base::FilePath&)>;
156 bool UnzipWithFilterCallback(const base::FilePath& zip_file,
157                              const base::FilePath& dest_dir,
158                              const FilterCallback& filter_cb,
159                              bool log_skipped_files);
160 
161 // Unzip the contents of zip_file, using the writers provided by writer_factory.
162 // For each file in zip_file, include it only if the callback |filter_cb|
163 // returns true. Otherwise omit it.
164 // If |log_skipped_files| is true, files skipped during extraction are printed
165 // to debug log.
166 typedef base::RepeatingCallback<std::unique_ptr<WriterDelegate>(
167     const base::FilePath&)>
168     WriterFactory;
169 typedef base::RepeatingCallback<bool(const base::FilePath&)> DirectoryCreator;
170 bool UnzipWithFilterAndWriters(const base::PlatformFile& zip_file,
171                                const WriterFactory& writer_factory,
172                                const DirectoryCreator& directory_creator,
173                                const FilterCallback& filter_cb,
174                                bool log_skipped_files);
175 
176 // Unzip the contents of zip_file into dest_dir.
177 bool Unzip(const base::FilePath& zip_file, const base::FilePath& dest_dir);
178 
179 }  // namespace zip
180 
181 #endif  // THIRD_PARTY_ZLIB_GOOGLE_ZIP_H_
182