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

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

Issue 179963002: New Zip::ZipFromMemory API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: addressing comments Created 6 years, 9 months 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/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
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
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 size_t 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<size_t>(
376 max_read_bytes, current_entry_info()->original_size()) + 1);
377
378 size_t 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 size_t bytes_to_read = contents.capacity() - buffer_index;
386 const int bytes_to_read_really = std::min<int>(INT_MAX, bytes_to_read);
387 const int bytes_read = unzReadCurrentFile(
388 zip_file_,
389 &(contents[buffer_index]),
390 bytes_to_read_really);
391 DCHECK(bytes_read <= bytes_to_read_really);
392
393 if (bytes_read == 0) {
394 contents.resize(buffer_index);
395 // Reached the end of the file.
396 break;
397 } else if (bytes_read < 0) {
398 // If num_bytes_read < 0, then it's a specific UNZ_* error code.
399 success = false;
400 break;
401 } else { // if (num_bytes_read > 0)
402 buffer_index += bytes_read;
403
404 if (buffer_index > max_read_bytes) {
405 success = false;
406 break;
407 }
408
409 if (bytes_read == bytes_to_read_really) {
410 // Filled up the buffer, no more space left, need to resize.
411 if (static_cast<size_t>(bytes_to_read_really) == bytes_to_read)
412 contents.reserve(contents.capacity() + internal::kZipBufSize);
413 } else {
414 contents.resize(buffer_index);
415 // Read less bytes than asked. That means it reached end of file.
416 break;
417 }
418 }
419 }
420
421 unzCloseCurrentFile(zip_file_);
422 if (success)
423 output->swap(contents);
424
425 return success;
426 }
427
354 bool ZipReader::OpenInternal() { 428 bool ZipReader::OpenInternal() {
355 DCHECK(zip_file_); 429 DCHECK(zip_file_);
356 430
357 unz_global_info zip_info = {}; // Zero-clear. 431 unz_global_info zip_info = {}; // Zero-clear.
358 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) { 432 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) {
359 return false; 433 return false;
360 } 434 }
361 num_entries_ = zip_info.number_entry; 435 num_entries_ = zip_info.number_entry;
362 if (num_entries_ < 0) 436 if (num_entries_ < 0)
363 return false; 437 return false;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 success_callback, 491 success_callback,
418 failure_callback, 492 failure_callback,
419 progress_callback, 493 progress_callback,
420 current_progress)); 494 current_progress));
421 495
422 } 496 }
423 } 497 }
424 498
425 499
426 } // namespace zip 500 } // namespace zip
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698