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