|  | // | 
|  | // Copyright 2011 The Android Open Source Project | 
|  | // | 
|  |  | 
|  | // File Finder implementation. | 
|  | // Implementation for the functions declared and documented in FileFinder.h | 
|  |  | 
|  | #include <utils/Vector.h> | 
|  | #include <utils/String8.h> | 
|  | #include <utils/KeyedVector.h> | 
|  |  | 
|  | #include <dirent.h> | 
|  | #include <sys/stat.h> | 
|  |  | 
|  | #include "DirectoryWalker.h" | 
|  | #include "FileFinder.h" | 
|  |  | 
|  | //#define DEBUG | 
|  |  | 
|  | using android::String8; | 
|  |  | 
|  | // Private function to check whether a file is a directory or not | 
|  | bool isDirectory(const char* filename) { | 
|  | struct stat fileStat; | 
|  | if (stat(filename, &fileStat) == -1) { | 
|  | return false; | 
|  | } | 
|  | return(S_ISDIR(fileStat.st_mode)); | 
|  | } | 
|  |  | 
|  |  | 
|  | // Private function to check whether a file is a regular file or not | 
|  | bool isFile(const char* filename) { | 
|  | struct stat fileStat; | 
|  | if (stat(filename, &fileStat) == -1) { | 
|  | return false; | 
|  | } | 
|  | return(S_ISREG(fileStat.st_mode)); | 
|  | } | 
|  |  | 
|  | bool SystemFileFinder::findFiles(String8 basePath, Vector<String8>& extensions, | 
|  | KeyedVector<String8,time_t>& fileStore, | 
|  | DirectoryWalker* dw) | 
|  | { | 
|  | // Scan the directory pointed to by basePath | 
|  | // check files and recurse into subdirectories. | 
|  | if (!dw->openDir(basePath)) { | 
|  | return false; | 
|  | } | 
|  | /* | 
|  | *  Go through all directory entries. Check each file using checkAndAddFile | 
|  | *  and recurse into sub-directories. | 
|  | */ | 
|  | struct dirent* entry; | 
|  | while ((entry = dw->nextEntry()) != NULL) { | 
|  | String8 entryName(entry->d_name); | 
|  | if (entry->d_name[0] == '.') // Skip hidden files and directories | 
|  | continue; | 
|  |  | 
|  | String8 fullPath = basePath.appendPathCopy(entryName); | 
|  | // If this entry is a directory we'll recurse into it | 
|  | if (isDirectory(fullPath.string()) ) { | 
|  | DirectoryWalker* copy = dw->clone(); | 
|  | findFiles(fullPath, extensions, fileStore,copy); | 
|  | delete copy; | 
|  | } | 
|  |  | 
|  | // If this entry is a file, we'll pass it over to checkAndAddFile | 
|  | if (isFile(fullPath.string()) ) { | 
|  | checkAndAddFile(fullPath,dw->entryStats(),extensions,fileStore); | 
|  | } | 
|  | } | 
|  |  | 
|  | // Clean up | 
|  | dw->closeDir(); | 
|  |  | 
|  | return true; | 
|  | } | 
|  |  | 
|  | void SystemFileFinder::checkAndAddFile(String8 path, const struct stat* stats, | 
|  | Vector<String8>& extensions, | 
|  | KeyedVector<String8,time_t>& fileStore) | 
|  | { | 
|  | // Loop over the extensions, checking for a match | 
|  | bool done = false; | 
|  | String8 ext(path.getPathExtension()); | 
|  | ext.toLower(); | 
|  | for (size_t i = 0; i < extensions.size() && !done; ++i) { | 
|  | String8 ext2 = extensions[i].getPathExtension(); | 
|  | ext2.toLower(); | 
|  | // Compare the extensions. If a match is found, add to storage. | 
|  | if (ext == ext2) { | 
|  | done = true; | 
|  | fileStore.add(path,stats->st_mtime); | 
|  | } | 
|  | } | 
|  | } | 
|  |  |