FileFinder.cpp revision 8a39da80b33691b0c82458c3b7727e13ff71277e
1e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy//
2e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// Copyright 2011 The Android Open Source Project
3e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy//
4e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
5e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// File Finder implementation.
6e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// Implementation for the functions declared and documented in FileFinder.h
7e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
8e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <utils/Vector.h>
9e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <utils/String8.h>
10e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <utils/KeyedVector.h>
11e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
12e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
13e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <iostream>
14e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
15e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include "DirectoryWalker.h"
16e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include "FileFinder.h"
1785bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy
1885bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy//#define DEBUG
1985bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy
2085bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guyusing android::String8;
21e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyusing std::cout;
22e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyusing std::endl;
23e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
2485bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guybool SystemFileFinder::findFiles(String8 basePath, Vector<String8>& extensions,
25e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy                                 KeyedVector<String8,time_t>& fileStore,
2685bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy                                 DirectoryWalker* dw)
2785bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy{
28e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Scan the directory pointed to by basePath
29e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // check files and recurse into subdirectories.
30e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    if (!dw->openDir(basePath)) {
3108ae317c21ec3086b5017672bba87420cc38a407Romain Guy        return false;
3285bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy    }
3385bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#ifdef DEBUG
3408ae317c21ec3086b5017672bba87420cc38a407Romain Guy    cout << "FileFinder looking in " << basePath << endl;
3585bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#endif // DEBUG
3608ae317c21ec3086b5017672bba87420cc38a407Romain Guy    /*
37e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy     *  Go through all directory entries. Check each file using checkAndAddFile
38e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy     *  and recurse into sub-directories.
39e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy     */
40e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    struct dirent* entry;
4185bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy    while ((entry = dw->nextEntry()) != NULL) {
42        String8 entryName(entry->d_name);
43        if (entry->d_name[0] == '.') // Skip hidden files and directories
44            continue;
45
46        String8 fullPath = basePath.appendPathCopy(entryName);
47        // If this entry is a directory we'll recurse into it
48        if (entry->d_type == DT_DIR) {
49            DirectoryWalker* copy = dw->clone();
50            findFiles(fullPath, extensions, fileStore,copy);
51            delete copy;
52        }
53
54        // If this entry is a file, we'll pass it over to checkAndAddFile
55        if (entry->d_type == DT_REG) {
56            checkAndAddFile(fullPath,dw->entryStats(),extensions,fileStore);
57        }
58    }
59
60    // Clean up
61    dw->closeDir();
62
63    return true;
64}
65
66void SystemFileFinder::checkAndAddFile(String8 path, const struct stat* stats,
67                                       Vector<String8>& extensions,
68                                       KeyedVector<String8,time_t>& fileStore)
69{
70#ifdef DEBUG
71    cout << "Checking file " << path << "...";
72#endif // DEBUG
73    // Loop over the extensions, checking for a match
74    bool done = false;
75    String8 ext(path.getPathExtension());
76    ext.toLower();
77    for (size_t i = 0; i < extensions.size() && !done; ++i) {
78        String8 ext2 = extensions[i].getPathExtension();
79        ext2.toLower();
80        // Compare the extensions. If a match is found, add to storage.
81        if (ext == ext2) {
82#ifdef DEBUG
83            cout << "Match";
84#endif // DEBUG
85            done = true;
86            fileStore.add(path,stats->st_mtime);
87        }
88    }
89#ifdef DEBUG
90    cout << endl;
91#endif //DEBUG
92}