FileFinder.cpp revision 9102165fd8be64bdc9110d0839a84fcdfa5b68cb
18a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// 28a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// Copyright 2011 The Android Open Source Project 38a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// 48a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 58a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// File Finder implementation. 68a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// Implementation for the functions declared and documented in FileFinder.h 78a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 88a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <utils/Vector.h> 98a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <utils/String8.h> 108a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <utils/KeyedVector.h> 118a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 128a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <iostream> 139102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin#include <dirent.h> 149102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin#include <sys/stat.h> 158a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 168a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include "DirectoryWalker.h" 178a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include "FileFinder.h" 188a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 198a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin//#define DEBUG 208a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 218a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinusing android::String8; 228a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinusing std::cout; 238a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinusing std::endl; 248a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 259102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin// Private function to check whether a file is a directory or not 269102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskinbool isDirectory(const char* filename) { 279102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin struct stat fileStat; 289102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin if (stat(filename, &fileStat) == -1) { 299102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin return false; 309102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin } 319102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin return(S_ISDIR(fileStat.st_mode)); 329102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin} 339102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin 349102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin 359102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin// Private function to check whether a file is a regular file or not 369102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskinbool isFile(const char* filename) { 379102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin struct stat fileStat; 389102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin if (stat(filename, &fileStat) == -1) { 399102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin return false; 409102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin } 419102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin return(S_ISREG(fileStat.st_mode)); 429102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin} 439102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin 448a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinbool SystemFileFinder::findFiles(String8 basePath, Vector<String8>& extensions, 458a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin KeyedVector<String8,time_t>& fileStore, 468a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin DirectoryWalker* dw) 478a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin{ 488a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Scan the directory pointed to by basePath 498a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // check files and recurse into subdirectories. 508a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin if (!dw->openDir(basePath)) { 518a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin return false; 528a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin } 538a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#ifdef DEBUG 548a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin cout << "FileFinder looking in " << basePath << endl; 558a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#endif // DEBUG 568a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin /* 578a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * Go through all directory entries. Check each file using checkAndAddFile 588a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * and recurse into sub-directories. 598a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin */ 608a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin struct dirent* entry; 618a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin while ((entry = dw->nextEntry()) != NULL) { 628a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin String8 entryName(entry->d_name); 638a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin if (entry->d_name[0] == '.') // Skip hidden files and directories 648a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin continue; 658a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 668a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin String8 fullPath = basePath.appendPathCopy(entryName); 678a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // If this entry is a directory we'll recurse into it 689102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin if (isDirectory(fullPath.string()) ) { 698a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin DirectoryWalker* copy = dw->clone(); 708a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin findFiles(fullPath, extensions, fileStore,copy); 718a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin delete copy; 728a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin } 738a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 748a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // If this entry is a file, we'll pass it over to checkAndAddFile 759102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin if (isFile(fullPath.string()) ) { 768a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin checkAndAddFile(fullPath,dw->entryStats(),extensions,fileStore); 778a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin } 788a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin } 798a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 808a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Clean up 818a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin dw->closeDir(); 828a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 838a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin return true; 848a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin} 858a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 868a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinvoid SystemFileFinder::checkAndAddFile(String8 path, const struct stat* stats, 878a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin Vector<String8>& extensions, 888a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin KeyedVector<String8,time_t>& fileStore) 898a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin{ 908a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#ifdef DEBUG 918a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin cout << "Checking file " << path << "..."; 928a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#endif // DEBUG 938a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Loop over the extensions, checking for a match 948a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin bool done = false; 958a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin String8 ext(path.getPathExtension()); 968a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin ext.toLower(); 978a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin for (size_t i = 0; i < extensions.size() && !done; ++i) { 988a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin String8 ext2 = extensions[i].getPathExtension(); 998a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin ext2.toLower(); 1008a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Compare the extensions. If a match is found, add to storage. 1018a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin if (ext == ext2) { 1028a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#ifdef DEBUG 1038a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin cout << "Match"; 1048a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#endif // DEBUG 1058a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin done = true; 1068a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin fileStore.add(path,stats->st_mtime); 1078a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin } 1088a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin } 1098a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#ifdef DEBUG 1108a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin cout << endl; 1118a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#endif //DEBUG 1129102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin} 1139102165fd8be64bdc9110d0839a84fcdfa5b68cbJosiah Gaskin 114