| // | |
| // Copyright 2011 The Android Open Source Project | |
| // | |
| // Implementation file for CrunchCache | |
| // This file defines functions laid out and documented in | |
| // CrunchCache.h | |
| #include <utils/Compat.h> | |
| #include <utils/Vector.h> | |
| #include <utils/String8.h> | |
| #include "DirectoryWalker.h" | |
| #include "FileFinder.h" | |
| #include "CacheUpdater.h" | |
| #include "CrunchCache.h" | |
| using namespace android; | |
| CrunchCache::CrunchCache(String8 sourcePath, String8 destPath, FileFinder* ff) | |
| : mSourcePath(sourcePath), mDestPath(destPath), mSourceFiles(0), mDestFiles(0), mFileFinder(ff) | |
| { | |
| // We initialize the default value to return to 0 so if a file doesn't exist | |
| // then all files are automatically "newer" than it. | |
| // Set file extensions to look for. Right now just pngs. | |
| mExtensions.push(String8(".png")); | |
| // Load files into our data members | |
| loadFiles(); | |
| } | |
| size_t CrunchCache::crunch(CacheUpdater* cu, bool forceOverwrite) | |
| { | |
| size_t numFilesUpdated = 0; | |
| // Iterate through the source files and compare to cache. | |
| // After processing a file, remove it from the source files and | |
| // from the dest files. | |
| // We're done when we're out of files in source. | |
| String8 relativePath; | |
| while (mSourceFiles.size() > 0) { | |
| // Get the full path to the source file, then convert to a c-string | |
| // and offset our beginning pointer to the length of the sourcePath | |
| // This efficiently strips the source directory prefix from our path. | |
| // Also, String8 doesn't have a substring method so this is what we've | |
| // got to work with. | |
| const char* rPathPtr = mSourceFiles.keyAt(0).string()+mSourcePath.length(); | |
| // Strip leading slash if present | |
| int offset = 0; | |
| if (rPathPtr[0] == OS_PATH_SEPARATOR) | |
| offset = 1; | |
| relativePath = String8(rPathPtr + offset); | |
| if (forceOverwrite || needsUpdating(relativePath)) { | |
| cu->processImage(mSourcePath.appendPathCopy(relativePath), | |
| mDestPath.appendPathCopy(relativePath)); | |
| numFilesUpdated++; | |
| // crunchFile(relativePath); | |
| } | |
| // Delete this file from the source files and (if it exists) from the | |
| // dest files. | |
| mSourceFiles.removeItemsAt(0); | |
| mDestFiles.removeItem(mDestPath.appendPathCopy(relativePath)); | |
| } | |
| // Iterate through what's left of destFiles and delete leftovers | |
| while (mDestFiles.size() > 0) { | |
| cu->deleteFile(mDestFiles.keyAt(0)); | |
| mDestFiles.removeItemsAt(0); | |
| } | |
| // Update our knowledge of the files cache | |
| // both source and dest should be empty by now. | |
| loadFiles(); | |
| return numFilesUpdated; | |
| } | |
| void CrunchCache::loadFiles() | |
| { | |
| // Clear out our data structures to avoid putting in duplicates | |
| mSourceFiles.clear(); | |
| mDestFiles.clear(); | |
| // Make a directory walker that points to the system. | |
| DirectoryWalker* dw = new SystemDirectoryWalker(); | |
| // Load files in the source directory | |
| mFileFinder->findFiles(mSourcePath, mExtensions, mSourceFiles,dw); | |
| // Load files in the destination directory | |
| mFileFinder->findFiles(mDestPath,mExtensions,mDestFiles,dw); | |
| delete dw; | |
| } | |
| bool CrunchCache::needsUpdating(const String8& relativePath) const | |
| { | |
| // Retrieve modification dates for this file entry under the source and | |
| // cache directory trees. The vectors will return a modification date of 0 | |
| // if the file doesn't exist. | |
| time_t sourceDate = mSourceFiles.valueFor(mSourcePath.appendPathCopy(relativePath)); | |
| time_t destDate = mDestFiles.valueFor(mDestPath.appendPathCopy(relativePath)); | |
| return sourceDate > destDate; | |
| } |