18a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// 28a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// Copyright 2011 The Android Open Source Project 38a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// 48a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// Implementation file for CrunchCache 58a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// This file defines functions laid out and documented in 68a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// CrunchCache.h 78a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 89ec96f97567bc86deebe073d5c828a6477b9a785Elliott Hughes#include <utils/Compat.h> 98a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <utils/Vector.h> 108a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <utils/String8.h> 118a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 128a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include "DirectoryWalker.h" 138a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include "FileFinder.h" 148a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include "CacheUpdater.h" 158a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include "CrunchCache.h" 168a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 178a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinusing namespace android; 188a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 198a39da80b33691b0c82458c3b7727e13ff71277eJosiah GaskinCrunchCache::CrunchCache(String8 sourcePath, String8 destPath, FileFinder* ff) 208a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin : mSourcePath(sourcePath), mDestPath(destPath), mSourceFiles(0), mDestFiles(0), mFileFinder(ff) 218a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin{ 228a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // We initialize the default value to return to 0 so if a file doesn't exist 238a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // then all files are automatically "newer" than it. 248a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 258a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Set file extensions to look for. Right now just pngs. 268a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin mExtensions.push(String8(".png")); 278a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 288a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Load files into our data members 298a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin loadFiles(); 308a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin} 318a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 328a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinsize_t CrunchCache::crunch(CacheUpdater* cu, bool forceOverwrite) 338a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin{ 348a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin size_t numFilesUpdated = 0; 358a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 368a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Iterate through the source files and compare to cache. 378a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // After processing a file, remove it from the source files and 388a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // from the dest files. 398a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // We're done when we're out of files in source. 408a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin String8 relativePath; 418a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin while (mSourceFiles.size() > 0) { 428a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Get the full path to the source file, then convert to a c-string 438a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // and offset our beginning pointer to the length of the sourcePath 448a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // This efficiently strips the source directory prefix from our path. 458a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Also, String8 doesn't have a substring method so this is what we've 468a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // got to work with. 478a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin const char* rPathPtr = mSourceFiles.keyAt(0).string()+mSourcePath.length(); 488a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Strip leading slash if present 498a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin int offset = 0; 508a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin if (rPathPtr[0] == OS_PATH_SEPARATOR) 518a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin offset = 1; 528a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin relativePath = String8(rPathPtr + offset); 538a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 548a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin if (forceOverwrite || needsUpdating(relativePath)) { 558a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin cu->processImage(mSourcePath.appendPathCopy(relativePath), 568a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin mDestPath.appendPathCopy(relativePath)); 578a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin numFilesUpdated++; 588a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // crunchFile(relativePath); 598a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin } 608a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Delete this file from the source files and (if it exists) from the 618a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // dest files. 628a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin mSourceFiles.removeItemsAt(0); 638a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin mDestFiles.removeItem(mDestPath.appendPathCopy(relativePath)); 648a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin } 658a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 668a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Iterate through what's left of destFiles and delete leftovers 678a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin while (mDestFiles.size() > 0) { 688a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin cu->deleteFile(mDestFiles.keyAt(0)); 698a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin mDestFiles.removeItemsAt(0); 708a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin } 718a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 728a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Update our knowledge of the files cache 738a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // both source and dest should be empty by now. 748a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin loadFiles(); 758a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 768a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin return numFilesUpdated; 778a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin} 788a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 798a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinvoid CrunchCache::loadFiles() 808a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin{ 818a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Clear out our data structures to avoid putting in duplicates 828a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin mSourceFiles.clear(); 838a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin mDestFiles.clear(); 848a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 858a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Make a directory walker that points to the system. 868a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin DirectoryWalker* dw = new SystemDirectoryWalker(); 878a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 888a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Load files in the source directory 898a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin mFileFinder->findFiles(mSourcePath, mExtensions, mSourceFiles,dw); 908a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 918a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Load files in the destination directory 928a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin mFileFinder->findFiles(mDestPath,mExtensions,mDestFiles,dw); 938a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 948a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin delete dw; 958a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin} 968a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 978a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinbool CrunchCache::needsUpdating(String8 relativePath) const 988a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin{ 998a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Retrieve modification dates for this file entry under the source and 1008a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // cache directory trees. The vectors will return a modification date of 0 1018a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // if the file doesn't exist. 1028a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin time_t sourceDate = mSourceFiles.valueFor(mSourcePath.appendPathCopy(relativePath)); 1038a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin time_t destDate = mDestFiles.valueFor(mDestPath.appendPathCopy(relativePath)); 1048a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin return sourceDate > destDate; 1052412f84064c26b643c722ce914a97c4ec7776c69Andreas Gampe} 106