diff --git a/jni/NativeFormats/util/AndroidUtil.cpp b/jni/NativeFormats/util/AndroidUtil.cpp index fe66837db..2be068cfe 100644 --- a/jni/NativeFormats/util/AndroidUtil.cpp +++ b/jni/NativeFormats/util/AndroidUtil.cpp @@ -95,6 +95,7 @@ shared_ptr AndroidUtil::Method_ZLFile_getInputStream; shared_ptr AndroidUtil::Method_ZLFile_getPath; shared_ptr AndroidUtil::Method_ZLFile_isDirectory; shared_ptr AndroidUtil::Method_ZLFile_size; +shared_ptr AndroidUtil::Method_ZLFile_lastModified; shared_ptr AndroidUtil::Constructor_FileInfo; shared_ptr AndroidUtil::Constructor_FileEncryptionInfo; @@ -177,6 +178,7 @@ bool AndroidUtil::init(JavaVM* jvm) { Method_ZLFile_getInputStream = new ObjectMethod(Class_ZLFile, "getInputStream", Class_java_io_InputStream, "()"); Method_ZLFile_getPath = new StringMethod(Class_ZLFile, "getPath", "()"); Method_ZLFile_size = new LongMethod(Class_ZLFile, "size", "()"); + Method_ZLFile_lastModified = new LongMethod(Class_ZLFile, "lastModified", "()"); Constructor_FileInfo = new Constructor(Class_FileInfo, "(Ljava/lang/String;Lorg/geometerplus/zlibrary/core/drm/FileEncryptionInfo;)V"); Constructor_FileEncryptionInfo = new Constructor(Class_FileEncryptionInfo, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); diff --git a/jni/NativeFormats/util/AndroidUtil.h b/jni/NativeFormats/util/AndroidUtil.h index ff7cb50cb..e8e92186b 100644 --- a/jni/NativeFormats/util/AndroidUtil.h +++ b/jni/NativeFormats/util/AndroidUtil.h @@ -117,6 +117,7 @@ public: static shared_ptr Method_ZLFile_getPath; static shared_ptr Method_ZLFile_isDirectory; static shared_ptr Method_ZLFile_size; + static shared_ptr Method_ZLFile_lastModified; static shared_ptr Constructor_FileInfo; static shared_ptr Constructor_FileEncryptionInfo; diff --git a/jni/NativeFormats/zlibrary/core/src/filesystem/ZLFile.cpp b/jni/NativeFormats/zlibrary/core/src/filesystem/ZLFile.cpp index 61ece819e..f46818432 100644 --- a/jni/NativeFormats/zlibrary/core/src/filesystem/ZLFile.cpp +++ b/jni/NativeFormats/zlibrary/core/src/filesystem/ZLFile.cpp @@ -238,6 +238,13 @@ std::size_t ZLFile::size() const { return myInfo.Size; } +std::size_t ZLFile::lastModified() const { + if (!myInfoIsFilled) { + fillInfo(); + } + return myInfo.MTime; +} + bool ZLFile::isDirectory() const { if (!myInfoIsFilled) { fillInfo(); diff --git a/jni/NativeFormats/zlibrary/core/src/filesystem/ZLFile.h b/jni/NativeFormats/zlibrary/core/src/filesystem/ZLFile.h index 73bd03734..31926eeb7 100644 --- a/jni/NativeFormats/zlibrary/core/src/filesystem/ZLFile.h +++ b/jni/NativeFormats/zlibrary/core/src/filesystem/ZLFile.h @@ -49,7 +49,7 @@ public: //TAR = 0x0200, ARCHIVE = 0xff00, }; - + private: ZLFile(); @@ -58,7 +58,8 @@ public: ~ZLFile(); bool exists() const; - std::size_t size() const; + std::size_t size() const; + std::size_t lastModified() const; void forceArchiveType(ArchiveType type) const; diff --git a/jni/NativeFormats/zlibrary/core/src/filesystem/ZLFileInfo.h b/jni/NativeFormats/zlibrary/core/src/filesystem/ZLFileInfo.h index 5fd1c1a0e..3c13d4ac2 100644 --- a/jni/NativeFormats/zlibrary/core/src/filesystem/ZLFileInfo.h +++ b/jni/NativeFormats/zlibrary/core/src/filesystem/ZLFileInfo.h @@ -24,6 +24,7 @@ struct ZLFileInfo { bool Exists; bool IsDirectory; std::size_t Size; + std::size_t MTime; ZLFileInfo(); }; diff --git a/jni/NativeFormats/zlibrary/core/src/filesystem/zip/ZLZip.h b/jni/NativeFormats/zlibrary/core/src/filesystem/zip/ZLZip.h index 2bb826392..c7a7c045b 100644 --- a/jni/NativeFormats/zlibrary/core/src/filesystem/zip/ZLZip.h +++ b/jni/NativeFormats/zlibrary/core/src/filesystem/zip/ZLZip.h @@ -57,8 +57,12 @@ public: Info info(const std::string &entryName) const; void collectFileNames(std::vector &names) const; +private: + bool isValid() const; + private: const std::string myContainerName; + std::size_t myLastModifiedTime; std::map myInfoMap; }; diff --git a/jni/NativeFormats/zlibrary/core/src/filesystem/zip/ZLZipEntryCache.cpp b/jni/NativeFormats/zlibrary/core/src/filesystem/zip/ZLZipEntryCache.cpp index 3da97af90..562487eb2 100644 --- a/jni/NativeFormats/zlibrary/core/src/filesystem/zip/ZLZipEntryCache.cpp +++ b/jni/NativeFormats/zlibrary/core/src/filesystem/zip/ZLZipEntryCache.cpp @@ -19,6 +19,7 @@ #include #include +#include #include "ZLZip.h" #include "ZLZipHeader.h" @@ -34,6 +35,12 @@ shared_ptr ZLZipEntryCache::cache(const std::string &containerN for (std::size_t i = 0; i < ourStorageSize; ++i) { shared_ptr cache = ourStoredCaches[i]; if (!cache.isNull() && cache->myContainerName == containerName) { + //ZLLogger::Instance().println("ZipEntryCache", "cache found for " + containerName); + if (!cache->isValid()) { + //ZLLogger::Instance().println("ZipEntryCache", "cache is not valid for " + containerName); + cache = new ZLZipEntryCache(containerName, containerStream); + ourStoredCaches[i] = cache; + } return cache; } } @@ -48,6 +55,7 @@ ZLZipEntryCache::Info::Info() : Offset(-1) { ZLZipEntryCache::ZLZipEntryCache(const std::string &containerName, ZLInputStream &containerStream) : myContainerName(containerName) { //ZLLogger::Instance().println("ZipEntryCache", "creating cache for " + containerName); + myLastModifiedTime = ZLFile(containerName).lastModified(); if (!containerStream.open()) { return; } @@ -75,6 +83,10 @@ ZLZipEntryCache::ZLZipEntryCache(const std::string &containerName, ZLInputStream containerStream.close(); } +bool ZLZipEntryCache::isValid() const { + return myLastModifiedTime == ZLFile(myContainerName).lastModified(); +} + ZLZipEntryCache::Info ZLZipEntryCache::info(const std::string &entryName) const { std::map::const_iterator it = myInfoMap.find(entryName); return (it != myInfoMap.end()) ? it->second : Info(); diff --git a/jni/NativeFormats/zlibrary/core/src/unix/filesystem/ZLUnixFSManager.cpp b/jni/NativeFormats/zlibrary/core/src/unix/filesystem/ZLUnixFSManager.cpp index c29fbb23c..09574cf65 100644 --- a/jni/NativeFormats/zlibrary/core/src/unix/filesystem/ZLUnixFSManager.cpp +++ b/jni/NativeFormats/zlibrary/core/src/unix/filesystem/ZLUnixFSManager.cpp @@ -47,6 +47,7 @@ ZLFileInfo ZLUnixFSManager::fileInfo(const std::string &path) const { info.Exists = stat(path.c_str(), &fileStat) == 0; if (info.Exists) { info.Size = fileStat.st_size; + info.MTime = fileStat.st_mtime; info.IsDirectory = S_ISDIR(fileStat.st_mode); } return info; diff --git a/jni/NativeFormats/zlibrary/ui/src/android/filesystem/ZLAndroidFSManager.cpp b/jni/NativeFormats/zlibrary/ui/src/android/filesystem/ZLAndroidFSManager.cpp index e157b3142..fd0ce1ede 100644 --- a/jni/NativeFormats/zlibrary/ui/src/android/filesystem/ZLAndroidFSManager.cpp +++ b/jni/NativeFormats/zlibrary/ui/src/android/filesystem/ZLAndroidFSManager.cpp @@ -93,6 +93,7 @@ ZLFileInfo ZLAndroidFSManager::fileInfo(const std::string &path) const { if (exists) { info.Exists = true; info.Size = AndroidUtil::Method_ZLFile_size->call(javaFile); + info.MTime = AndroidUtil::Method_ZLFile_lastModified->call(javaFile); } env->DeleteLocalRef(javaFile); diff --git a/src/org/geometerplus/zlibrary/core/filesystem/ZLFile.java b/src/org/geometerplus/zlibrary/core/filesystem/ZLFile.java index 704e878a7..a0f5a1b09 100644 --- a/src/org/geometerplus/zlibrary/core/filesystem/ZLFile.java +++ b/src/org/geometerplus/zlibrary/core/filesystem/ZLFile.java @@ -151,6 +151,11 @@ public abstract class ZLFile implements InputStreamHolder { public abstract ZLPhysicalFile getPhysicalFile(); public abstract InputStream getInputStream() throws IOException; + public long lastModified() { + final ZLFile physicalFile = getPhysicalFile(); + return physicalFile != null ? physicalFile.lastModified() : 0; + } + public final InputStream getInputStream(FileEncryptionInfo encryptionInfo) throws IOException { if (encryptionInfo == null) { return getInputStream(); diff --git a/src/org/geometerplus/zlibrary/core/filesystem/ZLPhysicalFile.java b/src/org/geometerplus/zlibrary/core/filesystem/ZLPhysicalFile.java index 8034c553c..5522b9a43 100644 --- a/src/org/geometerplus/zlibrary/core/filesystem/ZLPhysicalFile.java +++ b/src/org/geometerplus/zlibrary/core/filesystem/ZLPhysicalFile.java @@ -44,6 +44,11 @@ public final class ZLPhysicalFile extends ZLFile { return myFile.length(); } + @Override + public long lastModified() { + return myFile.lastModified(); + } + private Boolean myIsDirectory; @Override public boolean isDirectory() {