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/message_loop/message_loop.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 zip_file_ = internal::OpenHandleForUnzipping(zip_fd); | 100 zip_file_ = internal::OpenHandleForUnzipping(zip_fd); |
101 #endif | 101 #endif |
102 if (!zip_file_) { | 102 if (!zip_file_) { |
103 return false; | 103 return false; |
104 } | 104 } |
105 | 105 |
106 return OpenInternal(); | 106 return OpenInternal(); |
107 } | 107 } |
108 | 108 |
109 bool ZipReader::OpenFromString(const std::string& data) { | 109 bool ZipReader::OpenFromString(const std::string& data) { |
110 zip_file_ = internal::PreprareMemoryForUnzipping(data); | 110 zip_file_ = internal::PrepareMemoryForUnzipping(data); |
111 if (!zip_file_) | 111 if (!zip_file_) |
112 return false; | 112 return false; |
113 return OpenInternal(); | 113 return OpenInternal(); |
114 } | 114 } |
115 | 115 |
116 void ZipReader::Close() { | 116 void ZipReader::Close() { |
117 if (zip_file_) { | 117 if (zip_file_) { |
118 unzClose(zip_file_); | 118 unzClose(zip_file_); |
119 } | 119 } |
120 Reset(); | 120 Reset(); |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 break; | 344 break; |
345 } | 345 } |
346 } | 346 } |
347 } | 347 } |
348 | 348 |
349 unzCloseCurrentFile(zip_file_); | 349 unzCloseCurrentFile(zip_file_); |
350 return success; | 350 return success; |
351 } | 351 } |
352 #endif // defined(OS_POSIX) | 352 #endif // defined(OS_POSIX) |
353 | 353 |
| 354 bool ZipReader::ExtractCurrentEntryToString( |
| 355 int max_read_bytes, |
| 356 std::string* output) const { |
| 357 DCHECK(output); |
| 358 DCHECK(zip_file_); |
| 359 DCHECK(max_read_bytes > 0); |
| 360 |
| 361 if (current_entry_info()->is_directory()) { |
| 362 output->clear(); |
| 363 return true; |
| 364 } |
| 365 |
| 366 const int open_result = unzOpenCurrentFile(zip_file_); |
| 367 if (open_result != UNZ_OK) |
| 368 return false; |
| 369 |
| 370 // The original_size() is the best hint for the real size, so it saves |
| 371 // doing reallocations for the common case when the uncompressed size is |
| 372 // correct. However, we need to assume that the uncompressed size could be |
| 373 // incorrect therefore this function needs to read as much data as possible. |
| 374 std::string contents; |
| 375 contents.reserve(std::min<int64>( |
| 376 max_read_bytes, current_entry_info()->original_size()) + 1); |
| 377 |
| 378 int buffer_index = 0; |
| 379 bool success = true; |
| 380 while (true) { |
| 381 // This just sets size() to be equal to capacity() so the chars which are re
ad |
| 382 // ahead will not be erased by calling resize() later. |
| 383 contents.resize(contents.capacity()); |
| 384 |
| 385 const int bytes_to_read = contents.capacity() - buffer_index; |
| 386 const int bytes_read = unzReadCurrentFile( |
| 387 zip_file_, |
| 388 &(contents[buffer_index]), |
| 389 bytes_to_read); |
| 390 DCHECK(bytes_read <= bytes_to_read); |
| 391 |
| 392 if (bytes_read == 0) { |
| 393 contents.resize(buffer_index); |
| 394 // Reached the end of the file. |
| 395 break; |
| 396 } else if (bytes_read < 0) { |
| 397 // If num_bytes_read < 0, then it's a specific UNZ_* error code. |
| 398 success = false; |
| 399 break; |
| 400 } else { // if (num_bytes_read > 0) |
| 401 buffer_index += bytes_read; |
| 402 |
| 403 if (buffer_index > max_read_bytes) { |
| 404 success = false; |
| 405 break; |
| 406 } |
| 407 |
| 408 if (bytes_read == bytes_to_read) { |
| 409 // Filled up the buffer, no more space left, need to resize. |
| 410 contents.reserve(contents.capacity() + internal::kZipBufSize); |
| 411 } else { |
| 412 contents.resize(buffer_index); |
| 413 // Read less bytes than asked. That means it reached end of file. |
| 414 break; |
| 415 } |
| 416 } |
| 417 } |
| 418 |
| 419 unzCloseCurrentFile(zip_file_); |
| 420 if (success) |
| 421 output->swap(contents); |
| 422 |
| 423 return success; |
| 424 } |
| 425 |
354 bool ZipReader::OpenInternal() { | 426 bool ZipReader::OpenInternal() { |
355 DCHECK(zip_file_); | 427 DCHECK(zip_file_); |
356 | 428 |
357 unz_global_info zip_info = {}; // Zero-clear. | 429 unz_global_info zip_info = {}; // Zero-clear. |
358 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) { | 430 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) { |
359 return false; | 431 return false; |
360 } | 432 } |
361 num_entries_ = zip_info.number_entry; | 433 num_entries_ = zip_info.number_entry; |
362 if (num_entries_ < 0) | 434 if (num_entries_ < 0) |
363 return false; | 435 return false; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 success_callback, | 489 success_callback, |
418 failure_callback, | 490 failure_callback, |
419 progress_callback, | 491 progress_callback, |
420 current_progress)); | 492 current_progress)); |
421 | 493 |
422 } | 494 } |
423 } | 495 } |
424 | 496 |
425 | 497 |
426 } // namespace zip | 498 } // namespace zip |
OLD | NEW |