Root/src/filelister.cpp

1/***************************************************************************
2 * Copyright (C) 2006 by Massimiliano Torromeo *
3 * massimiliano.torromeo@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21//for browsing the filesystem
22#include <sys/stat.h>
23#include <sys/types.h>
24#include <dirent.h>
25#include <errno.h>
26#include <iostream>
27#include <algorithm>
28#include <cstring>
29
30#include "filelister.h"
31#include "utilities.h"
32#include "debug.h"
33
34using namespace std;
35
36FileLister::FileLister(const string &startPath, bool showDirectories,
37    bool showFiles) : showDirectories(showDirectories), showFiles(showFiles)
38{
39    setPath(startPath, false);
40}
41
42const string &FileLister::getPath()
43{
44    return path;
45}
46
47void FileLister::setPath(const string &path, bool doBrowse)
48{
49    this->path = path;
50
51    if (this->path[path.length() - 1]!='/')
52        this->path += "/";
53
54    if (doBrowse)
55        browse();
56}
57
58const string &FileLister::getFilter()
59{
60    return filter;
61}
62
63void FileLister::setFilter(const string &filter)
64{
65    this->filter = filter;
66}
67
68void FileLister::browse(bool clean)
69{
70    if (clean) {
71        directories.clear();
72        files.clear();
73    }
74
75    if (showDirectories || showFiles) {
76        DIR *dirp;
77        if ((dirp = opendir(path.c_str())) == NULL) {
78            ERROR("Unable to open directory: %s\n", path.c_str());
79            return;
80        }
81
82        vector<string> vfilter;
83        split(vfilter, getFilter(), ",");
84
85        string filepath, file, file_lowercase;
86        struct stat st;
87        struct dirent *dptr;
88
89        while ((dptr = readdir(dirp))) {
90            file = dptr->d_name;
91            file_lowercase = file;
92            std::transform(file_lowercase.begin(), file_lowercase.end(), file_lowercase.begin(), ::tolower);
93
94            if (file[0] == '.' && file != "..")
95                continue;
96
97            filepath = path + file;
98            int statRet = stat(filepath.c_str(), &st);
99            if (statRet == -1) {
100                ERROR("Stat failed on '%s' with error '%s'\n", filepath.c_str(), strerror(errno));
101                continue;
102            }
103            if (find(excludes.begin(), excludes.end(), file) != excludes.end())
104                continue;
105
106            if (S_ISDIR(st.st_mode)) {
107                if (!showDirectories)
108                    continue;
109
110                if (std::find(directories.begin(), directories.end(), file) != directories.end())
111                  continue;
112
113                directories.push_back(file);
114            } else {
115                if (!showFiles)
116                    continue;
117
118                if (std::find(files.begin(), files.end(), file) != files.end())
119                  continue;
120
121                for (vector<string>::iterator it = vfilter.begin(); it != vfilter.end(); ++it) {
122                    if (it->length() <= file.length()) {
123                        if (file_lowercase.compare(file.length() - it->length(), it->length(), *it) == 0) {
124                            files.push_back(file);
125                            break;
126                        }
127                    }
128                }
129            }
130        }
131
132        closedir(dirp);
133        sort(files.begin(), files.end(), case_less());
134        sort(directories.begin(), directories.end(), case_less());
135    }
136}
137
138unsigned int FileLister::size()
139{
140    return files.size() + directories.size();
141}
142
143unsigned int FileLister::dirCount()
144{
145    return directories.size();
146}
147
148unsigned int FileLister::fileCount()
149{
150    return files.size();
151}
152
153string FileLister::operator[](uint x)
154{
155    return at(x);
156}
157
158string FileLister::at(uint x)
159{
160    if (x < directories.size())
161        return directories[x];
162    else
163        return files[x-directories.size()];
164}
165
166bool FileLister::isFile(unsigned int x)
167{
168    return x >= directories.size() && x < size();
169}
170
171bool FileLister::isDirectory(unsigned int x)
172{
173    return x < directories.size();
174}
175
176void FileLister::insertFile(const string &file) {
177    files.insert(files.begin(), file);
178}
179
180void FileLister::addExclude(const string &exclude) {
181    excludes.push_back(exclude);
182}
183

Archive Download this file



interactive