1*d57664e9SAndroid Build Coastguard Worker // 2*d57664e9SAndroid Build Coastguard Worker // Copyright 2011 The Android Open Source Project 3*d57664e9SAndroid Build Coastguard Worker // 4*d57664e9SAndroid Build Coastguard Worker // Defines an abstraction for opening a directory on the filesystem and 5*d57664e9SAndroid Build Coastguard Worker // iterating through it. 6*d57664e9SAndroid Build Coastguard Worker 7*d57664e9SAndroid Build Coastguard Worker #ifndef DIRECTORYWALKER_H 8*d57664e9SAndroid Build Coastguard Worker #define DIRECTORYWALKER_H 9*d57664e9SAndroid Build Coastguard Worker 10*d57664e9SAndroid Build Coastguard Worker #include <androidfw/PathUtils.h> 11*d57664e9SAndroid Build Coastguard Worker #include <dirent.h> 12*d57664e9SAndroid Build Coastguard Worker #include <sys/types.h> 13*d57664e9SAndroid Build Coastguard Worker #include <sys/param.h> 14*d57664e9SAndroid Build Coastguard Worker #include <sys/stat.h> 15*d57664e9SAndroid Build Coastguard Worker #include <unistd.h> 16*d57664e9SAndroid Build Coastguard Worker #include <utils/String8.h> 17*d57664e9SAndroid Build Coastguard Worker 18*d57664e9SAndroid Build Coastguard Worker #include <stdio.h> 19*d57664e9SAndroid Build Coastguard Worker 20*d57664e9SAndroid Build Coastguard Worker using namespace android; 21*d57664e9SAndroid Build Coastguard Worker 22*d57664e9SAndroid Build Coastguard Worker // Directory Walker 23*d57664e9SAndroid Build Coastguard Worker // This is an abstraction for walking through a directory and getting files 24*d57664e9SAndroid Build Coastguard Worker // and descriptions. 25*d57664e9SAndroid Build Coastguard Worker 26*d57664e9SAndroid Build Coastguard Worker class DirectoryWalker { 27*d57664e9SAndroid Build Coastguard Worker public: ~DirectoryWalker()28*d57664e9SAndroid Build Coastguard Worker virtual ~DirectoryWalker() {}; 29*d57664e9SAndroid Build Coastguard Worker virtual bool openDir(String8 path) = 0; 30*d57664e9SAndroid Build Coastguard Worker virtual bool openDir(const char* path) = 0; 31*d57664e9SAndroid Build Coastguard Worker // Advance to next directory entry 32*d57664e9SAndroid Build Coastguard Worker virtual struct dirent* nextEntry() = 0; 33*d57664e9SAndroid Build Coastguard Worker // Get the stats for the current entry 34*d57664e9SAndroid Build Coastguard Worker virtual struct stat* entryStats() = 0; 35*d57664e9SAndroid Build Coastguard Worker // Clean Up 36*d57664e9SAndroid Build Coastguard Worker virtual void closeDir() = 0; 37*d57664e9SAndroid Build Coastguard Worker // This class is able to replicate itself on the heap 38*d57664e9SAndroid Build Coastguard Worker virtual DirectoryWalker* clone() = 0; 39*d57664e9SAndroid Build Coastguard Worker 40*d57664e9SAndroid Build Coastguard Worker // DATA MEMBERS 41*d57664e9SAndroid Build Coastguard Worker // Current directory entry 42*d57664e9SAndroid Build Coastguard Worker struct dirent mEntry; 43*d57664e9SAndroid Build Coastguard Worker // Stats for that directory entry 44*d57664e9SAndroid Build Coastguard Worker struct stat mStats; 45*d57664e9SAndroid Build Coastguard Worker // Base path 46*d57664e9SAndroid Build Coastguard Worker String8 mBasePath; 47*d57664e9SAndroid Build Coastguard Worker }; 48*d57664e9SAndroid Build Coastguard Worker 49*d57664e9SAndroid Build Coastguard Worker // System Directory Walker 50*d57664e9SAndroid Build Coastguard Worker // This is an implementation of the above abstraction that calls 51*d57664e9SAndroid Build Coastguard Worker // real system calls and is fully functional. 52*d57664e9SAndroid Build Coastguard Worker // functions are inlined since they're very short and simple 53*d57664e9SAndroid Build Coastguard Worker 54*d57664e9SAndroid Build Coastguard Worker class SystemDirectoryWalker : public DirectoryWalker { 55*d57664e9SAndroid Build Coastguard Worker 56*d57664e9SAndroid Build Coastguard Worker // Default constructor, copy constructor, and destructor are fine 57*d57664e9SAndroid Build Coastguard Worker public: openDir(String8 path)58*d57664e9SAndroid Build Coastguard Worker virtual bool openDir(String8 path) { 59*d57664e9SAndroid Build Coastguard Worker mBasePath = path; 60*d57664e9SAndroid Build Coastguard Worker dir = NULL; 61*d57664e9SAndroid Build Coastguard Worker dir = opendir(mBasePath.c_str() ); 62*d57664e9SAndroid Build Coastguard Worker 63*d57664e9SAndroid Build Coastguard Worker if (dir == NULL) 64*d57664e9SAndroid Build Coastguard Worker return false; 65*d57664e9SAndroid Build Coastguard Worker 66*d57664e9SAndroid Build Coastguard Worker return true; 67*d57664e9SAndroid Build Coastguard Worker }; openDir(const char * path)68*d57664e9SAndroid Build Coastguard Worker virtual bool openDir(const char* path) { 69*d57664e9SAndroid Build Coastguard Worker String8 p(path); 70*d57664e9SAndroid Build Coastguard Worker openDir(p); 71*d57664e9SAndroid Build Coastguard Worker return true; 72*d57664e9SAndroid Build Coastguard Worker }; 73*d57664e9SAndroid Build Coastguard Worker // Advance to next directory entry nextEntry()74*d57664e9SAndroid Build Coastguard Worker virtual struct dirent* nextEntry() { 75*d57664e9SAndroid Build Coastguard Worker struct dirent* entryPtr = readdir(dir); 76*d57664e9SAndroid Build Coastguard Worker if (entryPtr == NULL) 77*d57664e9SAndroid Build Coastguard Worker return NULL; 78*d57664e9SAndroid Build Coastguard Worker 79*d57664e9SAndroid Build Coastguard Worker mEntry = *entryPtr; 80*d57664e9SAndroid Build Coastguard Worker // Get stats 81*d57664e9SAndroid Build Coastguard Worker String8 fullPath = appendPathCopy(mBasePath, mEntry.d_name); 82*d57664e9SAndroid Build Coastguard Worker stat(fullPath.c_str(),&mStats); 83*d57664e9SAndroid Build Coastguard Worker return &mEntry; 84*d57664e9SAndroid Build Coastguard Worker }; 85*d57664e9SAndroid Build Coastguard Worker // Get the stats for the current entry entryStats()86*d57664e9SAndroid Build Coastguard Worker virtual struct stat* entryStats() { 87*d57664e9SAndroid Build Coastguard Worker return &mStats; 88*d57664e9SAndroid Build Coastguard Worker }; closeDir()89*d57664e9SAndroid Build Coastguard Worker virtual void closeDir() { 90*d57664e9SAndroid Build Coastguard Worker closedir(dir); 91*d57664e9SAndroid Build Coastguard Worker }; clone()92*d57664e9SAndroid Build Coastguard Worker virtual DirectoryWalker* clone() { 93*d57664e9SAndroid Build Coastguard Worker return new SystemDirectoryWalker(*this); 94*d57664e9SAndroid Build Coastguard Worker }; 95*d57664e9SAndroid Build Coastguard Worker private: 96*d57664e9SAndroid Build Coastguard Worker DIR* dir; 97*d57664e9SAndroid Build Coastguard Worker }; 98*d57664e9SAndroid Build Coastguard Worker 99*d57664e9SAndroid Build Coastguard Worker #endif // DIRECTORYWALKER_H 100