1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski//
2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Copyright 2011 The Android Open Source Project
3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski//
4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Defines an abstraction for opening a directory on the filesystem and
5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// iterating through it.
6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifndef DIRECTORYWALKER_H
8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define DIRECTORYWALKER_H
9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <dirent.h>
11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <sys/types.h>
12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <sys/param.h>
13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <sys/stat.h>
14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <unistd.h>
15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/String8.h>
16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <stdio.h>
18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiusing namespace android;
20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Directory Walker
22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// This is an abstraction for walking through a directory and getting files
23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// and descriptions.
24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass DirectoryWalker {
26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic:
27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual ~DirectoryWalker() {};
28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual bool openDir(String8 path) = 0;
29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual bool openDir(const char* path) = 0;
30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Advance to next directory entry
31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual struct dirent* nextEntry() = 0;
32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Get the stats for the current entry
33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual struct stat*   entryStats() = 0;
34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Clean Up
35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual void closeDir() = 0;
36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // This class is able to replicate itself on the heap
37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual DirectoryWalker* clone() = 0;
38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // DATA MEMBERS
40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Current directory entry
41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    struct dirent mEntry;
42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Stats for that directory entry
43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    struct stat mStats;
44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Base path
45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    String8 mBasePath;
46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski};
47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// System Directory Walker
49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// This is an implementation of the above abstraction that calls
50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// real system calls and is fully functional.
51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// functions are inlined since they're very short and simple
52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass SystemDirectoryWalker : public DirectoryWalker {
54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Default constructor, copy constructor, and destructor are fine
56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic:
57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual bool openDir(String8 path) {
58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mBasePath = path;
59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        dir = NULL;
60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        dir = opendir(mBasePath.string() );
61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (dir == NULL)
63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return false;
64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return true;
66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    };
67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual bool openDir(const char* path) {
68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        String8 p(path);
69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        openDir(p);
70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return true;
71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    };
72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Advance to next directory entry
73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual struct dirent* nextEntry() {
74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        struct dirent* entryPtr = readdir(dir);
75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (entryPtr == NULL)
76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return NULL;
77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mEntry = *entryPtr;
79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // Get stats
80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        String8 fullPath = mBasePath.appendPathCopy(mEntry.d_name);
81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        stat(fullPath.string(),&mStats);
82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return &mEntry;
83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    };
84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Get the stats for the current entry
85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual struct stat*   entryStats() {
86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return &mStats;
87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    };
88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual void closeDir() {
89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        closedir(dir);
90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    };
91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual DirectoryWalker* clone() {
92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return new SystemDirectoryWalker(*this);
93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    };
94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiprivate:
95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    DIR* dir;
96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski};
97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif // DIRECTORYWALKER_H
99