18a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// 28a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// Copyright 2011 The Android Open Source Project 38a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// 48a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// Defines an abstraction for opening a directory on the filesystem and 58a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// iterating through it. 68a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 78a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#ifndef DIRECTORYWALKER_H 88a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#define DIRECTORYWALKER_H 98a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 108a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <dirent.h> 118a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <sys/types.h> 128a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <sys/param.h> 138a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <sys/stat.h> 148a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <unistd.h> 158a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <utils/String8.h> 168a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 178a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <stdio.h> 188a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 198a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinusing namespace android; 208a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 218a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// Directory Walker 228a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// This is an abstraction for walking through a directory and getting files 238a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// and descriptions. 248a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 258a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinclass DirectoryWalker { 268a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinpublic: 278a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin virtual ~DirectoryWalker() {}; 288a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin virtual bool openDir(String8 path) = 0; 298a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin virtual bool openDir(const char* path) = 0; 308a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Advance to next directory entry 318a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin virtual struct dirent* nextEntry() = 0; 328a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Get the stats for the current entry 338a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin virtual struct stat* entryStats() = 0; 348a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Clean Up 358a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin virtual void closeDir() = 0; 368a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // This class is able to replicate itself on the heap 378a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin virtual DirectoryWalker* clone() = 0; 388a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 398a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // DATA MEMBERS 408a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Current directory entry 418a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin struct dirent mEntry; 428a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Stats for that directory entry 438a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin struct stat mStats; 448a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Base path 458a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin String8 mBasePath; 468a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin}; 478a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 488a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// System Directory Walker 498a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// This is an implementation of the above abstraction that calls 508a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// real system calls and is fully functional. 518a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// functions are inlined since they're very short and simple 528a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 538a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinclass SystemDirectoryWalker : public DirectoryWalker { 548a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 558a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Default constructor, copy constructor, and destructor are fine 568a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinpublic: 578a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin virtual bool openDir(String8 path) { 588a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin mBasePath = path; 598a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin dir = NULL; 608a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin dir = opendir(mBasePath.string() ); 618a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 628a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin if (dir == NULL) 638a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin return false; 648a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 658a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin return true; 668a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin }; 678a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin virtual bool openDir(const char* path) { 688a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin String8 p(path); 698a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin openDir(p); 708a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin return true; 718a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin }; 728a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Advance to next directory entry 738a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin virtual struct dirent* nextEntry() { 748a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin struct dirent* entryPtr = readdir(dir); 758a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin if (entryPtr == NULL) 768a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin return NULL; 778a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 788a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin mEntry = *entryPtr; 798a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Get stats 808a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin String8 fullPath = mBasePath.appendPathCopy(mEntry.d_name); 818a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin stat(fullPath.string(),&mStats); 828a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin return &mEntry; 838a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin }; 848a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin // Get the stats for the current entry 858a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin virtual struct stat* entryStats() { 868a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin return &mStats; 878a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin }; 888a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin virtual void closeDir() { 898a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin closedir(dir); 908a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin }; 918a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin virtual DirectoryWalker* clone() { 928a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin return new SystemDirectoryWalker(*this); 938a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin }; 948a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinprivate: 958a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin DIR* dir; 968a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin}; 978a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin 988a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#endif // DIRECTORYWALKER_H 99