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