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/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
10 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
11 #include "net/base/file_stream.h" | 12 #include "net/base/file_stream.h" |
12 #include "third_party/zlib/google/zip_internal.h" | 13 #include "third_party/zlib/google/zip_internal.h" |
13 | 14 |
14 #if defined(USE_SYSTEM_MINIZIP) | 15 #if defined(USE_SYSTEM_MINIZIP) |
15 #include <minizip/unzip.h> | 16 #include <minizip/unzip.h> |
16 #else | 17 #else |
17 #include "third_party/zlib/contrib/minizip/unzip.h" | 18 #include "third_party/zlib/contrib/minizip/unzip.h" |
18 #if defined(OS_WIN) | 19 #if defined(OS_WIN) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
62 exploded_time.second = raw_file_info.tmu_date.tm_sec; | 63 exploded_time.second = raw_file_info.tmu_date.tm_sec; |
63 exploded_time.millisecond = 0; | 64 exploded_time.millisecond = 0; |
64 if (exploded_time.HasValidValues()) { | 65 if (exploded_time.HasValidValues()) { |
65 last_modified_ = base::Time::FromLocalExploded(exploded_time); | 66 last_modified_ = base::Time::FromLocalExploded(exploded_time); |
66 } else { | 67 } else { |
67 // Use Unix time epoch if the time stamp data is invalid. | 68 // Use Unix time epoch if the time stamp data is invalid. |
68 last_modified_ = base::Time::UnixEpoch(); | 69 last_modified_ = base::Time::UnixEpoch(); |
69 } | 70 } |
70 } | 71 } |
71 | 72 |
72 ZipReader::ZipReader() { | 73 ZipReader::ZipReader() |
74 : weak_ptr_factory_(this) { | |
73 Reset(); | 75 Reset(); |
74 } | 76 } |
75 | 77 |
76 ZipReader::~ZipReader() { | 78 ZipReader::~ZipReader() { |
77 Close(); | 79 Close(); |
78 } | 80 } |
79 | 81 |
80 bool ZipReader::Open(const base::FilePath& zip_file_path) { | 82 bool ZipReader::Open(const base::FilePath& zip_file_path) { |
81 DCHECK(!zip_file_); | 83 DCHECK(!zip_file_); |
82 | 84 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
228 success = false; | 230 success = false; |
229 break; | 231 break; |
230 } | 232 } |
231 } | 233 } |
232 } | 234 } |
233 | 235 |
234 unzCloseCurrentFile(zip_file_); | 236 unzCloseCurrentFile(zip_file_); |
235 return success; | 237 return success; |
236 } | 238 } |
237 | 239 |
240 void ZipReader::ExtractCurrentEntryToFilePathAsync( | |
241 const base::FilePath& output_file_path, | |
242 const SuccessCallback& success_callback, | |
243 const FailureCallback& failure_callback, | |
244 const ProgressCallback& progress_callback) { | |
245 DCHECK(zip_file_); | |
246 DCHECK(current_entry_info_.get()); | |
247 | |
248 // If this is a directory, just create it and return. | |
249 if (current_entry_info()->is_directory()) { | |
250 if (base::CreateDirectory(output_file_path)) { | |
251 base::MessageLoopProxy::current()->PostTask(FROM_HERE, success_callback); | |
252 } else { | |
253 DVLOG(1) << "Unzip failed: unable to create directory."; | |
254 base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback); | |
255 } | |
256 return; | |
257 } | |
258 | |
259 if (current_entry_info()->is_directory()) { | |
260 DVLOG(1) << "Unzip failed: Cannot unzip a directory to an open file."; | |
261 base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback); | |
262 } | |
263 | |
264 if (unzOpenCurrentFile(zip_file_) != UNZ_OK) { | |
265 DVLOG(1) << "Unzip failed: unable to open current zip entry."; | |
266 base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback); | |
267 return; | |
268 } | |
269 | |
270 base::FilePath output_dir_path = output_file_path.DirName(); | |
271 if (!base::CreateDirectory(output_dir_path)) { | |
272 DVLOG(1) << "Unzip failed: unable to create containing directory."; | |
273 base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback); | |
274 return; | |
275 } | |
276 | |
277 const int flags = (base::PLATFORM_FILE_CREATE_ALWAYS | | |
278 base::PLATFORM_FILE_WRITE); | |
279 bool created = false; | |
280 base::PlatformFileError platform_file_error; | |
281 base::PlatformFile output_file = CreatePlatformFile(output_file_path, | |
282 flags, | |
283 &created, | |
284 &platform_file_error); | |
285 | |
286 if (platform_file_error != base::PLATFORM_FILE_OK) { | |
287 DVLOG(1) << "Unzip failed: unable to create platform file at " | |
288 << output_file_path.value(); | |
289 base::MessageLoopProxy::current()->PostTask(FROM_HERE, failure_callback); | |
290 return; | |
291 } | |
292 | |
293 base::MessageLoop::current()->PostTask( | |
294 FROM_HERE, | |
295 base::Bind(&ZipReader::ExtractChunk, | |
296 weak_ptr_factory_.GetWeakPtr(), | |
297 output_file, | |
298 success_callback, | |
299 failure_callback, | |
300 progress_callback, | |
301 0 /* initial offset */)); | |
302 } | |
303 | |
238 bool ZipReader::ExtractCurrentEntryIntoDirectory( | 304 bool ZipReader::ExtractCurrentEntryIntoDirectory( |
239 const base::FilePath& output_directory_path) { | 305 const base::FilePath& output_directory_path) { |
240 DCHECK(current_entry_info_.get()); | 306 DCHECK(current_entry_info_.get()); |
241 | 307 |
242 base::FilePath output_file_path = output_directory_path.Append( | 308 base::FilePath output_file_path = output_directory_path.Append( |
243 current_entry_info()->file_path()); | 309 current_entry_info()->file_path()); |
244 return ExtractCurrentEntryToFilePath(output_file_path); | 310 return ExtractCurrentEntryToFilePath(output_file_path); |
245 } | 311 } |
246 | 312 |
247 #if defined(OS_POSIX) | 313 #if defined(OS_POSIX) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
300 return true; | 366 return true; |
301 } | 367 } |
302 | 368 |
303 void ZipReader::Reset() { | 369 void ZipReader::Reset() { |
304 zip_file_ = NULL; | 370 zip_file_ = NULL; |
305 num_entries_ = 0; | 371 num_entries_ = 0; |
306 reached_end_ = false; | 372 reached_end_ = false; |
307 current_entry_info_.reset(); | 373 current_entry_info_.reset(); |
308 } | 374 } |
309 | 375 |
376 void ZipReader::ExtractChunk(base::PlatformFile output_file, | |
377 const SuccessCallback& success_callback, | |
378 const FailureCallback& failure_callback, | |
379 const ProgressCallback& progress_callback, | |
380 const int64 offset) { | |
381 char buffer[internal::kZipBufSize]; | |
382 | |
383 const int num_bytes_read = unzReadCurrentFile(zip_file_, | |
384 buffer, | |
385 internal::kZipBufSize); | |
386 | |
387 if (num_bytes_read == 0) { | |
388 unzCloseCurrentFile(zip_file_); | |
389 base::ClosePlatformFile(output_file); | |
390 success_callback.Run(); | |
391 } else if (num_bytes_read < 0) { | |
392 DVLOG(1) << "Unzip failed: error while reading zipfile " | |
393 << "(" << num_bytes_read << ")"; | |
394 base::ClosePlatformFile(output_file); | |
395 failure_callback.Run(); | |
396 } else { | |
397 if (num_bytes_read != base::WritePlatformFileAtCurrentPos(output_file, | |
398 buffer, | |
399 num_bytes_read)) { | |
400 DVLOG(1) << "Unzip failed: unable to write all bytes to target."; | |
401 base::ClosePlatformFile(output_file); | |
402 failure_callback.Run(); | |
403 return; | |
404 } | |
405 | |
406 int64 curr_progress = offset + num_bytes_read; | |
satorux1
2013/12/13 07:55:09
nit curr -> current in favor of less abbreviation
Drew Haven
2013/12/13 18:36:11
Done.
| |
407 | |
408 progress_callback.Run(curr_progress); | |
409 | |
410 base::MessageLoop::current()->PostTask( | |
411 FROM_HERE, | |
412 base::Bind(&ZipReader::ExtractChunk, | |
413 weak_ptr_factory_.GetWeakPtr(), | |
414 output_file, | |
415 success_callback, | |
416 failure_callback, | |
417 progress_callback, | |
418 curr_progress)); | |
419 | |
420 } | |
421 } | |
422 | |
423 | |
310 } // namespace zip | 424 } // namespace zip |
OLD | NEW |