OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/common/zip_reader.h" | 5 #include "chrome/common/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/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 bool ZipReader::Open(const FilePath& zip_file_path) { | 75 bool ZipReader::Open(const FilePath& zip_file_path) { |
76 DCHECK(!zip_file_); | 76 DCHECK(!zip_file_); |
77 | 77 |
78 // Use of "Unsafe" function does not look good, but there is no way to do | 78 // Use of "Unsafe" function does not look good, but there is no way to do |
79 // this safely on Linux. See file_util.h for details. | 79 // this safely on Linux. See file_util.h for details. |
80 zip_file_ = internal::OpenForUnzipping(zip_file_path.AsUTF8Unsafe()); | 80 zip_file_ = internal::OpenForUnzipping(zip_file_path.AsUTF8Unsafe()); |
81 if (!zip_file_) { | 81 if (!zip_file_) { |
82 return false; | 82 return false; |
83 } | 83 } |
84 | 84 |
85 unz_global_info zip_info = {}; // Zero-clear. | 85 return OpenInternal(); |
86 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) { | 86 } |
| 87 |
| 88 #if defined(OS_POSIX) |
| 89 bool ZipReader::OpenFromFd(const int zip_fd) { |
| 90 DCHECK(!zip_file_); |
| 91 |
| 92 zip_file_ = internal::OpenFdForUnzipping(zip_fd); |
| 93 if (!zip_file_) { |
87 return false; | 94 return false; |
88 } | 95 } |
89 num_entries_ = zip_info.number_entry; | |
90 if (num_entries_ < 0) | |
91 return false; | |
92 | 96 |
93 // We are already at the end if the zip file is empty. | 97 return OpenInternal(); |
94 reached_end_ = (num_entries_ == 0); | |
95 return true; | |
96 } | 98 } |
| 99 #endif |
97 | 100 |
98 void ZipReader::Close() { | 101 void ZipReader::Close() { |
99 if (zip_file_) { | 102 if (zip_file_) { |
100 unzClose(zip_file_); | 103 unzClose(zip_file_); |
101 } | 104 } |
102 Reset(); | 105 Reset(); |
103 } | 106 } |
104 | 107 |
105 bool ZipReader::HasMore() { | 108 bool ZipReader::HasMore() { |
106 return !reached_end_; | 109 return !reached_end_; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 | 225 |
223 bool ZipReader::ExtractCurrentEntryIntoDirectory( | 226 bool ZipReader::ExtractCurrentEntryIntoDirectory( |
224 const FilePath& output_directory_path) { | 227 const FilePath& output_directory_path) { |
225 DCHECK(current_entry_info_.get()); | 228 DCHECK(current_entry_info_.get()); |
226 | 229 |
227 FilePath output_file_path = output_directory_path.Append( | 230 FilePath output_file_path = output_directory_path.Append( |
228 current_entry_info()->file_path()); | 231 current_entry_info()->file_path()); |
229 return ExtractCurrentEntryToFilePath(output_file_path); | 232 return ExtractCurrentEntryToFilePath(output_file_path); |
230 } | 233 } |
231 | 234 |
| 235 #if defined(OS_POSIX) |
| 236 bool ZipReader::ExtractCurrentEntryToFd(const int fd) { |
| 237 DCHECK(zip_file_); |
| 238 |
| 239 // If this is a directory, there's nothing to extract to the file descriptor, |
| 240 // so return false. |
| 241 if (current_entry_info()->is_directory()) |
| 242 return false; |
| 243 |
| 244 const int open_result = unzOpenCurrentFile(zip_file_); |
| 245 if (open_result != UNZ_OK) |
| 246 return false; |
| 247 |
| 248 bool success = true; // This becomes false when something bad happens. |
| 249 while (true) { |
| 250 char buf[internal::kZipBufSize]; |
| 251 const int num_bytes_read = unzReadCurrentFile(zip_file_, buf, |
| 252 internal::kZipBufSize); |
| 253 if (num_bytes_read == 0) { |
| 254 // Reached the end of the file. |
| 255 break; |
| 256 } else if (num_bytes_read < 0) { |
| 257 // If num_bytes_read < 0, then it's a specific UNZ_* error code. |
| 258 success = false; |
| 259 break; |
| 260 } else if (num_bytes_read > 0) { |
| 261 // Some data is read. Write it to the output file descriptor. |
| 262 if (num_bytes_read != |
| 263 file_util::WriteFileDescriptor(fd, buf, num_bytes_read)) { |
| 264 success = false; |
| 265 break; |
| 266 } |
| 267 } |
| 268 } |
| 269 |
| 270 unzCloseCurrentFile(zip_file_); |
| 271 return success; |
| 272 } |
| 273 #endif // defined(OS_POSIX) |
| 274 |
| 275 bool ZipReader::OpenInternal() { |
| 276 DCHECK(zip_file_); |
| 277 |
| 278 unz_global_info zip_info = {}; // Zero-clear. |
| 279 if (unzGetGlobalInfo(zip_file_, &zip_info) != UNZ_OK) { |
| 280 return false; |
| 281 } |
| 282 num_entries_ = zip_info.number_entry; |
| 283 if (num_entries_ < 0) |
| 284 return false; |
| 285 |
| 286 // We are already at the end if the zip file is empty. |
| 287 reached_end_ = (num_entries_ == 0); |
| 288 return true; |
| 289 } |
| 290 |
232 void ZipReader::Reset() { | 291 void ZipReader::Reset() { |
233 zip_file_ = NULL; | 292 zip_file_ = NULL; |
234 num_entries_ = 0; | 293 num_entries_ = 0; |
235 reached_end_ = false; | 294 reached_end_ = false; |
236 current_entry_info_.reset(); | 295 current_entry_info_.reset(); |
237 } | 296 } |
238 | 297 |
239 } // namespace zip | 298 } // namespace zip |
OLD | NEW |