| 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 8787254d28f0c87bfe0c5041580a3e288dca2d73..7b7870ee981daf4287255dc50475890f094901e7 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"
|
| @@ -68,7 +69,8 @@ ZipReader::EntryInfo::EntryInfo(const std::string& file_name_in_zip,
|
| }
|
| }
|
|
|
| -ZipReader::ZipReader() {
|
| +ZipReader::ZipReader()
|
| + : weak_ptr_factory_(this) {
|
| Reset();
|
| }
|
|
|
| @@ -241,6 +243,65 @@ bool ZipReader::ExtractCurrentEntryToFilePath(
|
| return success;
|
| }
|
|
|
| +void ZipReader::ExtractCurrentEntryToFilePathAsync(
|
| + const base::FilePath& output_file_path,
|
| + const SuccessCallback& success_callback,
|
| + const FailureCallback& failure_callback,
|
| + const ProgressCallback& 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)) {
|
| + base::MessageLoopProxy::current()->PostTask(FROM_HERE, success_callback);
|
| + } else {
|
| + DVLOG(1) << "Unzip failed: unable to create directory.";
|
| + base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback);
|
| + }
|
| + return;
|
| + }
|
| +
|
| + if (unzOpenCurrentFile(zip_file_) != UNZ_OK) {
|
| + DVLOG(1) << "Unzip failed: unable to open current zip entry.";
|
| + base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback);
|
| + 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.";
|
| + base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback);
|
| + 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();
|
| + base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback);
|
| + return;
|
| + }
|
| +
|
| + base::MessageLoop::current()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&ZipReader::ExtractChunk,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + output_file,
|
| + success_callback,
|
| + failure_callback,
|
| + progress_callback,
|
| + 0 /* initial offset */));
|
| +}
|
| +
|
| bool ZipReader::ExtractCurrentEntryIntoDirectory(
|
| const base::FilePath& output_directory_path) {
|
| DCHECK(current_entry_info_.get());
|
| @@ -313,4 +374,53 @@ void ZipReader::Reset() {
|
| current_entry_info_.reset();
|
| }
|
|
|
| +void ZipReader::ExtractChunk(base::PlatformFile output_file,
|
| + const SuccessCallback& success_callback,
|
| + const FailureCallback& failure_callback,
|
| + const ProgressCallback& 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::WritePlatformFile(output_file,
|
| + offset,
|
| + buffer,
|
| + num_bytes_read)) {
|
| + DVLOG(1) << "Unzip failed: unable to write all bytes to target.";
|
| + base::ClosePlatformFile(output_file);
|
| + failure_callback.Run();
|
| + return;
|
| + }
|
| +
|
| + int64 current_progress = offset + num_bytes_read;
|
| +
|
| + progress_callback.Run(current_progress);
|
| +
|
| + base::MessageLoop::current()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&ZipReader::ExtractChunk,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + output_file,
|
| + success_callback,
|
| + failure_callback,
|
| + progress_callback,
|
| + current_progress));
|
| +
|
| + }
|
| +}
|
| +
|
| +
|
| } // namespace zip
|
|
|