FileFinder.cpp revision 9102165fd8be64bdc9110d0839a84fcdfa5b68cb
1// 2// Copyright 2011 The Android Open Source Project 3// 4 5// File Finder implementation. 6// Implementation for the functions declared and documented in FileFinder.h 7 8#include <utils/Vector.h> 9#include <utils/String8.h> 10#include <utils/KeyedVector.h> 11 12#include <iostream> 13#include <dirent.h> 14#include <sys/stat.h> 15 16#include "DirectoryWalker.h" 17#include "FileFinder.h" 18 19//#define DEBUG 20 21using android::String8; 22using std::cout; 23using std::endl; 24 25// Private function to check whether a file is a directory or not 26bool isDirectory(const char* filename) { 27 struct stat fileStat; 28 if (stat(filename, &fileStat) == -1) { 29 return false; 30 } 31 return(S_ISDIR(fileStat.st_mode)); 32} 33 34 35// Private function to check whether a file is a regular file or not 36bool isFile(const char* filename) { 37 struct stat fileStat; 38 if (stat(filename, &fileStat) == -1) { 39 return false; 40 } 41 return(S_ISREG(fileStat.st_mode)); 42} 43 44bool SystemFileFinder::findFiles(String8 basePath, Vector<String8>& extensions, 45 KeyedVector<String8,time_t>& fileStore, 46 DirectoryWalker* dw) 47{ 48 // Scan the directory pointed to by basePath 49 // check files and recurse into subdirectories. 50 if (!dw->openDir(basePath)) { 51 return false; 52 } 53#ifdef DEBUG 54 cout << "FileFinder looking in " << basePath << endl; 55#endif // DEBUG 56 /* 57 * Go through all directory entries. Check each file using checkAndAddFile 58 * and recurse into sub-directories. 59 */ 60 struct dirent* entry; 61 while ((entry = dw->nextEntry()) != NULL) { 62 String8 entryName(entry->d_name); 63 if (entry->d_name[0] == '.') // Skip hidden files and directories 64 continue; 65 66 String8 fullPath = basePath.appendPathCopy(entryName); 67 // If this entry is a directory we'll recurse into it 68 if (isDirectory(fullPath.string()) ) { 69 DirectoryWalker* copy = dw->clone(); 70 findFiles(fullPath, extensions, fileStore,copy); 71 delete copy; 72 } 73 74 // If this entry is a file, we'll pass it over to checkAndAddFile 75 if (isFile(fullPath.string()) ) { 76 checkAndAddFile(fullPath,dw->entryStats(),extensions,fileStore); 77 } 78 } 79 80 // Clean up 81 dw->closeDir(); 82 83 return true; 84} 85 86void SystemFileFinder::checkAndAddFile(String8 path, const struct stat* stats, 87 Vector<String8>& extensions, 88 KeyedVector<String8,time_t>& fileStore) 89{ 90#ifdef DEBUG 91 cout << "Checking file " << path << "..."; 92#endif // DEBUG 93 // Loop over the extensions, checking for a match 94 bool done = false; 95 String8 ext(path.getPathExtension()); 96 ext.toLower(); 97 for (size_t i = 0; i < extensions.size() && !done; ++i) { 98 String8 ext2 = extensions[i].getPathExtension(); 99 ext2.toLower(); 100 // Compare the extensions. If a match is found, add to storage. 101 if (ext == ext2) { 102#ifdef DEBUG 103 cout << "Match"; 104#endif // DEBUG 105 done = true; 106 fileStore.add(path,stats->st_mtime); 107 } 108 } 109#ifdef DEBUG 110 cout << endl; 111#endif //DEBUG 112} 113 114