1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Copyright 2011 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Implementation file for CrunchCache 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// This file defines functions laid out and documented in 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// CrunchCache.h 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/Vector.h> 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/String8.h> 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "DirectoryWalker.h" 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "FileFinder.h" 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "CacheUpdater.h" 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "CrunchCache.h" 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiusing namespace android; 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiCrunchCache::CrunchCache(String8 sourcePath, String8 destPath, FileFinder* ff) 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : mSourcePath(sourcePath), mDestPath(destPath), mSourceFiles(0), mDestFiles(0), mFileFinder(ff) 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We initialize the default value to return to 0 so if a file doesn't exist 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // then all files are automatically "newer" than it. 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Set file extensions to look for. Right now just pngs. 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mExtensions.push(String8(".png")); 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Load files into our data members 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski loadFiles(); 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisize_t CrunchCache::crunch(CacheUpdater* cu, bool forceOverwrite) 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t numFilesUpdated = 0; 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Iterate through the source files and compare to cache. 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // After processing a file, remove it from the source files and 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // from the dest files. 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We're done when we're out of files in source. 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 relativePath; 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (mSourceFiles.size() > 0) { 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Get the full path to the source file, then convert to a c-string 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // and offset our beginning pointer to the length of the sourcePath 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This efficiently strips the source directory prefix from our path. 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Also, String8 doesn't have a substring method so this is what we've 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // got to work with. 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* rPathPtr = mSourceFiles.keyAt(0).string()+mSourcePath.length(); 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Strip leading slash if present 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int offset = 0; 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rPathPtr[0] == OS_PATH_SEPARATOR) 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski offset = 1; 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski relativePath = String8(rPathPtr + offset); 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (forceOverwrite || needsUpdating(relativePath)) { 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cu->processImage(mSourcePath.appendPathCopy(relativePath), 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDestPath.appendPathCopy(relativePath)); 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski numFilesUpdated++; 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // crunchFile(relativePath); 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Delete this file from the source files and (if it exists) from the 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // dest files. 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mSourceFiles.removeItemsAt(0); 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDestFiles.removeItem(mDestPath.appendPathCopy(relativePath)); 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Iterate through what's left of destFiles and delete leftovers 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (mDestFiles.size() > 0) { 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cu->deleteFile(mDestFiles.keyAt(0)); 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDestFiles.removeItemsAt(0); 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Update our knowledge of the files cache 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // both source and dest should be empty by now. 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski loadFiles(); 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return numFilesUpdated; 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid CrunchCache::loadFiles() 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Clear out our data structures to avoid putting in duplicates 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mSourceFiles.clear(); 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDestFiles.clear(); 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make a directory walker that points to the system. 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DirectoryWalker* dw = new SystemDirectoryWalker(); 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Load files in the source directory 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFileFinder->findFiles(mSourcePath, mExtensions, mSourceFiles,dw); 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Load files in the destination directory 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFileFinder->findFiles(mDestPath,mExtensions,mDestFiles,dw); 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete dw; 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool CrunchCache::needsUpdating(String8 relativePath) const 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Retrieve modification dates for this file entry under the source and 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // cache directory trees. The vectors will return a modification date of 0 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if the file doesn't exist. 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski time_t sourceDate = mSourceFiles.valueFor(mSourcePath.appendPathCopy(relativePath)); 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski time_t destDate = mDestFiles.valueFor(mDestPath.appendPathCopy(relativePath)); 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sourceDate > destDate; 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}