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