View difference between Paste ID: Mzkiv188 and RpshAgZz
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
}