1*86ee64e7SAndroid Build Coastguard Worker // Copyright 2011 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 #ifndef THIRD_PARTY_ZLIB_GOOGLE_ZIP_READER_H_ 5*86ee64e7SAndroid Build Coastguard Worker #define THIRD_PARTY_ZLIB_GOOGLE_ZIP_READER_H_ 6*86ee64e7SAndroid Build Coastguard Worker 7*86ee64e7SAndroid Build Coastguard Worker #include <stddef.h> 8*86ee64e7SAndroid Build Coastguard Worker #include <stdint.h> 9*86ee64e7SAndroid Build Coastguard Worker 10*86ee64e7SAndroid Build Coastguard Worker #include <limits> 11*86ee64e7SAndroid Build Coastguard Worker #include <memory> 12*86ee64e7SAndroid Build Coastguard Worker #include <string> 13*86ee64e7SAndroid Build Coastguard Worker 14*86ee64e7SAndroid Build Coastguard Worker #include "base/files/file.h" 15*86ee64e7SAndroid Build Coastguard Worker #include "base/files/file_path.h" 16*86ee64e7SAndroid Build Coastguard Worker #include "base/functional/callback.h" 17*86ee64e7SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h" 18*86ee64e7SAndroid Build Coastguard Worker #include "base/numerics/safe_conversions.h" 19*86ee64e7SAndroid Build Coastguard Worker #include "base/time/time.h" 20*86ee64e7SAndroid Build Coastguard Worker 21*86ee64e7SAndroid Build Coastguard Worker #if defined(USE_SYSTEM_MINIZIP) 22*86ee64e7SAndroid Build Coastguard Worker #include <minizip/unzip.h> 23*86ee64e7SAndroid Build Coastguard Worker #else 24*86ee64e7SAndroid Build Coastguard Worker #include "third_party/zlib/contrib/minizip/unzip.h" 25*86ee64e7SAndroid Build Coastguard Worker #endif 26*86ee64e7SAndroid Build Coastguard Worker 27*86ee64e7SAndroid Build Coastguard Worker namespace zip { 28*86ee64e7SAndroid Build Coastguard Worker 29*86ee64e7SAndroid Build Coastguard Worker // A delegate interface used to stream out an entry; see 30*86ee64e7SAndroid Build Coastguard Worker // ZipReader::ExtractCurrentEntry. 31*86ee64e7SAndroid Build Coastguard Worker class WriterDelegate { 32*86ee64e7SAndroid Build Coastguard Worker public: ~WriterDelegate()33*86ee64e7SAndroid Build Coastguard Worker virtual ~WriterDelegate() {} 34*86ee64e7SAndroid Build Coastguard Worker 35*86ee64e7SAndroid Build Coastguard Worker // Invoked once before any data is streamed out to pave the way (e.g., to open 36*86ee64e7SAndroid Build Coastguard Worker // the output file). Return false on failure to cancel extraction. PrepareOutput()37*86ee64e7SAndroid Build Coastguard Worker virtual bool PrepareOutput() { return true; } 38*86ee64e7SAndroid Build Coastguard Worker 39*86ee64e7SAndroid Build Coastguard Worker // Invoked to write the next chunk of data. Return false on failure to cancel 40*86ee64e7SAndroid Build Coastguard Worker // extraction. WriteBytes(const char * data,int num_bytes)41*86ee64e7SAndroid Build Coastguard Worker virtual bool WriteBytes(const char* data, int num_bytes) { return true; } 42*86ee64e7SAndroid Build Coastguard Worker 43*86ee64e7SAndroid Build Coastguard Worker // Sets the last-modified time of the data. SetTimeModified(const base::Time & time)44*86ee64e7SAndroid Build Coastguard Worker virtual void SetTimeModified(const base::Time& time) {} 45*86ee64e7SAndroid Build Coastguard Worker 46*86ee64e7SAndroid Build Coastguard Worker // Called with the POSIX file permissions of the data; POSIX implementations 47*86ee64e7SAndroid Build Coastguard Worker // may apply some of the permissions (for example, the executable bit) to the 48*86ee64e7SAndroid Build Coastguard Worker // output file. SetPosixFilePermissions(int mode)49*86ee64e7SAndroid Build Coastguard Worker virtual void SetPosixFilePermissions(int mode) {} 50*86ee64e7SAndroid Build Coastguard Worker 51*86ee64e7SAndroid Build Coastguard Worker // Called if an error occurred while extracting the file. The WriterDelegate 52*86ee64e7SAndroid Build Coastguard Worker // can then remove and clean up the partially extracted data. OnError()53*86ee64e7SAndroid Build Coastguard Worker virtual void OnError() {} 54*86ee64e7SAndroid Build Coastguard Worker }; 55*86ee64e7SAndroid Build Coastguard Worker 56*86ee64e7SAndroid Build Coastguard Worker // This class is used for reading ZIP archives. A typical use case of this class 57*86ee64e7SAndroid Build Coastguard Worker // is to scan entries in a ZIP archive and extract them. The code will look 58*86ee64e7SAndroid Build Coastguard Worker // like: 59*86ee64e7SAndroid Build Coastguard Worker // 60*86ee64e7SAndroid Build Coastguard Worker // ZipReader reader; 61*86ee64e7SAndroid Build Coastguard Worker // if (!reader.Open(zip_path)) { 62*86ee64e7SAndroid Build Coastguard Worker // // Cannot open 63*86ee64e7SAndroid Build Coastguard Worker // return; 64*86ee64e7SAndroid Build Coastguard Worker // } 65*86ee64e7SAndroid Build Coastguard Worker // 66*86ee64e7SAndroid Build Coastguard Worker // while (const ZipReader::entry* entry = reader.Next()) { 67*86ee64e7SAndroid Build Coastguard Worker // auto writer = CreateFilePathWriterDelegate(extract_dir, entry->path); 68*86ee64e7SAndroid Build Coastguard Worker // if (!reader.ExtractCurrentEntry(writer)) { 69*86ee64e7SAndroid Build Coastguard Worker // // Cannot extract 70*86ee64e7SAndroid Build Coastguard Worker // return; 71*86ee64e7SAndroid Build Coastguard Worker // } 72*86ee64e7SAndroid Build Coastguard Worker // } 73*86ee64e7SAndroid Build Coastguard Worker // 74*86ee64e7SAndroid Build Coastguard Worker // if (!reader.ok()) { 75*86ee64e7SAndroid Build Coastguard Worker // // Error while enumerating entries 76*86ee64e7SAndroid Build Coastguard Worker // return; 77*86ee64e7SAndroid Build Coastguard Worker // } 78*86ee64e7SAndroid Build Coastguard Worker // 79*86ee64e7SAndroid Build Coastguard Worker class ZipReader { 80*86ee64e7SAndroid Build Coastguard Worker public: 81*86ee64e7SAndroid Build Coastguard Worker // A callback that is called when the operation is successful. 82*86ee64e7SAndroid Build Coastguard Worker using SuccessCallback = base::OnceClosure; 83*86ee64e7SAndroid Build Coastguard Worker // A callback that is called when the operation fails. 84*86ee64e7SAndroid Build Coastguard Worker using FailureCallback = base::OnceClosure; 85*86ee64e7SAndroid Build Coastguard Worker // A callback that is called periodically during the operation with the number 86*86ee64e7SAndroid Build Coastguard Worker // of bytes that have been processed so far. 87*86ee64e7SAndroid Build Coastguard Worker using ProgressCallback = base::RepeatingCallback<void(int64_t)>; 88*86ee64e7SAndroid Build Coastguard Worker // A callback that is called periodically during the operation with the number 89*86ee64e7SAndroid Build Coastguard Worker // of bytes that have been processed since the previous call (i.e. delta). 90*86ee64e7SAndroid Build Coastguard Worker using ListenerCallback = base::RepeatingCallback<void(uint64_t)>; 91*86ee64e7SAndroid Build Coastguard Worker 92*86ee64e7SAndroid Build Coastguard Worker // Information of an entry (file or directory) in a ZIP archive. 93*86ee64e7SAndroid Build Coastguard Worker struct Entry { 94*86ee64e7SAndroid Build Coastguard Worker // Path of this entry, in its original encoding as it is stored in the ZIP 95*86ee64e7SAndroid Build Coastguard Worker // archive. The encoding is not specified here. It might or might not be 96*86ee64e7SAndroid Build Coastguard Worker // UTF-8, and the caller needs to use other means to determine the encoding 97*86ee64e7SAndroid Build Coastguard Worker // if it wants to interpret this path correctly. 98*86ee64e7SAndroid Build Coastguard Worker std::string path_in_original_encoding; 99*86ee64e7SAndroid Build Coastguard Worker 100*86ee64e7SAndroid Build Coastguard Worker // Path of the entry, converted to Unicode. This path is relative (eg 101*86ee64e7SAndroid Build Coastguard Worker // "foo/bar.txt"). Absolute paths (eg "/foo/bar.txt") or paths containing 102*86ee64e7SAndroid Build Coastguard Worker // ".." or "." components (eg "../foo/bar.txt") are converted to safe 103*86ee64e7SAndroid Build Coastguard Worker // relative paths. Eg: 104*86ee64e7SAndroid Build Coastguard Worker // (In ZIP) -> (Entry.path) 105*86ee64e7SAndroid Build Coastguard Worker // /foo/bar -> ROOT/foo/bar 106*86ee64e7SAndroid Build Coastguard Worker // ../a -> UP/a 107*86ee64e7SAndroid Build Coastguard Worker // ./a -> DOT/a 108*86ee64e7SAndroid Build Coastguard Worker base::FilePath path; 109*86ee64e7SAndroid Build Coastguard Worker 110*86ee64e7SAndroid Build Coastguard Worker // Size of the original uncompressed file, or 0 if the entry is a directory. 111*86ee64e7SAndroid Build Coastguard Worker // This value should not be trusted, because it is stored as metadata in the 112*86ee64e7SAndroid Build Coastguard Worker // ZIP archive and can be different from the real uncompressed size. 113*86ee64e7SAndroid Build Coastguard Worker int64_t original_size; 114*86ee64e7SAndroid Build Coastguard Worker 115*86ee64e7SAndroid Build Coastguard Worker // Last modified time. If the timestamp stored in the ZIP archive is not 116*86ee64e7SAndroid Build Coastguard Worker // valid, the Unix epoch will be returned. 117*86ee64e7SAndroid Build Coastguard Worker // 118*86ee64e7SAndroid Build Coastguard Worker // The timestamp stored in the ZIP archive uses the MS-DOS date and time 119*86ee64e7SAndroid Build Coastguard Worker // format. 120*86ee64e7SAndroid Build Coastguard Worker // 121*86ee64e7SAndroid Build Coastguard Worker // http://msdn.microsoft.com/en-us/library/ms724247(v=vs.85).aspx 122*86ee64e7SAndroid Build Coastguard Worker // 123*86ee64e7SAndroid Build Coastguard Worker // As such the following limitations apply: 124*86ee64e7SAndroid Build Coastguard Worker // * Only years from 1980 to 2107 can be represented. 125*86ee64e7SAndroid Build Coastguard Worker // * The timestamp has a 2-second resolution. 126*86ee64e7SAndroid Build Coastguard Worker // * There is no timezone information, so the time is interpreted as UTC. 127*86ee64e7SAndroid Build Coastguard Worker base::Time last_modified; 128*86ee64e7SAndroid Build Coastguard Worker 129*86ee64e7SAndroid Build Coastguard Worker // True if the entry is a directory. 130*86ee64e7SAndroid Build Coastguard Worker // False if the entry is a file. 131*86ee64e7SAndroid Build Coastguard Worker bool is_directory = false; 132*86ee64e7SAndroid Build Coastguard Worker 133*86ee64e7SAndroid Build Coastguard Worker // True if the entry path cannot be converted to a safe relative path. This 134*86ee64e7SAndroid Build Coastguard Worker // happens if a file entry (not a directory) has a filename "." or "..". 135*86ee64e7SAndroid Build Coastguard Worker bool is_unsafe = false; 136*86ee64e7SAndroid Build Coastguard Worker 137*86ee64e7SAndroid Build Coastguard Worker // True if the file content is encrypted. 138*86ee64e7SAndroid Build Coastguard Worker bool is_encrypted = false; 139*86ee64e7SAndroid Build Coastguard Worker 140*86ee64e7SAndroid Build Coastguard Worker // True if the encryption scheme is AES. 141*86ee64e7SAndroid Build Coastguard Worker bool uses_aes_encryption = false; 142*86ee64e7SAndroid Build Coastguard Worker 143*86ee64e7SAndroid Build Coastguard Worker // Entry POSIX permissions (POSIX systems only). 144*86ee64e7SAndroid Build Coastguard Worker int posix_mode; 145*86ee64e7SAndroid Build Coastguard Worker }; 146*86ee64e7SAndroid Build Coastguard Worker 147*86ee64e7SAndroid Build Coastguard Worker ZipReader(); 148*86ee64e7SAndroid Build Coastguard Worker 149*86ee64e7SAndroid Build Coastguard Worker ZipReader(const ZipReader&) = delete; 150*86ee64e7SAndroid Build Coastguard Worker ZipReader& operator=(const ZipReader&) = delete; 151*86ee64e7SAndroid Build Coastguard Worker 152*86ee64e7SAndroid Build Coastguard Worker ~ZipReader(); 153*86ee64e7SAndroid Build Coastguard Worker 154*86ee64e7SAndroid Build Coastguard Worker // Opens the ZIP archive specified by |zip_path|. Returns true on 155*86ee64e7SAndroid Build Coastguard Worker // success. 156*86ee64e7SAndroid Build Coastguard Worker bool Open(const base::FilePath& zip_path); 157*86ee64e7SAndroid Build Coastguard Worker 158*86ee64e7SAndroid Build Coastguard Worker // Opens the ZIP archive referred to by the platform file |zip_fd|, without 159*86ee64e7SAndroid Build Coastguard Worker // taking ownership of |zip_fd|. Returns true on success. 160*86ee64e7SAndroid Build Coastguard Worker bool OpenFromPlatformFile(base::PlatformFile zip_fd); 161*86ee64e7SAndroid Build Coastguard Worker 162*86ee64e7SAndroid Build Coastguard Worker // Opens the zip data stored in |data|. This class uses a weak reference to 163*86ee64e7SAndroid Build Coastguard Worker // the given sring while extracting files, i.e. the caller should keep the 164*86ee64e7SAndroid Build Coastguard Worker // string until it finishes extracting files. 165*86ee64e7SAndroid Build Coastguard Worker bool OpenFromString(const std::string& data); 166*86ee64e7SAndroid Build Coastguard Worker 167*86ee64e7SAndroid Build Coastguard Worker // Closes the currently opened ZIP archive. This function is called in the 168*86ee64e7SAndroid Build Coastguard Worker // destructor of the class, so you usually don't need to call this. 169*86ee64e7SAndroid Build Coastguard Worker void Close(); 170*86ee64e7SAndroid Build Coastguard Worker 171*86ee64e7SAndroid Build Coastguard Worker // Sets the encoding of entry paths in the ZIP archive. 172*86ee64e7SAndroid Build Coastguard Worker // By default, paths are assumed to be in UTF-8. SetEncoding(std::string encoding)173*86ee64e7SAndroid Build Coastguard Worker void SetEncoding(std::string encoding) { encoding_ = std::move(encoding); } 174*86ee64e7SAndroid Build Coastguard Worker 175*86ee64e7SAndroid Build Coastguard Worker // Sets the decryption password that will be used to decrypt encrypted file in 176*86ee64e7SAndroid Build Coastguard Worker // the ZIP archive. SetPassword(std::string password)177*86ee64e7SAndroid Build Coastguard Worker void SetPassword(std::string password) { password_ = std::move(password); } 178*86ee64e7SAndroid Build Coastguard Worker 179*86ee64e7SAndroid Build Coastguard Worker // Gets the next entry. Returns null if there is no more entry, or if an error 180*86ee64e7SAndroid Build Coastguard Worker // occurred while scanning entries. The returned Entry is owned by this 181*86ee64e7SAndroid Build Coastguard Worker // ZipReader, and is valid until Next() is called again or until this 182*86ee64e7SAndroid Build Coastguard Worker // ZipReader is closed. 183*86ee64e7SAndroid Build Coastguard Worker // 184*86ee64e7SAndroid Build Coastguard Worker // This function should be called before operations over the current entry 185*86ee64e7SAndroid Build Coastguard Worker // like ExtractCurrentEntryToFile(). 186*86ee64e7SAndroid Build Coastguard Worker // 187*86ee64e7SAndroid Build Coastguard Worker // while (const ZipReader::Entry* entry = reader.Next()) { 188*86ee64e7SAndroid Build Coastguard Worker // // Do something with the current entry here. 189*86ee64e7SAndroid Build Coastguard Worker // ... 190*86ee64e7SAndroid Build Coastguard Worker // } 191*86ee64e7SAndroid Build Coastguard Worker // 192*86ee64e7SAndroid Build Coastguard Worker // // Finished scanning entries. 193*86ee64e7SAndroid Build Coastguard Worker // // Check if the scanning stopped because of an error. 194*86ee64e7SAndroid Build Coastguard Worker // if (!reader.ok()) { 195*86ee64e7SAndroid Build Coastguard Worker // // There was an error. 196*86ee64e7SAndroid Build Coastguard Worker // ... 197*86ee64e7SAndroid Build Coastguard Worker // } 198*86ee64e7SAndroid Build Coastguard Worker const Entry* Next(); 199*86ee64e7SAndroid Build Coastguard Worker 200*86ee64e7SAndroid Build Coastguard Worker // Returns true if the enumeration of entries was successful, or false if it 201*86ee64e7SAndroid Build Coastguard Worker // stopped because of an error. ok()202*86ee64e7SAndroid Build Coastguard Worker bool ok() const { return ok_; } 203*86ee64e7SAndroid Build Coastguard Worker 204*86ee64e7SAndroid Build Coastguard Worker // Extracts |num_bytes_to_extract| bytes of the current entry to |delegate|, 205*86ee64e7SAndroid Build Coastguard Worker // starting from the beginning of the entry. 206*86ee64e7SAndroid Build Coastguard Worker // 207*86ee64e7SAndroid Build Coastguard Worker // Returns true if the entire file was extracted without error. 208*86ee64e7SAndroid Build Coastguard Worker // 209*86ee64e7SAndroid Build Coastguard Worker // Precondition: Next() returned a non-null Entry. 210*86ee64e7SAndroid Build Coastguard Worker bool ExtractCurrentEntry(WriterDelegate* delegate, 211*86ee64e7SAndroid Build Coastguard Worker uint64_t num_bytes_to_extract = 212*86ee64e7SAndroid Build Coastguard Worker std::numeric_limits<uint64_t>::max()) const; 213*86ee64e7SAndroid Build Coastguard Worker 214*86ee64e7SAndroid Build Coastguard Worker // Extracts the current entry to |delegate|, starting from the beginning 215*86ee64e7SAndroid Build Coastguard Worker // of the entry, calling |listener_callback| regularly with the number of 216*86ee64e7SAndroid Build Coastguard Worker // bytes extracted. 217*86ee64e7SAndroid Build Coastguard Worker // 218*86ee64e7SAndroid Build Coastguard Worker // Returns true if the entire file was extracted without error. 219*86ee64e7SAndroid Build Coastguard Worker // 220*86ee64e7SAndroid Build Coastguard Worker // Precondition: Next() returned a non-null Entry. 221*86ee64e7SAndroid Build Coastguard Worker bool ExtractCurrentEntryWithListener( 222*86ee64e7SAndroid Build Coastguard Worker WriterDelegate* delegate, 223*86ee64e7SAndroid Build Coastguard Worker ListenerCallback listener_callback) const; 224*86ee64e7SAndroid Build Coastguard Worker 225*86ee64e7SAndroid Build Coastguard Worker // Asynchronously extracts the current entry to the given output file path. If 226*86ee64e7SAndroid Build Coastguard Worker // the current entry is a directory it just creates the directory 227*86ee64e7SAndroid Build Coastguard Worker // synchronously instead. 228*86ee64e7SAndroid Build Coastguard Worker // 229*86ee64e7SAndroid Build Coastguard Worker // |success_callback| will be called on success and |failure_callback| will be 230*86ee64e7SAndroid Build Coastguard Worker // called on failure. |progress_callback| will be called at least once. 231*86ee64e7SAndroid Build Coastguard Worker // Callbacks will be posted to the current MessageLoop in-order. 232*86ee64e7SAndroid Build Coastguard Worker // 233*86ee64e7SAndroid Build Coastguard Worker // Precondition: Next() returned a non-null Entry. 234*86ee64e7SAndroid Build Coastguard Worker void ExtractCurrentEntryToFilePathAsync( 235*86ee64e7SAndroid Build Coastguard Worker const base::FilePath& output_file_path, 236*86ee64e7SAndroid Build Coastguard Worker SuccessCallback success_callback, 237*86ee64e7SAndroid Build Coastguard Worker FailureCallback failure_callback, 238*86ee64e7SAndroid Build Coastguard Worker ProgressCallback progress_callback); 239*86ee64e7SAndroid Build Coastguard Worker 240*86ee64e7SAndroid Build Coastguard Worker // Extracts the current entry into memory. If the current entry is a 241*86ee64e7SAndroid Build Coastguard Worker // directory, |*output| is set to the empty string. If the current entry is a 242*86ee64e7SAndroid Build Coastguard Worker // file, |*output| is filled with its contents. 243*86ee64e7SAndroid Build Coastguard Worker // 244*86ee64e7SAndroid Build Coastguard Worker // The value in |Entry::original_size| cannot be trusted, so the real size of 245*86ee64e7SAndroid Build Coastguard Worker // the uncompressed contents can be different. |max_read_bytes| limits the 246*86ee64e7SAndroid Build Coastguard Worker // amount of memory used to carry the entry. 247*86ee64e7SAndroid Build Coastguard Worker // 248*86ee64e7SAndroid Build Coastguard Worker // Returns true if the entire content is read without error. If the content is 249*86ee64e7SAndroid Build Coastguard Worker // bigger than |max_read_bytes|, this function returns false and |*output| is 250*86ee64e7SAndroid Build Coastguard Worker // filled with |max_read_bytes| of data. If an error occurs, this function 251*86ee64e7SAndroid Build Coastguard Worker // returns false and |*output| contains the content extracted so far, which 252*86ee64e7SAndroid Build Coastguard Worker // might be garbage data. 253*86ee64e7SAndroid Build Coastguard Worker // 254*86ee64e7SAndroid Build Coastguard Worker // Precondition: Next() returned a non-null Entry. 255*86ee64e7SAndroid Build Coastguard Worker bool ExtractCurrentEntryToString(uint64_t max_read_bytes, 256*86ee64e7SAndroid Build Coastguard Worker std::string* output) const; 257*86ee64e7SAndroid Build Coastguard Worker ExtractCurrentEntryToString(std::string * output)258*86ee64e7SAndroid Build Coastguard Worker bool ExtractCurrentEntryToString(std::string* output) const { 259*86ee64e7SAndroid Build Coastguard Worker return ExtractCurrentEntryToString( 260*86ee64e7SAndroid Build Coastguard Worker base::checked_cast<uint64_t>(output->max_size()), output); 261*86ee64e7SAndroid Build Coastguard Worker } 262*86ee64e7SAndroid Build Coastguard Worker 263*86ee64e7SAndroid Build Coastguard Worker // Returns the number of entries in the ZIP archive. 264*86ee64e7SAndroid Build Coastguard Worker // 265*86ee64e7SAndroid Build Coastguard Worker // Precondition: one of the Open() methods returned true. num_entries()266*86ee64e7SAndroid Build Coastguard Worker int num_entries() const { return num_entries_; } 267*86ee64e7SAndroid Build Coastguard Worker 268*86ee64e7SAndroid Build Coastguard Worker private: 269*86ee64e7SAndroid Build Coastguard Worker // Common code used both in Open and OpenFromFd. 270*86ee64e7SAndroid Build Coastguard Worker bool OpenInternal(); 271*86ee64e7SAndroid Build Coastguard Worker 272*86ee64e7SAndroid Build Coastguard Worker // Resets the internal state. 273*86ee64e7SAndroid Build Coastguard Worker void Reset(); 274*86ee64e7SAndroid Build Coastguard Worker 275*86ee64e7SAndroid Build Coastguard Worker // Opens the current entry in the ZIP archive. On success, returns true and 276*86ee64e7SAndroid Build Coastguard Worker // updates the current entry state |entry_|. 277*86ee64e7SAndroid Build Coastguard Worker // 278*86ee64e7SAndroid Build Coastguard Worker // Note that there is no matching CloseEntry(). The current entry state is 279*86ee64e7SAndroid Build Coastguard Worker // reset automatically as needed. 280*86ee64e7SAndroid Build Coastguard Worker bool OpenEntry(); 281*86ee64e7SAndroid Build Coastguard Worker 282*86ee64e7SAndroid Build Coastguard Worker // Normalizes the given path passed as UTF-16 string piece. Sets entry_.path, 283*86ee64e7SAndroid Build Coastguard Worker // entry_.is_directory and entry_.is_unsafe. 284*86ee64e7SAndroid Build Coastguard Worker void Normalize(base::StringPiece16 in); 285*86ee64e7SAndroid Build Coastguard Worker 286*86ee64e7SAndroid Build Coastguard Worker // Runs the ListenerCallback at a throttled rate. 287*86ee64e7SAndroid Build Coastguard Worker void ReportProgress(ListenerCallback listener_callback, uint64_t bytes) const; 288*86ee64e7SAndroid Build Coastguard Worker 289*86ee64e7SAndroid Build Coastguard Worker // Extracts |num_bytes_to_extract| bytes of the current entry to |delegate|, 290*86ee64e7SAndroid Build Coastguard Worker // starting from the beginning of the entry calling |listener_callback| if 291*86ee64e7SAndroid Build Coastguard Worker // its supplied. 292*86ee64e7SAndroid Build Coastguard Worker // 293*86ee64e7SAndroid Build Coastguard Worker // Returns true if the entire file was extracted without error. 294*86ee64e7SAndroid Build Coastguard Worker // 295*86ee64e7SAndroid Build Coastguard Worker // Precondition: Next() returned a non-null Entry. 296*86ee64e7SAndroid Build Coastguard Worker bool ExtractCurrentEntry(WriterDelegate* delegate, 297*86ee64e7SAndroid Build Coastguard Worker ListenerCallback listener_callback, 298*86ee64e7SAndroid Build Coastguard Worker uint64_t num_bytes_to_extract = 299*86ee64e7SAndroid Build Coastguard Worker std::numeric_limits<uint64_t>::max()) const; 300*86ee64e7SAndroid Build Coastguard Worker 301*86ee64e7SAndroid Build Coastguard Worker // Extracts a chunk of the file to the target. Will post a task for the next 302*86ee64e7SAndroid Build Coastguard Worker // chunk and success/failure/progress callbacks as necessary. 303*86ee64e7SAndroid Build Coastguard Worker void ExtractChunk(base::File target_file, 304*86ee64e7SAndroid Build Coastguard Worker SuccessCallback success_callback, 305*86ee64e7SAndroid Build Coastguard Worker FailureCallback failure_callback, 306*86ee64e7SAndroid Build Coastguard Worker ProgressCallback progress_callback, 307*86ee64e7SAndroid Build Coastguard Worker const int64_t offset); 308*86ee64e7SAndroid Build Coastguard Worker 309*86ee64e7SAndroid Build Coastguard Worker std::string encoding_; 310*86ee64e7SAndroid Build Coastguard Worker std::string password_; 311*86ee64e7SAndroid Build Coastguard Worker unzFile zip_file_; 312*86ee64e7SAndroid Build Coastguard Worker int num_entries_; 313*86ee64e7SAndroid Build Coastguard Worker int next_index_; 314*86ee64e7SAndroid Build Coastguard Worker bool reached_end_; 315*86ee64e7SAndroid Build Coastguard Worker bool ok_; 316*86ee64e7SAndroid Build Coastguard Worker Entry entry_; 317*86ee64e7SAndroid Build Coastguard Worker 318*86ee64e7SAndroid Build Coastguard Worker // Next time to report progress. 319*86ee64e7SAndroid Build Coastguard Worker mutable base::TimeTicks next_progress_report_time_ = base::TimeTicks::Now(); 320*86ee64e7SAndroid Build Coastguard Worker 321*86ee64e7SAndroid Build Coastguard Worker // Progress time delta. 322*86ee64e7SAndroid Build Coastguard Worker // TODO(crbug.com/953256) Add this as parameter to the unzip options. 323*86ee64e7SAndroid Build Coastguard Worker base::TimeDelta progress_period_ = base::Milliseconds(1000); 324*86ee64e7SAndroid Build Coastguard Worker 325*86ee64e7SAndroid Build Coastguard Worker // Number of bytes read since last progress report callback executed. 326*86ee64e7SAndroid Build Coastguard Worker mutable uint64_t delta_bytes_read_ = 0; 327*86ee64e7SAndroid Build Coastguard Worker 328*86ee64e7SAndroid Build Coastguard Worker base::WeakPtrFactory<ZipReader> weak_ptr_factory_{this}; 329*86ee64e7SAndroid Build Coastguard Worker }; 330*86ee64e7SAndroid Build Coastguard Worker 331*86ee64e7SAndroid Build Coastguard Worker // A writer delegate that writes to a given File. It is recommended that this 332*86ee64e7SAndroid Build Coastguard Worker // file be initially empty. 333*86ee64e7SAndroid Build Coastguard Worker class FileWriterDelegate : public WriterDelegate { 334*86ee64e7SAndroid Build Coastguard Worker public: 335*86ee64e7SAndroid Build Coastguard Worker // Constructs a FileWriterDelegate that manipulates |file|. The delegate will 336*86ee64e7SAndroid Build Coastguard Worker // not own |file|, therefore the caller must guarantee |file| will outlive the 337*86ee64e7SAndroid Build Coastguard Worker // delegate. 338*86ee64e7SAndroid Build Coastguard Worker explicit FileWriterDelegate(base::File* file); 339*86ee64e7SAndroid Build Coastguard Worker 340*86ee64e7SAndroid Build Coastguard Worker // Constructs a FileWriterDelegate that takes ownership of |file|. 341*86ee64e7SAndroid Build Coastguard Worker explicit FileWriterDelegate(base::File owned_file); 342*86ee64e7SAndroid Build Coastguard Worker 343*86ee64e7SAndroid Build Coastguard Worker FileWriterDelegate(const FileWriterDelegate&) = delete; 344*86ee64e7SAndroid Build Coastguard Worker FileWriterDelegate& operator=(const FileWriterDelegate&) = delete; 345*86ee64e7SAndroid Build Coastguard Worker 346*86ee64e7SAndroid Build Coastguard Worker ~FileWriterDelegate() override; 347*86ee64e7SAndroid Build Coastguard Worker 348*86ee64e7SAndroid Build Coastguard Worker // Returns true if the file handle passed to the constructor is valid. 349*86ee64e7SAndroid Build Coastguard Worker bool PrepareOutput() override; 350*86ee64e7SAndroid Build Coastguard Worker 351*86ee64e7SAndroid Build Coastguard Worker // Writes |num_bytes| bytes of |data| to the file, returning false on error or 352*86ee64e7SAndroid Build Coastguard Worker // if not all bytes could be written. 353*86ee64e7SAndroid Build Coastguard Worker bool WriteBytes(const char* data, int num_bytes) override; 354*86ee64e7SAndroid Build Coastguard Worker 355*86ee64e7SAndroid Build Coastguard Worker // Sets the last-modified time of the data. 356*86ee64e7SAndroid Build Coastguard Worker void SetTimeModified(const base::Time& time) override; 357*86ee64e7SAndroid Build Coastguard Worker 358*86ee64e7SAndroid Build Coastguard Worker // On POSIX systems, sets the file to be executable if the source file was 359*86ee64e7SAndroid Build Coastguard Worker // executable. 360*86ee64e7SAndroid Build Coastguard Worker void SetPosixFilePermissions(int mode) override; 361*86ee64e7SAndroid Build Coastguard Worker 362*86ee64e7SAndroid Build Coastguard Worker // Empties the file to avoid leaving garbage data in it. 363*86ee64e7SAndroid Build Coastguard Worker void OnError() override; 364*86ee64e7SAndroid Build Coastguard Worker 365*86ee64e7SAndroid Build Coastguard Worker // Gets the number of bytes written into the file. file_length()366*86ee64e7SAndroid Build Coastguard Worker int64_t file_length() { return file_length_; } 367*86ee64e7SAndroid Build Coastguard Worker 368*86ee64e7SAndroid Build Coastguard Worker protected: 369*86ee64e7SAndroid Build Coastguard Worker // The delegate can optionally own the file it modifies, in which case 370*86ee64e7SAndroid Build Coastguard Worker // owned_file_ is set and file_ is an alias for owned_file_. 371*86ee64e7SAndroid Build Coastguard Worker base::File owned_file_; 372*86ee64e7SAndroid Build Coastguard Worker 373*86ee64e7SAndroid Build Coastguard Worker // The file the delegate modifies. 374*86ee64e7SAndroid Build Coastguard Worker base::File* const file_ = &owned_file_; 375*86ee64e7SAndroid Build Coastguard Worker 376*86ee64e7SAndroid Build Coastguard Worker int64_t file_length_ = 0; 377*86ee64e7SAndroid Build Coastguard Worker }; 378*86ee64e7SAndroid Build Coastguard Worker 379*86ee64e7SAndroid Build Coastguard Worker // A writer delegate that creates and writes a file at a given path. This does 380*86ee64e7SAndroid Build Coastguard Worker // not overwrite any existing file. 381*86ee64e7SAndroid Build Coastguard Worker class FilePathWriterDelegate : public FileWriterDelegate { 382*86ee64e7SAndroid Build Coastguard Worker public: 383*86ee64e7SAndroid Build Coastguard Worker explicit FilePathWriterDelegate(base::FilePath output_file_path); 384*86ee64e7SAndroid Build Coastguard Worker 385*86ee64e7SAndroid Build Coastguard Worker FilePathWriterDelegate(const FilePathWriterDelegate&) = delete; 386*86ee64e7SAndroid Build Coastguard Worker FilePathWriterDelegate& operator=(const FilePathWriterDelegate&) = delete; 387*86ee64e7SAndroid Build Coastguard Worker 388*86ee64e7SAndroid Build Coastguard Worker ~FilePathWriterDelegate() override; 389*86ee64e7SAndroid Build Coastguard Worker 390*86ee64e7SAndroid Build Coastguard Worker // Creates the output file and any necessary intermediate directories. Does 391*86ee64e7SAndroid Build Coastguard Worker // not overwrite any existing file, and returns false if the output file 392*86ee64e7SAndroid Build Coastguard Worker // cannot be created because another file conflicts with it. 393*86ee64e7SAndroid Build Coastguard Worker bool PrepareOutput() override; 394*86ee64e7SAndroid Build Coastguard Worker 395*86ee64e7SAndroid Build Coastguard Worker // Deletes the output file. 396*86ee64e7SAndroid Build Coastguard Worker void OnError() override; 397*86ee64e7SAndroid Build Coastguard Worker 398*86ee64e7SAndroid Build Coastguard Worker private: 399*86ee64e7SAndroid Build Coastguard Worker const base::FilePath output_file_path_; 400*86ee64e7SAndroid Build Coastguard Worker }; 401*86ee64e7SAndroid Build Coastguard Worker 402*86ee64e7SAndroid Build Coastguard Worker } // namespace zip 403*86ee64e7SAndroid Build Coastguard Worker 404*86ee64e7SAndroid Build Coastguard Worker #endif // THIRD_PARTY_ZLIB_GOOGLE_ZIP_READER_H_ 405