xref: /aosp_15_r20/external/zlib/google/zip_writer.cc (revision 86ee64e75fa5f8bce2c8c356138035642429cd05)
1*86ee64e7SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors
2*86ee64e7SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*86ee64e7SAndroid Build Coastguard Worker // found in the LICENSE file.
4*86ee64e7SAndroid Build Coastguard Worker 
5*86ee64e7SAndroid Build Coastguard Worker #include "third_party/zlib/google/zip_writer.h"
6*86ee64e7SAndroid Build Coastguard Worker 
7*86ee64e7SAndroid Build Coastguard Worker #include <algorithm>
8*86ee64e7SAndroid Build Coastguard Worker 
9*86ee64e7SAndroid Build Coastguard Worker #include "base/files/file.h"
10*86ee64e7SAndroid Build Coastguard Worker #include "base/logging.h"
11*86ee64e7SAndroid Build Coastguard Worker #include "base/strings/strcat.h"
12*86ee64e7SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
13*86ee64e7SAndroid Build Coastguard Worker #include "third_party/zlib/google/redact.h"
14*86ee64e7SAndroid Build Coastguard Worker #include "third_party/zlib/google/zip_internal.h"
15*86ee64e7SAndroid Build Coastguard Worker 
16*86ee64e7SAndroid Build Coastguard Worker namespace zip {
17*86ee64e7SAndroid Build Coastguard Worker namespace internal {
18*86ee64e7SAndroid Build Coastguard Worker 
ShouldContinue()19*86ee64e7SAndroid Build Coastguard Worker bool ZipWriter::ShouldContinue() {
20*86ee64e7SAndroid Build Coastguard Worker   if (!progress_callback_)
21*86ee64e7SAndroid Build Coastguard Worker     return true;
22*86ee64e7SAndroid Build Coastguard Worker 
23*86ee64e7SAndroid Build Coastguard Worker   const base::TimeTicks now = base::TimeTicks::Now();
24*86ee64e7SAndroid Build Coastguard Worker   if (next_progress_report_time_ > now)
25*86ee64e7SAndroid Build Coastguard Worker     return true;
26*86ee64e7SAndroid Build Coastguard Worker 
27*86ee64e7SAndroid Build Coastguard Worker   next_progress_report_time_ = now + progress_period_;
28*86ee64e7SAndroid Build Coastguard Worker   if (progress_callback_.Run(progress_))
29*86ee64e7SAndroid Build Coastguard Worker     return true;
30*86ee64e7SAndroid Build Coastguard Worker 
31*86ee64e7SAndroid Build Coastguard Worker   LOG(ERROR) << "Cancelling ZIP creation";
32*86ee64e7SAndroid Build Coastguard Worker   return false;
33*86ee64e7SAndroid Build Coastguard Worker }
34*86ee64e7SAndroid Build Coastguard Worker 
AddFileContent(const base::FilePath & path,base::File file)35*86ee64e7SAndroid Build Coastguard Worker bool ZipWriter::AddFileContent(const base::FilePath& path, base::File file) {
36*86ee64e7SAndroid Build Coastguard Worker   char buf[zip::internal::kZipBufSize];
37*86ee64e7SAndroid Build Coastguard Worker 
38*86ee64e7SAndroid Build Coastguard Worker   while (ShouldContinue()) {
39*86ee64e7SAndroid Build Coastguard Worker     const int num_bytes =
40*86ee64e7SAndroid Build Coastguard Worker         file.ReadAtCurrentPos(buf, zip::internal::kZipBufSize);
41*86ee64e7SAndroid Build Coastguard Worker 
42*86ee64e7SAndroid Build Coastguard Worker     if (num_bytes < 0) {
43*86ee64e7SAndroid Build Coastguard Worker       PLOG(ERROR) << "Cannot read file " << Redact(path);
44*86ee64e7SAndroid Build Coastguard Worker       return false;
45*86ee64e7SAndroid Build Coastguard Worker     }
46*86ee64e7SAndroid Build Coastguard Worker 
47*86ee64e7SAndroid Build Coastguard Worker     if (num_bytes == 0)
48*86ee64e7SAndroid Build Coastguard Worker       return true;
49*86ee64e7SAndroid Build Coastguard Worker 
50*86ee64e7SAndroid Build Coastguard Worker     if (zipWriteInFileInZip(zip_file_, buf, num_bytes) != ZIP_OK) {
51*86ee64e7SAndroid Build Coastguard Worker       PLOG(ERROR) << "Cannot write data from file " << Redact(path)
52*86ee64e7SAndroid Build Coastguard Worker                   << " to ZIP";
53*86ee64e7SAndroid Build Coastguard Worker       return false;
54*86ee64e7SAndroid Build Coastguard Worker     }
55*86ee64e7SAndroid Build Coastguard Worker 
56*86ee64e7SAndroid Build Coastguard Worker     progress_.bytes += num_bytes;
57*86ee64e7SAndroid Build Coastguard Worker   }
58*86ee64e7SAndroid Build Coastguard Worker 
59*86ee64e7SAndroid Build Coastguard Worker   return false;
60*86ee64e7SAndroid Build Coastguard Worker }
61*86ee64e7SAndroid Build Coastguard Worker 
OpenNewFileEntry(const base::FilePath & path,bool is_directory,base::Time last_modified)62*86ee64e7SAndroid Build Coastguard Worker bool ZipWriter::OpenNewFileEntry(const base::FilePath& path,
63*86ee64e7SAndroid Build Coastguard Worker                                  bool is_directory,
64*86ee64e7SAndroid Build Coastguard Worker                                  base::Time last_modified) {
65*86ee64e7SAndroid Build Coastguard Worker   std::string str_path = path.AsUTF8Unsafe();
66*86ee64e7SAndroid Build Coastguard Worker 
67*86ee64e7SAndroid Build Coastguard Worker #if defined(OS_WIN)
68*86ee64e7SAndroid Build Coastguard Worker   base::ReplaceSubstringsAfterOffset(&str_path, 0u, "\\", "/");
69*86ee64e7SAndroid Build Coastguard Worker #endif
70*86ee64e7SAndroid Build Coastguard Worker 
71*86ee64e7SAndroid Build Coastguard Worker   Compression compression = kDeflated;
72*86ee64e7SAndroid Build Coastguard Worker 
73*86ee64e7SAndroid Build Coastguard Worker   if (is_directory) {
74*86ee64e7SAndroid Build Coastguard Worker     str_path += "/";
75*86ee64e7SAndroid Build Coastguard Worker   } else {
76*86ee64e7SAndroid Build Coastguard Worker     compression = GetCompressionMethod(path);
77*86ee64e7SAndroid Build Coastguard Worker   }
78*86ee64e7SAndroid Build Coastguard Worker 
79*86ee64e7SAndroid Build Coastguard Worker   return zip::internal::ZipOpenNewFileInZip(zip_file_, str_path, last_modified,
80*86ee64e7SAndroid Build Coastguard Worker                                             compression);
81*86ee64e7SAndroid Build Coastguard Worker }
82*86ee64e7SAndroid Build Coastguard Worker 
CloseNewFileEntry()83*86ee64e7SAndroid Build Coastguard Worker bool ZipWriter::CloseNewFileEntry() {
84*86ee64e7SAndroid Build Coastguard Worker   return zipCloseFileInZip(zip_file_) == ZIP_OK;
85*86ee64e7SAndroid Build Coastguard Worker }
86*86ee64e7SAndroid Build Coastguard Worker 
AddFileEntry(const base::FilePath & path,base::File file)87*86ee64e7SAndroid Build Coastguard Worker bool ZipWriter::AddFileEntry(const base::FilePath& path, base::File file) {
88*86ee64e7SAndroid Build Coastguard Worker   base::File::Info info;
89*86ee64e7SAndroid Build Coastguard Worker   if (!file.GetInfo(&info))
90*86ee64e7SAndroid Build Coastguard Worker     return false;
91*86ee64e7SAndroid Build Coastguard Worker 
92*86ee64e7SAndroid Build Coastguard Worker   if (!OpenNewFileEntry(path, /*is_directory=*/false, info.last_modified))
93*86ee64e7SAndroid Build Coastguard Worker     return false;
94*86ee64e7SAndroid Build Coastguard Worker 
95*86ee64e7SAndroid Build Coastguard Worker   if (!AddFileContent(path, std::move(file)))
96*86ee64e7SAndroid Build Coastguard Worker     return false;
97*86ee64e7SAndroid Build Coastguard Worker 
98*86ee64e7SAndroid Build Coastguard Worker   progress_.files++;
99*86ee64e7SAndroid Build Coastguard Worker   return CloseNewFileEntry();
100*86ee64e7SAndroid Build Coastguard Worker }
101*86ee64e7SAndroid Build Coastguard Worker 
AddDirectoryEntry(const base::FilePath & path)102*86ee64e7SAndroid Build Coastguard Worker bool ZipWriter::AddDirectoryEntry(const base::FilePath& path) {
103*86ee64e7SAndroid Build Coastguard Worker   FileAccessor::Info info;
104*86ee64e7SAndroid Build Coastguard Worker   if (!file_accessor_->GetInfo(path, &info) || !info.is_directory) {
105*86ee64e7SAndroid Build Coastguard Worker     LOG(ERROR) << "Not a directory: " << Redact(path);
106*86ee64e7SAndroid Build Coastguard Worker     progress_.errors++;
107*86ee64e7SAndroid Build Coastguard Worker     return continue_on_error_;
108*86ee64e7SAndroid Build Coastguard Worker   }
109*86ee64e7SAndroid Build Coastguard Worker 
110*86ee64e7SAndroid Build Coastguard Worker   if (!OpenNewFileEntry(path, /*is_directory=*/true, info.last_modified))
111*86ee64e7SAndroid Build Coastguard Worker     return false;
112*86ee64e7SAndroid Build Coastguard Worker 
113*86ee64e7SAndroid Build Coastguard Worker   if (!CloseNewFileEntry())
114*86ee64e7SAndroid Build Coastguard Worker     return false;
115*86ee64e7SAndroid Build Coastguard Worker 
116*86ee64e7SAndroid Build Coastguard Worker   progress_.directories++;
117*86ee64e7SAndroid Build Coastguard Worker   if (!ShouldContinue())
118*86ee64e7SAndroid Build Coastguard Worker     return false;
119*86ee64e7SAndroid Build Coastguard Worker 
120*86ee64e7SAndroid Build Coastguard Worker   if (!recursive_)
121*86ee64e7SAndroid Build Coastguard Worker     return true;
122*86ee64e7SAndroid Build Coastguard Worker 
123*86ee64e7SAndroid Build Coastguard Worker   return AddDirectoryContents(path);
124*86ee64e7SAndroid Build Coastguard Worker }
125*86ee64e7SAndroid Build Coastguard Worker 
126*86ee64e7SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA)
127*86ee64e7SAndroid Build Coastguard Worker // static
CreateWithFd(int zip_file_fd,FileAccessor * file_accessor)128*86ee64e7SAndroid Build Coastguard Worker std::unique_ptr<ZipWriter> ZipWriter::CreateWithFd(
129*86ee64e7SAndroid Build Coastguard Worker     int zip_file_fd,
130*86ee64e7SAndroid Build Coastguard Worker     FileAccessor* file_accessor) {
131*86ee64e7SAndroid Build Coastguard Worker   DCHECK(zip_file_fd != base::kInvalidPlatformFile);
132*86ee64e7SAndroid Build Coastguard Worker   zipFile zip_file =
133*86ee64e7SAndroid Build Coastguard Worker       internal::OpenFdForZipping(zip_file_fd, APPEND_STATUS_CREATE);
134*86ee64e7SAndroid Build Coastguard Worker 
135*86ee64e7SAndroid Build Coastguard Worker   if (!zip_file) {
136*86ee64e7SAndroid Build Coastguard Worker     DLOG(ERROR) << "Cannot create ZIP file for FD " << zip_file_fd;
137*86ee64e7SAndroid Build Coastguard Worker     return nullptr;
138*86ee64e7SAndroid Build Coastguard Worker   }
139*86ee64e7SAndroid Build Coastguard Worker 
140*86ee64e7SAndroid Build Coastguard Worker   return std::unique_ptr<ZipWriter>(new ZipWriter(zip_file, file_accessor));
141*86ee64e7SAndroid Build Coastguard Worker }
142*86ee64e7SAndroid Build Coastguard Worker #endif
143*86ee64e7SAndroid Build Coastguard Worker 
144*86ee64e7SAndroid Build Coastguard Worker // static
Create(const base::FilePath & zip_file_path,FileAccessor * file_accessor)145*86ee64e7SAndroid Build Coastguard Worker std::unique_ptr<ZipWriter> ZipWriter::Create(
146*86ee64e7SAndroid Build Coastguard Worker     const base::FilePath& zip_file_path,
147*86ee64e7SAndroid Build Coastguard Worker     FileAccessor* file_accessor) {
148*86ee64e7SAndroid Build Coastguard Worker   DCHECK(!zip_file_path.empty());
149*86ee64e7SAndroid Build Coastguard Worker   zipFile zip_file = internal::OpenForZipping(zip_file_path.AsUTF8Unsafe(),
150*86ee64e7SAndroid Build Coastguard Worker                                               APPEND_STATUS_CREATE);
151*86ee64e7SAndroid Build Coastguard Worker 
152*86ee64e7SAndroid Build Coastguard Worker   if (!zip_file) {
153*86ee64e7SAndroid Build Coastguard Worker     PLOG(ERROR) << "Cannot create ZIP file " << Redact(zip_file_path);
154*86ee64e7SAndroid Build Coastguard Worker     return nullptr;
155*86ee64e7SAndroid Build Coastguard Worker   }
156*86ee64e7SAndroid Build Coastguard Worker 
157*86ee64e7SAndroid Build Coastguard Worker   return std::unique_ptr<ZipWriter>(new ZipWriter(zip_file, file_accessor));
158*86ee64e7SAndroid Build Coastguard Worker }
159*86ee64e7SAndroid Build Coastguard Worker 
ZipWriter(zipFile zip_file,FileAccessor * file_accessor)160*86ee64e7SAndroid Build Coastguard Worker ZipWriter::ZipWriter(zipFile zip_file, FileAccessor* file_accessor)
161*86ee64e7SAndroid Build Coastguard Worker     : zip_file_(zip_file), file_accessor_(file_accessor) {}
162*86ee64e7SAndroid Build Coastguard Worker 
~ZipWriter()163*86ee64e7SAndroid Build Coastguard Worker ZipWriter::~ZipWriter() {
164*86ee64e7SAndroid Build Coastguard Worker   if (zip_file_)
165*86ee64e7SAndroid Build Coastguard Worker     zipClose(zip_file_, nullptr);
166*86ee64e7SAndroid Build Coastguard Worker }
167*86ee64e7SAndroid Build Coastguard Worker 
Close()168*86ee64e7SAndroid Build Coastguard Worker bool ZipWriter::Close() {
169*86ee64e7SAndroid Build Coastguard Worker   const bool success = zipClose(zip_file_, nullptr) == ZIP_OK;
170*86ee64e7SAndroid Build Coastguard Worker   zip_file_ = nullptr;
171*86ee64e7SAndroid Build Coastguard Worker 
172*86ee64e7SAndroid Build Coastguard Worker   // Call the progress callback one last time with the final progress status.
173*86ee64e7SAndroid Build Coastguard Worker   if (progress_callback_ && !progress_callback_.Run(progress_)) {
174*86ee64e7SAndroid Build Coastguard Worker     LOG(ERROR) << "Cancelling ZIP creation at the end";
175*86ee64e7SAndroid Build Coastguard Worker     return false;
176*86ee64e7SAndroid Build Coastguard Worker   }
177*86ee64e7SAndroid Build Coastguard Worker 
178*86ee64e7SAndroid Build Coastguard Worker   return success;
179*86ee64e7SAndroid Build Coastguard Worker }
180*86ee64e7SAndroid Build Coastguard Worker 
AddMixedEntries(Paths paths)181*86ee64e7SAndroid Build Coastguard Worker bool ZipWriter::AddMixedEntries(Paths paths) {
182*86ee64e7SAndroid Build Coastguard Worker   // Pointers to directory paths in |paths|.
183*86ee64e7SAndroid Build Coastguard Worker   std::vector<const base::FilePath*> directories;
184*86ee64e7SAndroid Build Coastguard Worker 
185*86ee64e7SAndroid Build Coastguard Worker   // Declared outside loop to reuse internal buffer.
186*86ee64e7SAndroid Build Coastguard Worker   std::vector<base::File> files;
187*86ee64e7SAndroid Build Coastguard Worker 
188*86ee64e7SAndroid Build Coastguard Worker   // First pass. We don't know which paths are files and which ones are
189*86ee64e7SAndroid Build Coastguard Worker   // directories, and we want to avoid making a call to file_accessor_ for each
190*86ee64e7SAndroid Build Coastguard Worker   // path. Try to open all of the paths as files. We'll get invalid file
191*86ee64e7SAndroid Build Coastguard Worker   // descriptors for directories, and we'll process these directories in the
192*86ee64e7SAndroid Build Coastguard Worker   // second pass.
193*86ee64e7SAndroid Build Coastguard Worker   while (!paths.empty()) {
194*86ee64e7SAndroid Build Coastguard Worker     // Work with chunks of 50 paths at most.
195*86ee64e7SAndroid Build Coastguard Worker     const size_t n = std::min<size_t>(paths.size(), 50);
196*86ee64e7SAndroid Build Coastguard Worker     const Paths relative_paths = paths.subspan(0, n);
197*86ee64e7SAndroid Build Coastguard Worker     paths = paths.subspan(n, paths.size() - n);
198*86ee64e7SAndroid Build Coastguard Worker 
199*86ee64e7SAndroid Build Coastguard Worker     files.clear();
200*86ee64e7SAndroid Build Coastguard Worker     if (!file_accessor_->Open(relative_paths, &files) || files.size() != n)
201*86ee64e7SAndroid Build Coastguard Worker       return false;
202*86ee64e7SAndroid Build Coastguard Worker 
203*86ee64e7SAndroid Build Coastguard Worker     for (size_t i = 0; i < n; i++) {
204*86ee64e7SAndroid Build Coastguard Worker       const base::FilePath& relative_path = relative_paths[i];
205*86ee64e7SAndroid Build Coastguard Worker       DCHECK(!relative_path.empty());
206*86ee64e7SAndroid Build Coastguard Worker       base::File& file = files[i];
207*86ee64e7SAndroid Build Coastguard Worker 
208*86ee64e7SAndroid Build Coastguard Worker       if (file.IsValid()) {
209*86ee64e7SAndroid Build Coastguard Worker         // It's a file.
210*86ee64e7SAndroid Build Coastguard Worker         if (!AddFileEntry(relative_path, std::move(file)))
211*86ee64e7SAndroid Build Coastguard Worker           return false;
212*86ee64e7SAndroid Build Coastguard Worker       } else {
213*86ee64e7SAndroid Build Coastguard Worker         // It's probably a directory. Remember its path for the second pass.
214*86ee64e7SAndroid Build Coastguard Worker         directories.push_back(&relative_path);
215*86ee64e7SAndroid Build Coastguard Worker       }
216*86ee64e7SAndroid Build Coastguard Worker     }
217*86ee64e7SAndroid Build Coastguard Worker   }
218*86ee64e7SAndroid Build Coastguard Worker 
219*86ee64e7SAndroid Build Coastguard Worker   // Second pass for directories discovered during the first pass.
220*86ee64e7SAndroid Build Coastguard Worker   for (const base::FilePath* const path : directories) {
221*86ee64e7SAndroid Build Coastguard Worker     DCHECK(path);
222*86ee64e7SAndroid Build Coastguard Worker     if (!AddDirectoryEntry(*path))
223*86ee64e7SAndroid Build Coastguard Worker       return false;
224*86ee64e7SAndroid Build Coastguard Worker   }
225*86ee64e7SAndroid Build Coastguard Worker 
226*86ee64e7SAndroid Build Coastguard Worker   return true;
227*86ee64e7SAndroid Build Coastguard Worker }
228*86ee64e7SAndroid Build Coastguard Worker 
AddFileEntries(Paths paths)229*86ee64e7SAndroid Build Coastguard Worker bool ZipWriter::AddFileEntries(Paths paths) {
230*86ee64e7SAndroid Build Coastguard Worker   // Declared outside loop to reuse internal buffer.
231*86ee64e7SAndroid Build Coastguard Worker   std::vector<base::File> files;
232*86ee64e7SAndroid Build Coastguard Worker 
233*86ee64e7SAndroid Build Coastguard Worker   while (!paths.empty()) {
234*86ee64e7SAndroid Build Coastguard Worker     // Work with chunks of 50 paths at most.
235*86ee64e7SAndroid Build Coastguard Worker     const size_t n = std::min<size_t>(paths.size(), 50);
236*86ee64e7SAndroid Build Coastguard Worker     const Paths relative_paths = paths.subspan(0, n);
237*86ee64e7SAndroid Build Coastguard Worker     paths = paths.subspan(n, paths.size() - n);
238*86ee64e7SAndroid Build Coastguard Worker 
239*86ee64e7SAndroid Build Coastguard Worker     DCHECK_EQ(relative_paths.size(), n);
240*86ee64e7SAndroid Build Coastguard Worker 
241*86ee64e7SAndroid Build Coastguard Worker     files.clear();
242*86ee64e7SAndroid Build Coastguard Worker     if (!file_accessor_->Open(relative_paths, &files) || files.size() != n)
243*86ee64e7SAndroid Build Coastguard Worker       return false;
244*86ee64e7SAndroid Build Coastguard Worker 
245*86ee64e7SAndroid Build Coastguard Worker     for (size_t i = 0; i < n; i++) {
246*86ee64e7SAndroid Build Coastguard Worker       const base::FilePath& relative_path = relative_paths[i];
247*86ee64e7SAndroid Build Coastguard Worker       DCHECK(!relative_path.empty());
248*86ee64e7SAndroid Build Coastguard Worker       base::File& file = files[i];
249*86ee64e7SAndroid Build Coastguard Worker 
250*86ee64e7SAndroid Build Coastguard Worker       if (!file.IsValid()) {
251*86ee64e7SAndroid Build Coastguard Worker         LOG(ERROR) << "Cannot open " << Redact(relative_path);
252*86ee64e7SAndroid Build Coastguard Worker         progress_.errors++;
253*86ee64e7SAndroid Build Coastguard Worker 
254*86ee64e7SAndroid Build Coastguard Worker         if (continue_on_error_)
255*86ee64e7SAndroid Build Coastguard Worker           continue;
256*86ee64e7SAndroid Build Coastguard Worker 
257*86ee64e7SAndroid Build Coastguard Worker         return false;
258*86ee64e7SAndroid Build Coastguard Worker       }
259*86ee64e7SAndroid Build Coastguard Worker 
260*86ee64e7SAndroid Build Coastguard Worker       if (!AddFileEntry(relative_path, std::move(file)))
261*86ee64e7SAndroid Build Coastguard Worker         return false;
262*86ee64e7SAndroid Build Coastguard Worker     }
263*86ee64e7SAndroid Build Coastguard Worker   }
264*86ee64e7SAndroid Build Coastguard Worker 
265*86ee64e7SAndroid Build Coastguard Worker   return true;
266*86ee64e7SAndroid Build Coastguard Worker }
267*86ee64e7SAndroid Build Coastguard Worker 
AddDirectoryEntries(Paths paths)268*86ee64e7SAndroid Build Coastguard Worker bool ZipWriter::AddDirectoryEntries(Paths paths) {
269*86ee64e7SAndroid Build Coastguard Worker   for (const base::FilePath& path : paths) {
270*86ee64e7SAndroid Build Coastguard Worker     if (!AddDirectoryEntry(path))
271*86ee64e7SAndroid Build Coastguard Worker       return false;
272*86ee64e7SAndroid Build Coastguard Worker   }
273*86ee64e7SAndroid Build Coastguard Worker 
274*86ee64e7SAndroid Build Coastguard Worker   return true;
275*86ee64e7SAndroid Build Coastguard Worker }
276*86ee64e7SAndroid Build Coastguard Worker 
AddDirectoryContents(const base::FilePath & path)277*86ee64e7SAndroid Build Coastguard Worker bool ZipWriter::AddDirectoryContents(const base::FilePath& path) {
278*86ee64e7SAndroid Build Coastguard Worker   std::vector<base::FilePath> files, subdirs;
279*86ee64e7SAndroid Build Coastguard Worker 
280*86ee64e7SAndroid Build Coastguard Worker   if (!file_accessor_->List(path, &files, &subdirs)) {
281*86ee64e7SAndroid Build Coastguard Worker     progress_.errors++;
282*86ee64e7SAndroid Build Coastguard Worker     return continue_on_error_;
283*86ee64e7SAndroid Build Coastguard Worker   }
284*86ee64e7SAndroid Build Coastguard Worker 
285*86ee64e7SAndroid Build Coastguard Worker   Filter(&files);
286*86ee64e7SAndroid Build Coastguard Worker   Filter(&subdirs);
287*86ee64e7SAndroid Build Coastguard Worker 
288*86ee64e7SAndroid Build Coastguard Worker   if (!AddFileEntries(files))
289*86ee64e7SAndroid Build Coastguard Worker     return false;
290*86ee64e7SAndroid Build Coastguard Worker 
291*86ee64e7SAndroid Build Coastguard Worker   return AddDirectoryEntries(subdirs);
292*86ee64e7SAndroid Build Coastguard Worker }
293*86ee64e7SAndroid Build Coastguard Worker 
Filter(std::vector<base::FilePath> * const paths)294*86ee64e7SAndroid Build Coastguard Worker void ZipWriter::Filter(std::vector<base::FilePath>* const paths) {
295*86ee64e7SAndroid Build Coastguard Worker   DCHECK(paths);
296*86ee64e7SAndroid Build Coastguard Worker 
297*86ee64e7SAndroid Build Coastguard Worker   if (!filter_callback_)
298*86ee64e7SAndroid Build Coastguard Worker     return;
299*86ee64e7SAndroid Build Coastguard Worker 
300*86ee64e7SAndroid Build Coastguard Worker   const auto end = std::remove_if(paths->begin(), paths->end(),
301*86ee64e7SAndroid Build Coastguard Worker                                   [this](const base::FilePath& path) {
302*86ee64e7SAndroid Build Coastguard Worker                                     return !filter_callback_.Run(path);
303*86ee64e7SAndroid Build Coastguard Worker                                   });
304*86ee64e7SAndroid Build Coastguard Worker   paths->erase(end, paths->end());
305*86ee64e7SAndroid Build Coastguard Worker }
306*86ee64e7SAndroid Build Coastguard Worker 
307*86ee64e7SAndroid Build Coastguard Worker }  // namespace internal
308*86ee64e7SAndroid Build Coastguard Worker }  // namespace zip
309