1  //
2  // Copyright 2011 The Android Open Source Project
3  //
4  // Implementation file for CrunchCache
5  // This file defines functions laid out and documented in
6  // CrunchCache.h
7  
8  #include <utils/Compat.h>
9  #include <utils/Vector.h>
10  #include <utils/String8.h>
11  
12  #include "DirectoryWalker.h"
13  #include "FileFinder.h"
14  #include "CacheUpdater.h"
15  #include "CrunchCache.h"
16  
17  using namespace android;
18  
CrunchCache(String8 sourcePath,String8 destPath,FileFinder * ff)19  CrunchCache::CrunchCache(String8 sourcePath, String8 destPath, FileFinder* ff)
20      : mSourcePath(sourcePath), mDestPath(destPath), mSourceFiles(0), mDestFiles(0), mFileFinder(ff)
21  {
22      // We initialize the default value to return to 0 so if a file doesn't exist
23      // then all files are automatically "newer" than it.
24  
25      // Set file extensions to look for. Right now just pngs.
26      mExtensions.push(String8(".png"));
27  
28      // Load files into our data members
29      loadFiles();
30  }
31  
crunch(CacheUpdater * cu,bool forceOverwrite)32  size_t CrunchCache::crunch(CacheUpdater* cu, bool forceOverwrite)
33  {
34      size_t numFilesUpdated = 0;
35  
36      // Iterate through the source files and compare to cache.
37      // After processing a file, remove it from the source files and
38      // from the dest files.
39      // We're done when we're out of files in source.
40      String8 relativePath;
41      while (mSourceFiles.size() > 0) {
42          // Get the full path to the source file, then convert to a c-string
43          // and offset our beginning pointer to the length of the sourcePath
44          // This efficiently strips the source directory prefix from our path.
45          // Also, String8 doesn't have a substring method so this is what we've
46          // got to work with.
47          const char* rPathPtr = mSourceFiles.keyAt(0).string()+mSourcePath.length();
48          // Strip leading slash if present
49          int offset = 0;
50          if (rPathPtr[0] == OS_PATH_SEPARATOR)
51              offset = 1;
52          relativePath = String8(rPathPtr + offset);
53  
54          if (forceOverwrite || needsUpdating(relativePath)) {
55              cu->processImage(mSourcePath.appendPathCopy(relativePath),
56                               mDestPath.appendPathCopy(relativePath));
57              numFilesUpdated++;
58              // crunchFile(relativePath);
59          }
60          // Delete this file from the source files and (if it exists) from the
61          // dest files.
62          mSourceFiles.removeItemsAt(0);
63          mDestFiles.removeItem(mDestPath.appendPathCopy(relativePath));
64      }
65  
66      // Iterate through what's left of destFiles and delete leftovers
67      while (mDestFiles.size() > 0) {
68          cu->deleteFile(mDestFiles.keyAt(0));
69          mDestFiles.removeItemsAt(0);
70      }
71  
72      // Update our knowledge of the files cache
73      // both source and dest should be empty by now.
74      loadFiles();
75  
76      return numFilesUpdated;
77  }
78  
loadFiles()79  void CrunchCache::loadFiles()
80  {
81      // Clear out our data structures to avoid putting in duplicates
82      mSourceFiles.clear();
83      mDestFiles.clear();
84  
85      // Make a directory walker that points to the system.
86      DirectoryWalker* dw = new SystemDirectoryWalker();
87  
88      // Load files in the source directory
89      mFileFinder->findFiles(mSourcePath, mExtensions, mSourceFiles,dw);
90  
91      // Load files in the destination directory
92      mFileFinder->findFiles(mDestPath,mExtensions,mDestFiles,dw);
93  
94      delete dw;
95  }
96  
needsUpdating(const String8 & relativePath) const97  bool CrunchCache::needsUpdating(const String8& relativePath) const
98  {
99      // Retrieve modification dates for this file entry under the source and
100      // cache directory trees. The vectors will return a modification date of 0
101      // if the file doesn't exist.
102      time_t sourceDate = mSourceFiles.valueFor(mSourcePath.appendPathCopy(relativePath));
103      time_t destDate = mDestFiles.valueFor(mDestPath.appendPathCopy(relativePath));
104      return sourceDate > destDate;
105  }
106