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
19using namespace android;
20
21// Directory Walker
22// This is an abstraction for walking through a directory and getting files
23// and descriptions.
24
25class DirectoryWalker {
26public:
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
53class SystemDirectoryWalker : public DirectoryWalker {
54
55    // Default constructor, copy constructor, and destructor are fine
56public:
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    };
67    virtual bool openDir(const char* path) {
68        String8 p(path);
69        openDir(p);
70        return true;
71    };
72    // Advance to next directory entry
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
85    virtual struct stat*   entryStats() {
86        return &mStats;
87    };
88    virtual void closeDir() {
89        closedir(dir);
90    };
91    virtual DirectoryWalker* clone() {
92        return new SystemDirectoryWalker(*this);
93    };
94private:
95    DIR* dir;
96};
97
98#endif // DIRECTORYWALKER_H
99