//
// Copyright 2011 The Android Open Source Project
//
// Defines an abstraction for opening a directory on the filesystem and
// iterating through it.
#ifndef DIRECTORYWALKER_H
#define DIRECTORYWALKER_H
#include <dirent.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>
#include <utils/String8.h>
#include <stdio.h>
using namespace android;
// Directory Walker
// This is an abstraction for walking through a directory and getting files
// and descriptions.
class DirectoryWalker {
public:
virtual ~DirectoryWalker() {};
virtual bool openDir(String8 path) = 0;
virtual bool openDir(const char* path) = 0;
// Advance to next directory entry
virtual struct dirent* nextEntry() = 0;
// Get the stats for the current entry
virtual struct stat* entryStats() = 0;
// Clean Up
virtual void closeDir() = 0;
// This class is able to replicate itself on the heap
virtual DirectoryWalker* clone() = 0;
// DATA MEMBERS
// Current directory entry
struct dirent mEntry;
// Stats for that directory entry
struct stat mStats;
// Base path
String8 mBasePath;
};
// System Directory Walker
// This is an implementation of the above abstraction that calls
// real system calls and is fully functional.
// functions are inlined since they're very short and simple
class SystemDirectoryWalker : public DirectoryWalker {
// Default constructor, copy constructor, and destructor are fine
public:
virtual bool openDir(String8 path) {
mBasePath = path;
dir = NULL;
dir = opendir(mBasePath.string() );
if (dir == NULL)
return false;
return true;
};
virtual bool openDir(const char* path) {
String8 p(path);
openDir(p);
return true;
};
// Advance to next directory entry
virtual struct dirent* nextEntry() {
struct dirent* entryPtr = readdir(dir);
if (entryPtr == NULL)
return NULL;
mEntry = *entryPtr;
// Get stats
String8 fullPath = mBasePath.appendPathCopy(mEntry.d_name);
stat(fullPath.string(),&mStats);
return &mEntry;
};
// Get the stats for the current entry
virtual struct stat* entryStats() {
return &mStats;
};
virtual void closeDir() {
closedir(dir);
};
virtual DirectoryWalker* clone() {
return new SystemDirectoryWalker(*this);
};
private:
DIR* dir;
};
#endif // DIRECTORYWALKER_H