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/memory/ref_counted_memory.h" |
9 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
10 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
11 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
12 #include "net/base/file_stream.h" | 13 #include "net/base/file_stream.h" |
13 #include "third_party/zlib/google/zip_internal.h" | 14 #include "third_party/zlib/google/zip_internal.h" |
14 | 15 |
15 #if defined(USE_SYSTEM_MINIZIP) | 16 #if defined(USE_SYSTEM_MINIZIP) |
16 #include <minizip/unzip.h> | 17 #include <minizip/unzip.h> |
17 #else | 18 #else |
18 #include "third_party/zlib/contrib/minizip/unzip.h" | 19 #include "third_party/zlib/contrib/minizip/unzip.h" |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 break; | 345 break; |
345 } | 346 } |
346 } | 347 } |
347 } | 348 } |
348 | 349 |
349 unzCloseCurrentFile(zip_file_); | 350 unzCloseCurrentFile(zip_file_); |
350 return success; | 351 return success; |
351 } | 352 } |
352 #endif // defined(OS_POSIX) | 353 #endif // defined(OS_POSIX) |
353 | 354 |
| 355 bool ZipReader::ExtractCurrentEntryToRefCountedMemory( |
| 356 int max_read_bytes, |
| 357 base::RefCountedMemory** output) const { |
| 358 DCHECK(output); |
| 359 DCHECK(zip_file_); |
| 360 DCHECK(max_read_bytes > 0); |
| 361 |
| 362 if (current_entry_info()->is_directory()) { |
| 363 *output = NULL; |
| 364 return true; |
| 365 } |
| 366 |
| 367 const int open_result = unzOpenCurrentFile(zip_file_); |
| 368 if (open_result != UNZ_OK) |
| 369 return false; |
| 370 |
| 371 // The original_size() is the best hint for the real size, so it saves |
| 372 // doing reallocations for the common case when the uncompressed size is |
| 373 // correct. However, we need to assume that the uncompressed size could be |
| 374 // incorrect therefore this function needs to read as much data as possible. |
| 375 std::vector<unsigned char> contents(std::min<int64>( |
| 376 max_read_bytes, current_entry_info()->original_size()) + 1, 0); |
| 377 |
| 378 int buffer_index = 0; |
| 379 bool success = true; |
| 380 while (true) { |
| 381 const int bytes_to_read = contents.size() - buffer_index; |
| 382 const int bytes_read = unzReadCurrentFile( |
| 383 zip_file_, |
| 384 &(contents[buffer_index]), |
| 385 bytes_to_read); |
| 386 DCHECK(bytes_read <= bytes_to_read); |
| 387 |
| 388 if (bytes_read == 0) { |
| 389 contents.resize(buffer_index, 0); |
| 390 // Reached the end of the file. |
| 391 break; |
| 392 } else if (bytes_read < 0) { |
| 393 // If num_bytes_read < 0, then it's a specific UNZ_* error code. |
| 394 success = false; |
| 395 break; |
| 396 } else { // if (num_bytes_read > 0) |
| 397 buffer_index += bytes_read; |
| 398 |
| 399 if (buffer_index > max_read_bytes) { |
| 400 success = false; |
| 401 break; |
| 402 } |
| 403 |
| 404 if (bytes_read == bytes_to_read) { |
| 405 // Filled up the buffer, no more space left, need to resize. |
| 406 contents.resize(contents.size() + internal::kZipBufSize, 0); |
| 407 } else { |
| 408 contents.resize(buffer_index, 0); |
| 409 // Read less bytes than asked. That means it reached end of file. |
| 410 break; |
| 411 } |
| 412 } |
| 413 } |
| 414 |
| 415 unzCloseCurrentFile(zip_file_); |
| 416 if (success) |
| 417 *output = base::RefCountedBytes::TakeVector(&contents); |
| 418 |
| 419 return success; |
| 420 } |
| 421 |
| 422 bool ZipReader::ExtractCurrentEntryToRefCountedMemory( |
| 423 int max_read_bytes, |
| 424 scoped_refptr<base::RefCountedMemory>* output) const { |
| 425 DCHECK(output); |
| 426 base::RefCountedMemory* ptr = NULL; |
| 427 bool result = ExtractCurrentEntryToRefCountedMemory(max_read_bytes, &ptr); |
| 428 if (result && ptr) |
| 429 *output = make_scoped_refptr(ptr); |
| 430 return result; |
| 431 } |
| 432 |
354 bool ZipReader::OpenInternal() { | 433 bool ZipReader::OpenInternal() { |
355 DCHECK(zip_file_); | 434 DCHECK(zip_file_); |
356 | 435 |
357 unz_global_info zip_info = {}; // Zero-clear. | 436 unz_global_info zip_info = {}; // Zero-clear. |
358 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) { | 437 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) { |
359 return false; | 438 return false; |
360 } | 439 } |
361 num_entries_ = zip_info.number_entry; | 440 num_entries_ = zip_info.number_entry; |
362 if (num_entries_ < 0) | 441 if (num_entries_ < 0) |
363 return false; | 442 return false; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 success_callback, | 496 success_callback, |
418 failure_callback, | 497 failure_callback, |
419 progress_callback, | 498 progress_callback, |
420 current_progress)); | 499 current_progress)); |
421 | 500 |
422 } | 501 } |
423 } | 502 } |
424 | 503 |
425 | 504 |
426 } // namespace zip | 505 } // namespace zip |
OLD | NEW |