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 <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/files/file.h" | 10 #include "base/files/file.h" |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 break; | 318 break; |
319 } | 319 } |
320 } | 320 } |
321 } | 321 } |
322 | 322 |
323 unzCloseCurrentFile(zip_file_); | 323 unzCloseCurrentFile(zip_file_); |
324 | 324 |
325 return success; | 325 return success; |
326 } | 326 } |
327 | 327 |
| 328 bool ZipReader::ExtractPartOfCurrentEntry(WriterDelegate* delegate, |
| 329 size_t num_bytes) const { |
| 330 DCHECK(zip_file_); |
| 331 |
| 332 const int open_result = unzOpenCurrentFile(zip_file_); |
| 333 if (open_result != UNZ_OK) |
| 334 return false; |
| 335 |
| 336 if (!delegate->PrepareOutput()) |
| 337 return false; |
| 338 |
| 339 bool success = true; // This becomes false when something bad happens. |
| 340 std::unique_ptr<char[]> buf(new char[num_bytes]); |
| 341 size_t total_num_bytes_read = 0; |
| 342 while (true) { |
| 343 const int num_bytes_read = unzReadCurrentFile( |
| 344 zip_file_, buf.get(), base::checked_cast<unsigned int>(num_bytes)); |
| 345 if (num_bytes_read < 0) { |
| 346 // If num_bytes_read < 0, then it's a specific UNZ_* error code. |
| 347 success = false; |
| 348 break; |
| 349 } else if (num_bytes_read > 0) { |
| 350 // Some data is read. |
| 351 if (!delegate->WriteBytes(buf.get(), num_bytes_read)) { |
| 352 success = false; |
| 353 break; |
| 354 } |
| 355 } |
| 356 // Previous check ensures that num_bytes_read is not negative here. |
| 357 total_num_bytes_read += base::checked_cast<size_t>(num_bytes_read); |
| 358 if (total_num_bytes_read == num_bytes) { |
| 359 // Read all the data. |
| 360 break; |
| 361 } |
| 362 } |
| 363 |
| 364 unzCloseCurrentFile(zip_file_); |
| 365 |
| 366 return success; |
| 367 } |
| 368 |
328 bool ZipReader::ExtractCurrentEntryToFilePath( | 369 bool ZipReader::ExtractCurrentEntryToFilePath( |
329 const base::FilePath& output_file_path) const { | 370 const base::FilePath& output_file_path) const { |
330 DCHECK(zip_file_); | 371 DCHECK(zip_file_); |
331 | 372 |
332 // If this is a directory, just create it and return. | 373 // If this is a directory, just create it and return. |
333 if (current_entry_info()->is_directory()) | 374 if (current_entry_info()->is_directory()) |
334 return base::CreateDirectory(output_file_path); | 375 return base::CreateDirectory(output_file_path); |
335 | 376 |
336 bool success = false; | 377 bool success = false; |
337 { | 378 { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 static_cast<size_t>(std::min(static_cast<int64_t>(max_read_bytes), | 480 static_cast<size_t>(std::min(static_cast<int64_t>(max_read_bytes), |
440 current_entry_info()->original_size()))); | 481 current_entry_info()->original_size()))); |
441 | 482 |
442 StringWriterDelegate writer(max_read_bytes, &contents); | 483 StringWriterDelegate writer(max_read_bytes, &contents); |
443 if (!ExtractCurrentEntry(&writer)) | 484 if (!ExtractCurrentEntry(&writer)) |
444 return false; | 485 return false; |
445 output->swap(contents); | 486 output->swap(contents); |
446 return true; | 487 return true; |
447 } | 488 } |
448 | 489 |
| 490 bool ZipReader::ExtractPartOfCurrentEntryToString(size_t num_bytes, |
| 491 std::string* output) const { |
| 492 DCHECK(output); |
| 493 DCHECK(zip_file_); |
| 494 DCHECK_NE(0U, num_bytes); |
| 495 |
| 496 if (current_entry_info()->is_directory()) { |
| 497 output->clear(); |
| 498 return true; |
| 499 } |
| 500 |
| 501 std::string contents; |
| 502 contents.reserve(num_bytes); |
| 503 |
| 504 StringWriterDelegate writer(num_bytes, &contents); |
| 505 if (!ExtractPartOfCurrentEntry(&writer, num_bytes)) |
| 506 return false; |
| 507 output->swap(contents); |
| 508 return true; |
| 509 } |
| 510 |
449 bool ZipReader::OpenInternal() { | 511 bool ZipReader::OpenInternal() { |
450 DCHECK(zip_file_); | 512 DCHECK(zip_file_); |
451 | 513 |
452 unz_global_info zip_info = {}; // Zero-clear. | 514 unz_global_info zip_info = {}; // Zero-clear. |
453 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) { | 515 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) { |
454 return false; | 516 return false; |
455 } | 517 } |
456 num_entries_ = zip_info.number_entry; | 518 num_entries_ = zip_info.number_entry; |
457 if (num_entries_ < 0) | 519 if (num_entries_ < 0) |
458 return false; | 520 return false; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 } | 586 } |
525 | 587 |
526 bool FileWriterDelegate::WriteBytes(const char* data, int num_bytes) { | 588 bool FileWriterDelegate::WriteBytes(const char* data, int num_bytes) { |
527 int bytes_written = file_->WriteAtCurrentPos(data, num_bytes); | 589 int bytes_written = file_->WriteAtCurrentPos(data, num_bytes); |
528 if (bytes_written > 0) | 590 if (bytes_written > 0) |
529 file_length_ += bytes_written; | 591 file_length_ += bytes_written; |
530 return bytes_written == num_bytes; | 592 return bytes_written == num_bytes; |
531 } | 593 } |
532 | 594 |
533 } // namespace zip | 595 } // namespace zip |
OLD | NEW |