Chromium Code Reviews| Index: third_party/zlib/google/zip_reader.cc |
| diff --git a/third_party/zlib/google/zip_reader.cc b/third_party/zlib/google/zip_reader.cc |
| index 6ea8025094151de4bb83a7947057b0b6dc616387..3cc32ca01000a59bc2f582c4421e99c4ec73d2a9 100644 |
| --- a/third_party/zlib/google/zip_reader.cc |
| +++ b/third_party/zlib/google/zip_reader.cc |
| @@ -6,6 +6,7 @@ |
| #include "base/file_util.h" |
| #include "base/logging.h" |
| +#include "base/message_loop/message_loop.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "net/base/file_stream.h" |
| @@ -69,7 +70,8 @@ ZipReader::EntryInfo::EntryInfo(const std::string& file_name_in_zip, |
| } |
| } |
| -ZipReader::ZipReader() { |
| +ZipReader::ZipReader() |
| + : weak_factory_(this) { |
| Reset(); |
| } |
| @@ -235,6 +237,70 @@ bool ZipReader::ExtractCurrentEntryToFilePath( |
| return success; |
| } |
| +void ZipReader::ExtractCurrentEntryToFilePathAsync( |
| + const base::FilePath& output_file_path, |
| + base::Closure success_callback, |
| + base::Closure failure_callback, |
| + base::Callback<void(int64)> progress_callback) { |
| + DCHECK(zip_file_); |
| + DCHECK(current_entry_info_.get()); |
| + |
| + // If this is a directory, just create it and return. |
| + if (current_entry_info()->is_directory()) { |
| + if (base::CreateDirectory(output_file_path)) { |
| + success_callback.Run(); |
|
satorux1
2013/12/11 06:45:11
It's probably nicer to run this through a message
Drew Haven
2013/12/11 18:20:53
Done.
|
| + } else { |
| + DVLOG(1) << "Unzip failed: unable to create directory."; |
| + failure_callback.Run(); |
|
satorux1
2013/12/11 06:45:11
ditto, and other places too.
Drew Haven
2013/12/11 18:20:53
Done.
|
| + } |
| + return; |
| + } |
| + |
| + if (current_entry_info()->is_directory()) { |
| + DVLOG(1) << "Unzip failed: Cannot unzip a directory to an open file."; |
| + failure_callback.Run(); |
| + } |
| + |
| + if (unzOpenCurrentFile(zip_file_) != UNZ_OK) { |
| + DVLOG(1) << "Unzip failed: unable to open current zip entry."; |
| + failure_callback.Run(); |
| + return; |
| + } |
| + |
| + base::FilePath output_dir_path = output_file_path.DirName(); |
| + if (!base::CreateDirectory(output_dir_path)) { |
| + DVLOG(1) << "Unzip failed: unable to create containing directory."; |
| + failure_callback.Run(); |
| + return; |
| + } |
| + |
| + const int flags = (base::PLATFORM_FILE_CREATE_ALWAYS | |
| + base::PLATFORM_FILE_WRITE); |
| + bool created = false; |
| + base::PlatformFileError platform_file_error; |
| + base::PlatformFile output_file = CreatePlatformFile(output_file_path, |
| + flags, |
| + &created, |
| + &platform_file_error); |
| + |
| + if (platform_file_error != base::PLATFORM_FILE_OK) { |
| + DVLOG(1) << "Unzip failed: unable to create platform file at " |
| + << output_file_path.value(); |
| + failure_callback.Run(); |
| + return; |
| + } |
| + |
| + base::MessageLoop::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&ZipReader::ExtractChunk, |
| + weak_factory_.GetWeakPtr(), |
| + output_file, |
| + success_callback, |
| + failure_callback, |
| + progress_callback, |
| + 0)); |
|
satorux1
2013/12/11 06:45:11
0 looks a bit cryptic. maybe:
0 /* offset */));
Drew Haven
2013/12/11 18:20:53
Done.
|
| +} |
| + |
| bool ZipReader::ExtractCurrentEntryIntoDirectory( |
| const base::FilePath& output_directory_path) { |
| DCHECK(current_entry_info_.get()); |
| @@ -307,4 +373,52 @@ void ZipReader::Reset() { |
| current_entry_info_.reset(); |
| } |
| +void ZipReader::ExtractChunk(base::PlatformFile output_file, |
| + base::Closure success_callback, |
| + base::Closure failure_callback, |
| + base::Callback<void(int64)> progress_callback, |
| + const int64 offset) { |
| + char buffer[internal::kZipBufSize]; |
| + |
| + const int num_bytes_read = unzReadCurrentFile(zip_file_, |
| + buffer, |
| + internal::kZipBufSize); |
| + |
| + if (num_bytes_read == 0) { |
| + unzCloseCurrentFile(zip_file_); |
| + base::ClosePlatformFile(output_file); |
| + success_callback.Run(); |
| + } else if (num_bytes_read < 0) { |
| + DVLOG(1) << "Unzip failed: error while reading zipfile " |
| + << "(" << num_bytes_read << ")"; |
| + base::ClosePlatformFile(output_file); |
| + failure_callback.Run(); |
| + } else { |
| + if (num_bytes_read != base::WritePlatformFileAtCurrentPos(output_file, |
| + buffer, |
| + num_bytes_read)) { |
| + DVLOG(1) << "Unzip failed: unable to write all bytes to target."; |
| + base::ClosePlatformFile(output_file); |
| + failure_callback.Run(); |
| + return; |
| + } |
| + |
| + int64 curr_progress = offset + num_bytes_read; |
| + |
| + progress_callback.Run(curr_progress); |
| + |
| + base::MessageLoop::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&ZipReader::ExtractChunk, |
| + weak_factory_.GetWeakPtr(), |
| + output_file, |
| + success_callback, |
| + failure_callback, |
| + progress_callback, |
| + curr_progress)); |
| + |
| + } |
| +} |
| + |
| + |
| } // namespace zip |