| // | |
| // 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(const 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); | |
| } | |
| } | |
| } | |