| OLD | NEW |
| 1 // Copyright 2017 The Chromium OS Authors. All rights reserved. | 1 // Copyright 2017 The Chromium OS 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 "compressor_archive_libarchive.h" | 5 #include "compressor_archive_libarchive.h" |
| 6 | 6 |
| 7 #include <cerrno> | 7 #include <cerrno> |
| 8 #include <cstring> | 8 #include <cstring> |
| 9 | 9 |
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 return 0 /* Success */; | 25 return 0 /* Success */; |
| 26 } | 26 } |
| 27 | 27 |
| 28 // Called when data chunk must be written on the archive. It copies data | 28 // Called when data chunk must be written on the archive. It copies data |
| 29 // from the given buffer processed by minizip to an array buffer and passes | 29 // from the given buffer processed by minizip to an array buffer and passes |
| 30 // it to compressor_stream. | 30 // it to compressor_stream. |
| 31 uLong CustomArchiveWrite(void* compressor, | 31 uLong CustomArchiveWrite(void* compressor, |
| 32 void* /*stream*/, | 32 void* /*stream*/, |
| 33 const void* zip_buffer, | 33 const void* zip_buffer, |
| 34 uLong zip_length) { | 34 uLong zip_length) { |
| 35 CompressorArchiveLibarchive* compressor_libarchive = | 35 CompressorArchiveMinizip* compressor_minizip = |
| 36 static_cast<CompressorArchiveLibarchive*>(compressor); | 36 static_cast<CompressorArchiveMinizip*>(compressor); |
| 37 | 37 |
| 38 int64_t written_bytes = compressor_libarchive->compressor_stream()->Write( | 38 int64_t written_bytes = compressor_minizip->compressor_stream()->Write( |
| 39 compressor_libarchive->offset_, zip_length, | 39 compressor_minizip->offset_, zip_length, |
| 40 static_cast<const char*>(zip_buffer)); | 40 static_cast<const char*>(zip_buffer)); |
| 41 | 41 |
| 42 if (written_bytes != zip_length) | 42 if (written_bytes != zip_length) |
| 43 return 0 /* Error */; | 43 return 0 /* Error */; |
| 44 | 44 |
| 45 // Update offset_ and length_. | 45 // Update offset_ and length_. |
| 46 compressor_libarchive->offset_ += written_bytes; | 46 compressor_minizip->offset_ += written_bytes; |
| 47 if (compressor_libarchive->offset_ > compressor_libarchive->length_) | 47 if (compressor_minizip->offset_ > compressor_minizip->length_) |
| 48 compressor_libarchive->length_ = compressor_libarchive->offset_; | 48 compressor_minizip->length_ = compressor_minizip->offset_; |
| 49 return static_cast<uLong>(written_bytes); | 49 return static_cast<uLong>(written_bytes); |
| 50 } | 50 } |
| 51 | 51 |
| 52 // Returns the offset from the beginning of the data. | 52 // Returns the offset from the beginning of the data. |
| 53 long CustomArchiveTell(void* compressor, void* /*stream*/) { | 53 long CustomArchiveTell(void* compressor, void* /*stream*/) { |
| 54 CompressorArchiveLibarchive* compressor_libarchive = | 54 CompressorArchiveMinizip* compressor_minizip = |
| 55 static_cast<CompressorArchiveLibarchive*>(compressor); | 55 static_cast<CompressorArchiveMinizip*>(compressor); |
| 56 return static_cast<long>(compressor_libarchive->offset_); | 56 return static_cast<long>(compressor_minizip->offset_); |
| 57 } | 57 } |
| 58 | 58 |
| 59 // Moves the current offset to the specified position. | 59 // Moves the current offset to the specified position. |
| 60 long CustomArchiveSeek(void* compressor, | 60 long CustomArchiveSeek(void* compressor, |
| 61 void* /*stream*/, | 61 void* /*stream*/, |
| 62 uLong offset, | 62 uLong offset, |
| 63 int origin) { | 63 int origin) { |
| 64 CompressorArchiveLibarchive* compressor_libarchive = | 64 CompressorArchiveMinizip* compressor_minizip = |
| 65 static_cast<CompressorArchiveLibarchive*>(compressor); | 65 static_cast<CompressorArchiveMinizip*>(compressor); |
| 66 | 66 |
| 67 if (origin == ZLIB_FILEFUNC_SEEK_CUR) { | 67 if (origin == ZLIB_FILEFUNC_SEEK_CUR) { |
| 68 compressor_libarchive->offset_ = | 68 compressor_minizip->offset_ = |
| 69 std::min(compressor_libarchive->offset_ + static_cast<int64_t>(offset), | 69 std::min(compressor_minizip->offset_ + static_cast<int64_t>(offset), |
| 70 compressor_libarchive->length_); | 70 compressor_minizip->length_); |
| 71 return 0 /* Success */; | 71 return 0 /* Success */; |
| 72 } | 72 } |
| 73 if (origin == ZLIB_FILEFUNC_SEEK_END) { | 73 if (origin == ZLIB_FILEFUNC_SEEK_END) { |
| 74 compressor_libarchive->offset_ = | 74 compressor_minizip->offset_ = |
| 75 std::max(compressor_libarchive->length_ - static_cast<int64_t>(offset), | 75 std::max(compressor_minizip->length_ - static_cast<int64_t>(offset), |
| 76 0LL); | 76 0LL); |
| 77 return 0 /* Success */; | 77 return 0 /* Success */; |
| 78 } | 78 } |
| 79 if (origin == ZLIB_FILEFUNC_SEEK_SET) { | 79 if (origin == ZLIB_FILEFUNC_SEEK_SET) { |
| 80 compressor_libarchive->offset_ = | 80 compressor_minizip->offset_ = |
| 81 std::min(static_cast<int64_t>(offset), compressor_libarchive->length_); | 81 std::min(static_cast<int64_t>(offset), compressor_minizip->length_); |
| 82 return 0 /* Success */; | 82 return 0 /* Success */; |
| 83 } | 83 } |
| 84 return -1 /* Error */; | 84 return -1 /* Error */; |
| 85 } | 85 } |
| 86 | 86 |
| 87 // Releases all used resources. compressor points to compressor_libarchive and | 87 // Releases all used resources. compressor points to compressor_minizip and |
| 88 // it is deleted in the destructor of Compressor, so we don't need to delete | 88 // it is deleted in the destructor of Compressor, so we don't need to delete |
| 89 // it here. | 89 // it here. |
| 90 int CustomArchiveClose(void* /*compressor*/, void* /*stream*/) { | 90 int CustomArchiveClose(void* /*compressor*/, void* /*stream*/) { |
| 91 return 0 /* Success */; | 91 return 0 /* Success */; |
| 92 } | 92 } |
| 93 | 93 |
| 94 // Returns the last error that happened when writing data. This function always | 94 // Returns the last error that happened when writing data. This function always |
| 95 // returns zero, which means there are no errors. | 95 // returns zero, which means there are no errors. |
| 96 int CustomArchiveError(void* /*compressor*/, void* /*stream*/) { | 96 int CustomArchiveError(void* /*compressor*/, void* /*stream*/) { |
| 97 return 0 /* Success */; | 97 return 0 /* Success */; |
| 98 } | 98 } |
| 99 | 99 |
| 100 } // compressor_archive_functions | 100 } // compressor_archive_functions |
| 101 | 101 |
| 102 CompressorArchiveLibarchive::CompressorArchiveLibarchive( | 102 CompressorArchiveMinizip::CompressorArchiveMinizip( |
| 103 CompressorStream* compressor_stream) | 103 CompressorStream* compressor_stream) |
| 104 : CompressorArchive(compressor_stream), | 104 : CompressorArchive(compressor_stream), |
| 105 compressor_stream_(compressor_stream), | 105 compressor_stream_(compressor_stream), |
| 106 zip_file_(nullptr), | 106 zip_file_(nullptr), |
| 107 offset_(0), | 107 offset_(0), |
| 108 length_(0) { | 108 length_(0) { |
| 109 destination_buffer_ = | 109 destination_buffer_ = |
| 110 new char[compressor_stream_constants::kMaximumDataChunkSize]; | 110 new char[compressor_stream_constants::kMaximumDataChunkSize]; |
| 111 } | 111 } |
| 112 | 112 |
| 113 CompressorArchiveLibarchive::~CompressorArchiveLibarchive() { | 113 CompressorArchiveMinizip::~CompressorArchiveMinizip() { |
| 114 delete destination_buffer_; | 114 delete destination_buffer_; |
| 115 } | 115 } |
| 116 | 116 |
| 117 bool CompressorArchiveLibarchive::CreateArchive() { | 117 bool CompressorArchiveMinizip::CreateArchive() { |
| 118 // Set up archive object. | 118 // Set up archive object. |
| 119 zlib_filefunc_def zip_funcs; | 119 zlib_filefunc_def zip_funcs; |
| 120 zip_funcs.zopen_file = compressor_archive_functions::CustomArchiveOpen; | 120 zip_funcs.zopen_file = compressor_archive_functions::CustomArchiveOpen; |
| 121 zip_funcs.zread_file = compressor_archive_functions::CustomArchiveRead; | 121 zip_funcs.zread_file = compressor_archive_functions::CustomArchiveRead; |
| 122 zip_funcs.zwrite_file = compressor_archive_functions::CustomArchiveWrite; | 122 zip_funcs.zwrite_file = compressor_archive_functions::CustomArchiveWrite; |
| 123 zip_funcs.ztell_file = compressor_archive_functions::CustomArchiveTell; | 123 zip_funcs.ztell_file = compressor_archive_functions::CustomArchiveTell; |
| 124 zip_funcs.zseek_file = compressor_archive_functions::CustomArchiveSeek; | 124 zip_funcs.zseek_file = compressor_archive_functions::CustomArchiveSeek; |
| 125 zip_funcs.zclose_file = compressor_archive_functions::CustomArchiveClose; | 125 zip_funcs.zclose_file = compressor_archive_functions::CustomArchiveClose; |
| 126 zip_funcs.zerror_file = compressor_archive_functions::CustomArchiveError; | 126 zip_funcs.zerror_file = compressor_archive_functions::CustomArchiveError; |
| 127 zip_funcs.opaque = this; | 127 zip_funcs.opaque = this; |
| 128 | 128 |
| 129 zip_file_ = zipOpen2(nullptr /* pathname */, | 129 zip_file_ = zipOpen2(nullptr /* pathname */, |
| 130 APPEND_STATUS_CREATE, | 130 APPEND_STATUS_CREATE, |
| 131 nullptr /* globalcomment */, | 131 nullptr /* globalcomment */, |
| 132 &zip_funcs); | 132 &zip_funcs); |
| 133 if (!zip_file_) { | 133 if (!zip_file_) { |
| 134 set_error_message(compressor_archive_constants::kCreateArchiveError); | 134 set_error_message(compressor_archive_constants::kCreateArchiveError); |
| 135 return false /* Error */; | 135 return false /* Error */; |
| 136 } | 136 } |
| 137 return true /* Success */; | 137 return true /* Success */; |
| 138 } | 138 } |
| 139 | 139 |
| 140 bool CompressorArchiveLibarchive::AddToArchive(const std::string& filename, | 140 bool CompressorArchiveMinizip::AddToArchive(const std::string& filename, |
| 141 int64_t file_size, | 141 int64_t file_size, |
| 142 int64_t modification_time, | 142 int64_t modification_time, |
| 143 bool is_directory) { | 143 bool is_directory) { |
| 144 // Minizip takes filenames that end with '/' as directories. | 144 // Minizip takes filenames that end with '/' as directories. |
| 145 std::string normalized_filename = filename; | 145 std::string normalized_filename = filename; |
| 146 if (is_directory) | 146 if (is_directory) |
| 147 normalized_filename += "/"; | 147 normalized_filename += "/"; |
| 148 | 148 |
| 149 // Fill zipfileMetadata with modification_time. | 149 // Fill zipfileMetadata with modification_time. |
| 150 zip_fileinfo zipfileMetadata; | 150 zip_fileinfo zipfileMetadata; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 | 221 |
| 222 if (has_error) { | 222 if (has_error) { |
| 223 CloseArchive(true /* has_error */); | 223 CloseArchive(true /* has_error */); |
| 224 set_error_message(compressor_archive_constants::kAddToArchiveError); | 224 set_error_message(compressor_archive_constants::kAddToArchiveError); |
| 225 return false /* Error */; | 225 return false /* Error */; |
| 226 } | 226 } |
| 227 | 227 |
| 228 return true /* Success */; | 228 return true /* Success */; |
| 229 } | 229 } |
| 230 | 230 |
| 231 bool CompressorArchiveLibarchive::CloseArchive(bool has_error) { | 231 bool CompressorArchiveMinizip::CloseArchive(bool has_error) { |
| 232 if (zipClose(zip_file_, nullptr /* global_comment */) != ZIP_OK) { | 232 if (zipClose(zip_file_, nullptr /* global_comment */) != ZIP_OK) { |
| 233 set_error_message(compressor_archive_constants::kCloseArchiveError); | 233 set_error_message(compressor_archive_constants::kCloseArchiveError); |
| 234 return false /* Error */; | 234 return false /* Error */; |
| 235 } | 235 } |
| 236 if (!has_error) { | 236 if (!has_error) { |
| 237 if (compressor_stream()->Flush() < 0) { | 237 if (compressor_stream()->Flush() < 0) { |
| 238 set_error_message(compressor_archive_constants::kCloseArchiveError); | 238 set_error_message(compressor_archive_constants::kCloseArchiveError); |
| 239 return false /* Error */; | 239 return false /* Error */; |
| 240 } | 240 } |
| 241 } | 241 } |
| 242 return true /* Success */; | 242 return true /* Success */; |
| 243 } | 243 } |
| OLD | NEW |