| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium OS Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef VOLUME_ARCHIVE_LIBARCHIVE_H_ | |
| 6 #define VOLUME_ARCHIVE_LIBARCHIVE_H_ | |
| 7 | |
| 8 #include <string> | |
| 9 | |
| 10 #include "archive.h" | |
| 11 | |
| 12 #include "volume_archive.h" | |
| 13 | |
| 14 // A namespace with constants used by VolumeArchiveLibarchive. | |
| 15 namespace volume_archive_constants { | |
| 16 | |
| 17 const char kArchiveReadNewError[] = "Could not allocate archive."; | |
| 18 const char kFileNotFound[] = "File not found for read data request."; | |
| 19 const char kVolumeReaderError[] = "VolumeReader failed to retrieve data."; | |
| 20 const char kArchiveSupportErrorPrefix[] = "Error at support rar/zip format: "; | |
| 21 const char kArchiveOpenErrorPrefix[] = "Error at open archive: "; | |
| 22 const char kArchiveNextHeaderErrorPrefix[] = | |
| 23 "Error at reading next header for metadata: "; | |
| 24 const char kArchiveReadDataErrorPrefix[] = "Error at reading data: "; | |
| 25 const char kArchiveReadFreeErrorPrefix[] = "Error at archive free: "; | |
| 26 | |
| 27 // The size of the buffer used to skip unnecessary data. | |
| 28 // Should be positive and less than size_t maximum. | |
| 29 const int64_t kDummyBufferSize = 512 * 1024; // 512 KB | |
| 30 | |
| 31 // The size of the buffer used by ReadInProgress to decompress data. | |
| 32 // Should be positive and less than size_t maximum. | |
| 33 const int64_t kDecompressBufferSize = 512 * 1024; // 512 KB. | |
| 34 | |
| 35 // The maximum data chunk size for VolumeReader::Read requests. | |
| 36 // Should be positive. | |
| 37 const int64_t kMaximumDataChunkSize = 512 * 1024; // 512 KB. | |
| 38 | |
| 39 // The minimum data chunk size for VolumeReader::Read requests. | |
| 40 // Should be positive. | |
| 41 const int64_t kMinimumDataChunkSize = 32 * 1024; // 16 KB. | |
| 42 | |
| 43 } // namespace volume_archive_constants | |
| 44 | |
| 45 // Defines an implementation of VolumeArchive that wraps all libarchive | |
| 46 // operations. | |
| 47 class VolumeArchiveLibarchive : public VolumeArchive { | |
| 48 public: | |
| 49 explicit VolumeArchiveLibarchive(VolumeReader* reader); | |
| 50 | |
| 51 virtual ~VolumeArchiveLibarchive(); | |
| 52 | |
| 53 // See volume_archive_interface.h. | |
| 54 virtual bool Init(const std::string& encoding); | |
| 55 | |
| 56 // See volume_archive_interface.h. | |
| 57 virtual Result GetNextHeader(); | |
| 58 virtual Result GetNextHeader(const char** path_name, | |
| 59 int64_t* size, | |
| 60 bool* is_directory, | |
| 61 time_t* modification_time); | |
| 62 | |
| 63 // See volume_archive_interface.h. | |
| 64 virtual bool SeekHeader(int64_t index); | |
| 65 | |
| 66 // See volume_archive_interface.h. | |
| 67 virtual int64_t ReadData(int64_t offset, | |
| 68 int64_t length, | |
| 69 const char** buffer); | |
| 70 | |
| 71 // See volume_archive_interface.h. | |
| 72 virtual void MaybeDecompressAhead(); | |
| 73 | |
| 74 // See volume_archive_interface.h. | |
| 75 virtual bool Cleanup(); | |
| 76 | |
| 77 int64_t reader_data_size() const { return reader_data_size_; } | |
| 78 | |
| 79 private: | |
| 80 // Decompress length bytes of data starting from offset. | |
| 81 void DecompressData(int64_t offset, int64_t length); | |
| 82 | |
| 83 // The size of the requested data from VolumeReader. | |
| 84 int64_t reader_data_size_; | |
| 85 | |
| 86 // The libarchive correspondent archive object. | |
| 87 archive* archive_; | |
| 88 | |
| 89 // The last reached entry with VolumeArchiveLibarchive::GetNextHeader. | |
| 90 archive_entry* current_archive_entry_; | |
| 91 | |
| 92 // The data offset, which will be offset + length after last read | |
| 93 // operation, where offset and length are method parameters for | |
| 94 // VolumeArchiveLibarchive::ReadData. Data offset is used to improve | |
| 95 // performance for consecutive calls to VolumeArchiveLibarchive::ReadData. | |
| 96 // | |
| 97 // Intead of starting the read from the beginning for every | |
| 98 // VolumeArchiveLibarchive::ReadData, the next call will start | |
| 99 // from last_read_data_offset_ in case the offset parameter of | |
| 100 // VolumeArchiveLibarchive::ReadData has the same value as | |
| 101 // last_read_data_offset_. This avoids decompressing again the bytes at | |
| 102 // the begninning of the file, which is the average case scenario. | |
| 103 // But in case the offset parameter is different than last_read_data_offset_, | |
| 104 // then dummy_buffer_ will be used to ignore unused bytes. | |
| 105 int64_t last_read_data_offset_; | |
| 106 | |
| 107 // The length of the last VolumeArchiveLibarchive::ReadData. Used for | |
| 108 // decompress ahead. | |
| 109 int64_t last_read_data_length_; | |
| 110 | |
| 111 // Dummy buffer for unused data read using VolumeArchiveLibarchive::ReadData. | |
| 112 // Sometimes VolumeArchiveLibarchive::ReadData can require reading from | |
| 113 // offsets different from last_read_data_offset_. In this case some bytes | |
| 114 // must be skipped. Because seeking is not possible inside compressed files, | |
| 115 // the bytes will be discarded using this buffer. | |
| 116 char dummy_buffer_[volume_archive_constants::kDummyBufferSize]; | |
| 117 | |
| 118 // The address where the decompressed data starting from | |
| 119 // decompressed_offset_ is stored. It should point to a valid location | |
| 120 // inside decompressed_data_buffer_. Necesssary in order to NOT throw | |
| 121 // away unused decompressed bytes as throwing them away would mean in some | |
| 122 // situations restarting decompressing the file from the beginning. | |
| 123 char* decompressed_data_; | |
| 124 | |
| 125 // The actual buffer that contains the decompressed data. | |
| 126 char decompressed_data_buffer_ | |
| 127 [volume_archive_constants::kDecompressBufferSize]; | |
| 128 | |
| 129 // The size of valid data starting from decompressed_data_ that is stored | |
| 130 // inside decompressed_data_buffer_. | |
| 131 int64_t decompressed_data_size_; | |
| 132 | |
| 133 // True if VolumeArchiveLibarchive::DecompressData failed. | |
| 134 bool decompressed_error_; | |
| 135 }; | |
| 136 | |
| 137 #endif // VOLUME_ARCHIVE_LIBARCHIVE_H_ | |
| OLD | NEW |