Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 const SuccessCallback& success_callback, | |
| 243 const FailureCallback& failure_callback, | |
| 244 const 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 Loading... | |
| 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 const SuccessCallback& success_callback, | |
| 378 const FailureCallback& failure_callback, | |
| 379 const 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 success_callback.Run(); | |
| 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 failure_callback.Run(); | |
| 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 failure_callback.Run(); | |
| 403 return; | |
| 404 } | |
| 405 | |
| 406 int64 curr_progress = offset + num_bytes_read; | |
|
satorux1
2013/12/13 07:55:09
nit curr -> current in favor of less abbreviation
Drew Haven
2013/12/13 18:36:11
Done.
| |
| 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 |
| OLD | NEW |