• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 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_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)
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();
48 
49   // Sets the optional progress callback. The callback is called once for each
50   // time |period|. The final callback is always called when the ZIP operation
51   // completes.
SetProgressCallback(ProgressCallback callback,base::TimeDelta period)52   void SetProgressCallback(ProgressCallback callback, base::TimeDelta period) {
53     progress_callback_ = std::move(callback);
54     progress_period_ = std::move(period);
55   }
56 
57   // Sets the recursive flag, indicating whether the contents of subdirectories
58   // should be included.
SetRecursive(bool b)59   void SetRecursive(bool b) { recursive_ = b; }
60 
61   // Sets the filter callback.
SetFilterCallback(FilterCallback callback)62   void SetFilterCallback(FilterCallback callback) {
63     filter_callback_ = std::move(callback);
64   }
65 
66   // Adds the contents of a directory. If the recursive flag is set, the
67   // contents of subdirectories are also added.
68   bool AddDirectoryContents(const base::FilePath& path);
69 
70   // Adds the entries at |paths| to the ZIP file. These can be a mixed bag of
71   // files and directories. If the recursive flag is set, the contents of
72   // subdirectories is also added.
73   bool AddMixedEntries(Paths paths);
74 
75   // Closes the ZIP file.
76   bool Close();
77 
78  private:
79   // Takes ownership of |zip_file|.
80   ZipWriter(zipFile zip_file, FileAccessor* file_accessor);
81 
82   // Regularly called during processing to check whether zipping should continue
83   // or should be cancelled.
84   bool ShouldContinue();
85 
86   // Adds file content to currently open file entry.
87   bool AddFileContent(const base::FilePath& path, base::File file);
88 
89   // Adds a file entry (including file contents).
90   bool AddFileEntry(const base::FilePath& path, base::File file);
91 
92   // Adds file entries. All the paths should be existing files.
93   bool AddFileEntries(Paths paths);
94 
95   // Adds a directory entry. If the recursive flag is set, the contents of this
96   // directory are also added.
97   bool AddDirectoryEntry(const base::FilePath& path);
98 
99   // Adds directory entries. All the paths should be existing directories. If
100   // the recursive flag is set, the contents of these directories are also
101   // added.
102   bool AddDirectoryEntries(Paths paths);
103 
104   // Opens a file or directory entry.
105   bool OpenNewFileEntry(const base::FilePath& path,
106                         bool is_directory,
107                         base::Time last_modified);
108 
109   // Closes the currently open entry.
110   bool CloseNewFileEntry();
111 
112   // Filters entries.
113   void Filter(std::vector<base::FilePath>* paths);
114 
115   // The actual zip file.
116   zipFile zip_file_;
117 
118   // Abstraction over file access methods used to read files.
119   FileAccessor* const file_accessor_;
120 
121   // Progress stats.
122   Progress progress_;
123 
124   // Optional progress callback.
125   ProgressCallback progress_callback_;
126 
127   // Optional progress reporting period.
128   base::TimeDelta progress_period_;
129 
130   // Next time to report progress.
131   base::TimeTicks next_progress_report_time_ = base::TimeTicks::Now();
132 
133   // Filter used to exclude files from the ZIP file.
134   FilterCallback filter_callback_;
135 
136   // Should recursively add directories?
137   bool recursive_ = false;
138 
139   DISALLOW_COPY_AND_ASSIGN(ZipWriter);
140 };
141 
142 }  // namespace internal
143 }  // namespace zip
144 
145 #endif  // THIRD_PARTY_ZLIB_GOOGLE_ZIP_WRITER_H_
146