Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: third_party/zlib/google/zip_reader.cc

Issue 92873003: Adds asynchronous unzip functions to ZipReader (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixes up commenting and minor style issues. Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "third_party/zlib/google/zip_reader.h" 5 #include "third_party/zlib/google/zip_reader.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
9 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
11 #include "net/base/file_stream.h" 12 #include "net/base/file_stream.h"
12 #include "third_party/zlib/google/zip_internal.h" 13 #include "third_party/zlib/google/zip_internal.h"
13 14
14 #if defined(USE_SYSTEM_MINIZIP) 15 #if defined(USE_SYSTEM_MINIZIP)
15 #include <minizip/unzip.h> 16 #include <minizip/unzip.h>
16 #else 17 #else
17 #include "third_party/zlib/contrib/minizip/unzip.h" 18 #include "third_party/zlib/contrib/minizip/unzip.h"
18 #if defined(OS_WIN) 19 #if defined(OS_WIN)
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 exploded_time.second = raw_file_info.tmu_date.tm_sec; 63 exploded_time.second = raw_file_info.tmu_date.tm_sec;
63 exploded_time.millisecond = 0; 64 exploded_time.millisecond = 0;
64 if (exploded_time.HasValidValues()) { 65 if (exploded_time.HasValidValues()) {
65 last_modified_ = base::Time::FromLocalExploded(exploded_time); 66 last_modified_ = base::Time::FromLocalExploded(exploded_time);
66 } else { 67 } else {
67 // Use Unix time epoch if the time stamp data is invalid. 68 // Use Unix time epoch if the time stamp data is invalid.
68 last_modified_ = base::Time::UnixEpoch(); 69 last_modified_ = base::Time::UnixEpoch();
69 } 70 }
70 } 71 }
71 72
72 ZipReader::ZipReader() { 73 ZipReader::ZipReader()
74 : weak_ptr_factory_(this) {
73 Reset(); 75 Reset();
74 } 76 }
75 77
76 ZipReader::~ZipReader() { 78 ZipReader::~ZipReader() {
77 Close(); 79 Close();
78 } 80 }
79 81
80 bool ZipReader::Open(const base::FilePath& zip_file_path) { 82 bool ZipReader::Open(const base::FilePath& zip_file_path) {
81 DCHECK(!zip_file_); 83 DCHECK(!zip_file_);
82 84
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 success = false; 230 success = false;
229 break; 231 break;
230 } 232 }
231 } 233 }
232 } 234 }
233 235
234 unzCloseCurrentFile(zip_file_); 236 unzCloseCurrentFile(zip_file_);
235 return success; 237 return success;
236 } 238 }
237 239
240 void ZipReader::ExtractCurrentEntryToFilePathAsync(
241 const base::FilePath& output_file_path,
242 SuccessCallback success_callback,
243 FailureCallback failure_callback,
244 ProgressCallback progress_callback) {
245 DCHECK(zip_file_);
246 DCHECK(current_entry_info_.get());
247
248 // If this is a directory, just create it and return.
249 if (current_entry_info()->is_directory()) {
250 if (base::CreateDirectory(output_file_path)) {
251 base::MessageLoopProxy::current()->PostTask(FROM_HERE, success_callback);
252 } else {
253 DVLOG(1) << "Unzip failed: unable to create directory.";
254 base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback);
255 }
256 return;
257 }
258
259 if (current_entry_info()->is_directory()) {
260 DVLOG(1) << "Unzip failed: Cannot unzip a directory to an open file.";
261 base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback);
262 }
263
264 if (unzOpenCurrentFile(zip_file_) != UNZ_OK) {
265 DVLOG(1) << "Unzip failed: unable to open current zip entry.";
266 base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback);
267 return;
268 }
269
270 base::FilePath output_dir_path = output_file_path.DirName();
271 if (!base::CreateDirectory(output_dir_path)) {
272 DVLOG(1) << "Unzip failed: unable to create containing directory.";
273 base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback);
274 return;
275 }
276
277 const int flags = (base::PLATFORM_FILE_CREATE_ALWAYS |
278 base::PLATFORM_FILE_WRITE);
279 bool created = false;
280 base::PlatformFileError platform_file_error;
281 base::PlatformFile output_file = CreatePlatformFile(output_file_path,
282 flags,
283 &created,
284 &platform_file_error);
285
286 if (platform_file_error != base::PLATFORM_FILE_OK) {
287 DVLOG(1) << "Unzip failed: unable to create platform file at "
288 << output_file_path.value();
289 base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback);
290 return;
291 }
292
293 base::MessageLoop::current()->PostTask(
294 FROM_HERE,
295 base::Bind(&ZipReader::ExtractChunk,
296 weak_ptr_factory_.GetWeakPtr(),
297 output_file,
298 success_callback,
299 failure_callback,
300 progress_callback,
301 0 /* initial offset */));
302 }
303
238 bool ZipReader::ExtractCurrentEntryIntoDirectory( 304 bool ZipReader::ExtractCurrentEntryIntoDirectory(
239 const base::FilePath& output_directory_path) { 305 const base::FilePath& output_directory_path) {
240 DCHECK(current_entry_info_.get()); 306 DCHECK(current_entry_info_.get());
241 307
242 base::FilePath output_file_path = output_directory_path.Append( 308 base::FilePath output_file_path = output_directory_path.Append(
243 current_entry_info()->file_path()); 309 current_entry_info()->file_path());
244 return ExtractCurrentEntryToFilePath(output_file_path); 310 return ExtractCurrentEntryToFilePath(output_file_path);
245 } 311 }
246 312
247 #if defined(OS_POSIX) 313 #if defined(OS_POSIX)
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 return true; 366 return true;
301 } 367 }
302 368
303 void ZipReader::Reset() { 369 void ZipReader::Reset() {
304 zip_file_ = NULL; 370 zip_file_ = NULL;
305 num_entries_ = 0; 371 num_entries_ = 0;
306 reached_end_ = false; 372 reached_end_ = false;
307 current_entry_info_.reset(); 373 current_entry_info_.reset();
308 } 374 }
309 375
376 void ZipReader::ExtractChunk(base::PlatformFile output_file,
377 SuccessCallback success_callback,
378 FailureCallback failure_callback,
379 ProgressCallback progress_callback,
380 const int64 offset) {
381 char buffer[internal::kZipBufSize];
382
383 const int num_bytes_read = unzReadCurrentFile(zip_file_,
384 buffer,
385 internal::kZipBufSize);
386
387 if (num_bytes_read == 0) {
388 unzCloseCurrentFile(zip_file_);
389 base::ClosePlatformFile(output_file);
390 base::MessageLoopProxy::current()->PostTask(FROM_HERE, success_callback);
satorux1 2013/12/12 08:13:01 ExtractChunk() was called asynchronously, so it's
Drew Haven 2013/12/12 22:06:17 Oh, you're completely right. Done. I didn't even
391 } else if (num_bytes_read < 0) {
392 DVLOG(1) << "Unzip failed: error while reading zipfile "
393 << "(" << num_bytes_read << ")";
394 base::ClosePlatformFile(output_file);
395 base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback);
396 } else {
397 if (num_bytes_read != base::WritePlatformFileAtCurrentPos(output_file,
398 buffer,
399 num_bytes_read)) {
400 DVLOG(1) << "Unzip failed: unable to write all bytes to target.";
401 base::ClosePlatformFile(output_file);
402 base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback);
403 return;
404 }
405
406 int64 curr_progress = offset + num_bytes_read;
407
408 progress_callback.Run(curr_progress);
409
410 base::MessageLoop::current()->PostTask(
411 FROM_HERE,
412 base::Bind(&ZipReader::ExtractChunk,
413 weak_ptr_factory_.GetWeakPtr(),
414 output_file,
415 success_callback,
416 failure_callback,
417 progress_callback,
418 curr_progress));
419
420 }
421 }
422
423
310 } // namespace zip 424 } // namespace zip
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698