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

Unified Diff: ui/file_manager/zip_archiver/cpp/volume_archive_libarchive.h

Issue 2807063002: Replace Libarchive with MiniZip. (Closed)
Patch Set: Delete BUILD.gn Created 3 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: ui/file_manager/zip_archiver/cpp/volume_archive_libarchive.h
diff --git a/ui/file_manager/zip_archiver/cpp/volume_archive_libarchive.h b/ui/file_manager/zip_archiver/cpp/volume_archive_libarchive.h
index fde019aa390a72adca8aec3882bf99d46fc1f577..ee549aecabfa495f0060c6055b7b5d2d629e032c 100644
--- a/ui/file_manager/zip_archiver/cpp/volume_archive_libarchive.h
+++ b/ui/file_manager/zip_archiver/cpp/volume_archive_libarchive.h
@@ -7,7 +7,8 @@
#include <string>
-#include "archive.h"
+#include "third_party/zlib/contrib/minizip/unzip.h"
+#include "third_party/zlib/contrib/minizip/zip.h"
#include "volume_archive.h"
@@ -17,12 +18,11 @@ namespace volume_archive_constants {
const char kArchiveReadNewError[] = "Could not allocate archive.";
const char kFileNotFound[] = "File not found for read data request.";
const char kVolumeReaderError[] = "VolumeReader failed to retrieve data.";
-const char kArchiveSupportErrorPrefix[] = "Error at support rar/zip format: ";
-const char kArchiveOpenErrorPrefix[] = "Error at open archive: ";
-const char kArchiveNextHeaderErrorPrefix[] =
- "Error at reading next header for metadata: ";
-const char kArchiveReadDataErrorPrefix[] = "Error at reading data: ";
-const char kArchiveReadFreeErrorPrefix[] = "Error at archive free: ";
+const char kArchiveOpenError[] = "Failed to open archive.";
+const char kArchiveNextHeaderError[] =
+ "Failed to open current file in archive.";
+const char kArchiveReadDataError[] = "Failed to read archive data.";
+const char kArchiveReadFreeError[] = "Failed to close archive.";
// The size of the buffer used to skip unnecessary data.
// Should be positive and less than size_t maximum.
@@ -40,8 +40,32 @@ const int64_t kMaximumDataChunkSize = 512 * 1024; // 512 KB.
// Should be positive.
const int64_t kMinimumDataChunkSize = 32 * 1024; // 16 KB.
+// Maximum length of filename in zip archive.
+const int kZipMaxPath = 256;
+
+// The size of the static cache. We need at least 64KB to cache whole
+// 'end of central directory' data.
+const int64_t kStaticCacheSize = 128 * 1024;
} // namespace volume_archive_constants
mtomasz 2017/04/10 07:15:09 nit: \n missing before } for consistency with \n a
takise 2017/04/11 06:00:52 Done.
+class VolumeArchiveLibarchive;
+
+// A name space with custom functions passed to minizip.
mtomasz 2017/04/10 07:15:09 nit: name space -> namespace
takise 2017/04/11 06:00:52 Done.
+namespace volume_archive_functions {
+ int64_t DynamicCache(VolumeArchiveLibarchive* va, int64_t unz_size);
+ uLong CustomArchiveRead(void* opaque, void* /*stream*/, void* buf, uLong size);
+ // Returns the offset from the beginning of the data.
+ long CustomArchiveTell(void* opaque, void* /*stream*/);
mtomasz 2017/04/10 07:15:09 nit: Can we have an empty line between functions?
takise 2017/04/11 06:00:52 Done.
+ // Moves the current offset to the specified position.
+ long CustomArchiveSeek(void* opaque,
+ void* /*stream*/,
+ uLong offset,
+ int origin);
+} // compressor_archive_functions
mtomasz 2017/04/10 07:15:09 nit: \s\s before //
takise 2017/04/11 06:00:52 Done.
+
+
+class VolumeArchiveLibarchive;
+
// Defines an implementation of VolumeArchive that wraps all libarchive
// operations.
class VolumeArchiveLibarchive : public VolumeArchive {
@@ -54,19 +78,18 @@ class VolumeArchiveLibarchive : public VolumeArchive {
virtual bool Init(const std::string& encoding);
// See volume_archive_interface.h.
- virtual Result GetNextHeader();
- virtual Result GetNextHeader(const char** path_name,
- int64_t* size,
- bool* is_directory,
- time_t* modification_time);
+ virtual VolumeArchive::Result GetCurrentFileInfo(std::string* path_name,
+ int64_t* size,
+ bool* is_directory,
+ time_t* modification_time);
+
+ virtual VolumeArchive::Result GoToNextFile();
// See volume_archive_interface.h.
- virtual bool SeekHeader(int64_t index);
+ virtual bool SeekHeader(const std::string& path_name);
// See volume_archive_interface.h.
- virtual int64_t ReadData(int64_t offset,
- int64_t length,
- const char** buffer);
+ virtual int64_t ReadData(int64_t offset, int64_t length, const char** buffer);
// See volume_archive_interface.h.
virtual void MaybeDecompressAhead();
@@ -76,6 +99,17 @@ class VolumeArchiveLibarchive : public VolumeArchive {
int64_t reader_data_size() const { return reader_data_size_; }
+ // Custom functions need to access private variables of
+ // CompressorArchiveLibarchive frequently.
+ friend int64_t volume_archive_functions::DynamicCache(
+ VolumeArchiveLibarchive* va, int64_t unz_size);
+ friend uLong volume_archive_functions::CustomArchiveRead(
+ void* opaque, void* /*stream*/, void* buf, uLong size);
mtomasz 2017/04/10 07:15:09 nit: No need for commenting out arguments in heade
takise 2017/04/11 06:00:52 Done.
+ friend long volume_archive_functions::CustomArchiveTell(
+ void* opaque, void* /*stream*/);
+ friend long volume_archive_functions::CustomArchiveSeek(
+ void* opaque, void* /*stream*/, uLong offset, int origin);
+
private:
// Decompress length bytes of data starting from offset.
void DecompressData(int64_t offset, int64_t length);
@@ -83,11 +117,37 @@ class VolumeArchiveLibarchive : public VolumeArchive {
// The size of the requested data from VolumeReader.
int64_t reader_data_size_;
- // The libarchive correspondent archive object.
- archive* archive_;
-
- // The last reached entry with VolumeArchiveLibarchive::GetNextHeader.
- archive_entry* current_archive_entry_;
+ // The minizip correspondent archive object.
+ zipFile zip_file_;
+
+ // We use two kinds of cache strategies here: dynamic and static.
+ // Dynamic cache is a common cache strategy used in most of IO streams such as
+ // fread. When a file chunk is requested and if the size of the requested
+ // chunk is small, we load larger size of bytes from the archive and cache
+ // them in dynamic_cache_. If the range of the next requested chunk is within
+ // the cache, we don't read the archive and just return the data in the cache.
+ char dynamic_cache_[volume_archive_constants::kMaximumDataChunkSize];
+
+ // The offset from which dynamic_cache_ has the data of the archive.
+ int64_t dynamic_cache_offset_;
+
+ // The size of the data in dynamic_cache_.
+ int64_t dynamic_cache_size_;
+
+ // Although dynamic cache works in most situations, it doesn't work when
+ // MiniZip is looking for the front index of the central directory. Since
+ // MiniZip reads the data little by little backwards from the end to find the
+ // index, dynamic_cache will be reloaded every time. To avoid this, we first
+ // cache a certain length of data from the end into static_cache_. The data
+ // in this buffer is also used when the data in the central directory is
mtomasz 2017/04/10 07:15:09 Is size of this cache enough for large ZIP files,
takise 2017/04/11 06:00:52 Actually, this buffer doesn't have 'central direct
mtomasz 2017/04/11 06:36:45 Thanks for the explanation. Now I understand very
+ // requested by MiniZip later.
+ char static_cache_[volume_archive_constants::kStaticCacheSize];
+
+ // The offset from which static_cache_ has the data of the archive.
+ int64_t static_cache_offset_;
+
+ // The size of the data in static_cache_.
+ int64_t static_cache_size_;
// The data offset, which will be offset + length after last read
// operation, where offset and length are method parameters for

Powered by Google App Engine
This is Rietveld 408576698