xref: /aosp_15_r20/external/zlib/google/zip_writer.h (revision 86ee64e75fa5f8bce2c8c356138035642429cd05)
1 // Copyright 2017 The Chromium Authors
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_WRITER_H_
6 #define THIRD_PARTY_ZLIB_GOOGLE_ZIP_WRITER_H_
7 
8 #include <memory>
9 #include <vector>
10 
11 #include "base/files/file_path.h"
12 #include "base/time/time.h"
13 #include "build/build_config.h"
14 #include "third_party/zlib/google/zip.h"
15 
16 #if defined(USE_SYSTEM_MINIZIP)
17 #include <minizip/unzip.h>
18 #include <minizip/zip.h>
19 #else
20 #include "third_party/zlib/contrib/minizip/unzip.h"
21 #include "third_party/zlib/contrib/minizip/zip.h"
22 #endif
23 
24 namespace zip {
25 namespace internal {
26 
27 // A class used to write entries to a ZIP file and buffering the reading of
28 // files to limit the number of calls to the FileAccessor. This is for
29 // performance reasons as these calls may be expensive when IPC based).
30 // This class is so far internal and only used by zip.cc, but could be made
31 // public if needed.
32 //
33 // All methods returning a bool return true on success and false on error.
34 class ZipWriter {
35  public:
36 // Creates a writer that will write a ZIP file to |zip_file_fd| or |zip_file|
37 // and which entries are relative to |file_accessor|'s source directory.
38 // All file reads are performed using |file_accessor|.
39 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
40   static std::unique_ptr<ZipWriter> CreateWithFd(int zip_file_fd,
41                                                  FileAccessor* file_accessor);
42 #endif
43 
44   static std::unique_ptr<ZipWriter> Create(const base::FilePath& zip_file,
45                                            FileAccessor* file_accessor);
46 
47   ZipWriter(const ZipWriter&) = delete;
48   ZipWriter& operator=(const ZipWriter&) = delete;
49 
50   ~ZipWriter();
51 
52   // Sets the optional progress callback. The callback is called once for each
53   // time |period|. The final callback is always called when the ZIP operation
54   // completes.
SetProgressCallback(ProgressCallback callback,base::TimeDelta period)55   void SetProgressCallback(ProgressCallback callback, base::TimeDelta period) {
56     progress_callback_ = std::move(callback);
57     progress_period_ = std::move(period);
58   }
59 
60   // Should ignore missing files and directories?
ContinueOnError(bool continue_on_error)61   void ContinueOnError(bool continue_on_error) {
62     continue_on_error_ = continue_on_error;
63   }
64 
65   // Sets the recursive flag, indicating whether the contents of subdirectories
66   // should be included.
SetRecursive(bool b)67   void SetRecursive(bool b) { recursive_ = b; }
68 
69   // Sets the filter callback.
SetFilterCallback(FilterCallback callback)70   void SetFilterCallback(FilterCallback callback) {
71     filter_callback_ = std::move(callback);
72   }
73 
74   // Adds the contents of a directory. If the recursive flag is set, the
75   // contents of subdirectories are also added.
76   bool AddDirectoryContents(const base::FilePath& path);
77 
78   // Adds the entries at |paths| to the ZIP file. These can be a mixed bag of
79   // files and directories. If the recursive flag is set, the contents of
80   // subdirectories is also added.
81   bool AddMixedEntries(Paths paths);
82 
83   // Closes the ZIP file.
84   bool Close();
85 
86  private:
87   // Takes ownership of |zip_file|.
88   ZipWriter(zipFile zip_file, FileAccessor* file_accessor);
89 
90   // Regularly called during processing to check whether zipping should continue
91   // or should be cancelled.
92   bool ShouldContinue();
93 
94   // Adds file content to currently open file entry.
95   bool AddFileContent(const base::FilePath& path, base::File file);
96 
97   // Adds a file entry (including file contents).
98   bool AddFileEntry(const base::FilePath& path, base::File file);
99 
100   // Adds file entries. All the paths should be existing files.
101   bool AddFileEntries(Paths paths);
102 
103   // Adds a directory entry. If the recursive flag is set, the contents of this
104   // directory are also added.
105   bool AddDirectoryEntry(const base::FilePath& path);
106 
107   // Adds directory entries. All the paths should be existing directories. If
108   // the recursive flag is set, the contents of these directories are also
109   // added.
110   bool AddDirectoryEntries(Paths paths);
111 
112   // Opens a file or directory entry.
113   bool OpenNewFileEntry(const base::FilePath& path,
114                         bool is_directory,
115                         base::Time last_modified);
116 
117   // Closes the currently open entry.
118   bool CloseNewFileEntry();
119 
120   // Filters entries.
121   void Filter(std::vector<base::FilePath>* paths);
122 
123   // The actual zip file.
124   zipFile zip_file_;
125 
126   // Abstraction over file access methods used to read files.
127   FileAccessor* const file_accessor_;
128 
129   // Progress stats.
130   Progress progress_;
131 
132   // Optional progress callback.
133   ProgressCallback progress_callback_;
134 
135   // Optional progress reporting period.
136   base::TimeDelta progress_period_;
137 
138   // Next time to report progress.
139   base::TimeTicks next_progress_report_time_ = base::TimeTicks::Now();
140 
141   // Filter used to exclude files from the ZIP file.
142   FilterCallback filter_callback_;
143 
144   // Should recursively add directories?
145   bool recursive_ = false;
146 
147   // Should ignore missing files and directories?
148   bool continue_on_error_ = false;
149 };
150 
151 }  // namespace internal
152 }  // namespace zip
153 
154 #endif  // THIRD_PARTY_ZLIB_GOOGLE_ZIP_WRITER_H_
155