SHOW:
|
|
- or go back to the newest paste.
| 1 | #include <iostream> | |
| 2 | #include <vector> | |
| 3 | #include <dirent.h> | |
| 4 | ||
| 5 | class MyDir {
| |
| 6 | public: | |
| 7 | typedef struct dir_entry * dir_entry_t; | |
| 8 | struct dir_entry {
| |
| 9 | - | struct dir_entry *subdirs; |
| 9 | + | |
| 10 | void *subdirs; | |
| 11 | }; | |
| 12 | ||
| 13 | typedef std::vector<struct dir_entry> dirs_t; | |
| 14 | ||
| 15 | MyDir(std::string path); | |
| 16 | ~MyDir(void); | |
| 17 | ||
| 18 | MyDir::dirs_t find(std::string str); | |
| 19 | ||
| 20 | private: | |
| 21 | dirs_t *dirs; | |
| 22 | void parse_dir(std::string prefix, std::string subpath, dirs_t *dir); | |
| 23 | void _find(std::string str, MyDir::dirs_t *results, | |
| 24 | MyDir::dirs_t *cdir); | |
| 25 | }; | |
| 26 | ||
| 27 | MyDir::MyDir(std::string path) {
| |
| 28 | this->dirs = new dirs_t; | |
| 29 | ||
| 30 | this->parse_dir(path, "", this->dirs); | |
| 31 | } | |
| 32 | ||
| 33 | static inline void destroy_dir_entry(MyDir::dirs_t *dir) {
| |
| 34 | MyDir::dirs_t::iterator it; | |
| 35 | ||
| 36 | for (it = dir->begin(); it != dir->end(); it++) {
| |
| 37 | if (it->subdirs != NULL) | |
| 38 | destroy_dir_entry((MyDir::dirs_t *)it->subdirs); | |
| 39 | } | |
| 40 | ||
| 41 | delete dir; | |
| 42 | } | |
| 43 | ||
| 44 | MyDir::~MyDir(void) {
| |
| 45 | destroy_dir_entry(this->dirs); | |
| 46 | } | |
| 47 | ||
| 48 | static inline int my_dir_filter(struct dirent *entry) {
| |
| 49 | std::string name = entry->d_name; | |
| 50 | ||
| 51 | if (name == "." || name == "..") | |
| 52 | return 0; | |
| 53 | ||
| 54 | if (entry->d_type == DT_DIR) | |
| 55 | return 1; | |
| 56 | ||
| 57 | return 0; | |
| 58 | } | |
| 59 | ||
| 60 | void MyDir::parse_dir(std::string prefix, std::string subpath, dirs_t *dir) {
| |
| 61 | struct dirent **dirs; | |
| 62 | int rval = 0; | |
| 63 | std::string full_path = prefix; | |
| 64 | ||
| 65 | if (full_path[full_path.length() - 1] != '/') | |
| 66 | full_path += '/'; | |
| 67 | ||
| 68 | full_path += subpath; | |
| 69 | ||
| 70 | rval = scandir(full_path.c_str(), &dirs, my_dir_filter, NULL); | |
| 71 | ||
| 72 | struct dir_entry dentry; | |
| 73 | dentry.name = subpath; | |
| 74 | dentry.path = full_path; | |
| 75 | dentry.subdirs = NULL; | |
| 76 | ||
| 77 | if (rval == -1 || !rval) {
| |
| 78 | dir->push_back(dentry); | |
| 79 | ||
| 80 | return; | |
| 81 | } | |
| 82 | ||
| 83 | dirs_t *cdir = new dirs_t; | |
| 84 | dentry.subdirs = (dir_entry_t)cdir; | |
| 85 | dir->push_back(dentry); | |
| 86 | ||
| 87 | for (int i = 0; i != rval; i++) {
| |
| 88 | std::string spath = dirs[i]->d_name; | |
| 89 | ||
| 90 | parse_dir(full_path, spath, cdir); | |
| 91 | } | |
| 92 | } | |
| 93 | ||
| 94 | void MyDir::_find | |
| 95 | (std::string str, dirs_t *results, MyDir::dirs_t *cdir) {
| |
| 96 | MyDir::dirs_t::iterator it; | |
| 97 | ||
| 98 | for (it = cdir->begin(); it != cdir->end(); it++) {
| |
| 99 | if (it->name.find(str) != std::string::npos) | |
| 100 | results->push_back(*it); | |
| 101 | ||
| 102 | if (it->subdirs != NULL) | |
| 103 | _find(str, results, (MyDir::dirs_t *)it->subdirs); | |
| 104 | } | |
| 105 | } | |
| 106 | ||
| 107 | MyDir::dirs_t MyDir::find(std::string str) {
| |
| 108 | dirs_t results; | |
| 109 | ||
| 110 | this->_find(str, &results, this->dirs); | |
| 111 | ||
| 112 | return results; | |
| 113 | } | |
| 114 | ||
| 115 | int main(int argc, char **argv) {
| |
| 116 | if (argc != 3) | |
| 117 | return 1; | |
| 118 | ||
| 119 | std::cout << "Indexing " << argv[1] << " ..." << std::endl; | |
| 120 | MyDir dir(argv[1]); | |
| 121 | ||
| 122 | std::cout << "Searching for" << argv[2] << " ..." << std::endl; | |
| 123 | MyDir::dirs_t find_results = dir.find(argv[2]); | |
| 124 | ||
| 125 | std::cout << "Results (" << find_results.size() << "):" << std::endl;
| |
| 126 | ||
| 127 | MyDir::dirs_t::iterator fit; | |
| 128 | for (fit = find_results.begin(); fit != find_results.end(); fit++) {
| |
| 129 | std::cout << fit->path << std::endl; | |
| 130 | } | |
| 131 | ||
| 132 | return 0; | |
| 133 | } |