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#include "filelister.h"
22
23#include "debug.h"
24#include "utilities.h"
25
26//for browsing the filesystem
27#include <sys/stat.h>
28#include <sys/types.h>
29#include <dirent.h>
30#include <errno.h>
31#include <iostream>
32#include <algorithm>
33#include <cstring>
34
35using namespace std;
36
37FileLister::FileLister(const string &startPath, bool showDirectories,
38    bool showFiles) : showDirectories(showDirectories), showFiles(showFiles)
39{
40    setPath(startPath, false);
41}
42
43const string &FileLister::getPath()
44{
45    return path;
46}
47
48void FileLister::setPath(const string &path, bool doBrowse)
49{
50    this->path = path;
51
52    if (this->path[path.length() - 1]!='/')
53        this->path += "/";
54
55    if (doBrowse)
56        browse();
57}
58
59const string &FileLister::getFilter()
60{
61    return filter;
62}
63
64void FileLister::setFilter(const string &filter)
65{
66    this->filter = filter;
67}
68
69void FileLister::browse(bool clean)
70{
71    if (clean) {
72        directories.clear();
73        files.clear();
74    }
75
76    if (showDirectories || showFiles) {
77        DIR *dirp;
78        if ((dirp = opendir(path.c_str())) == NULL) {
79            ERROR("Unable to open directory: %s\n", path.c_str());
80            return;
81        }
82
83        string filepath, file;
84        struct stat st;
85        struct dirent *dptr;
86
87        while ((dptr = readdir(dirp))) {
88            file = dptr->d_name;
89
90            if (file[0] == '.' && file != "..")
91                continue;
92
93            filepath = path + file;
94            int statRet = stat(filepath.c_str(), &st);
95            if (statRet == -1) {
96                ERROR("Stat failed on '%s' with error '%s'\n", filepath.c_str(), strerror(errno));
97                continue;
98            }
99            if (find(excludes.begin(), excludes.end(), file) != excludes.end())
100                continue;
101
102            if (S_ISDIR(st.st_mode)) {
103                if (!showDirectories)
104                    continue;
105
106                if (std::find(directories.begin(), directories.end(), file) != directories.end())
107                  continue;
108
109                directories.push_back(file);
110            } else {
111                if (!showFiles)
112                    continue;
113
114                if (std::find(files.begin(), files.end(), file) != files.end())
115                  continue;
116
117                if (filter.compare("*") == 0) {
118                    files.push_back(file);
119                    continue;
120                }
121
122                vector<string> vfilter;
123                split(vfilter, filter, ",");
124                for (vector<string>::iterator it = vfilter.begin(); it != vfilter.end(); ++it) {
125                    if (file.find('.') == string::npos) {
126                        if (!it->empty())
127                            continue;
128
129                        files.push_back(file);
130                        break;
131                    }
132
133                    if (it->length() < file.length()) {
134                        if (file[file.length() - it->length() - 1] != '.')
135                            continue;
136
137                        string file_lowercase =
138                                    file.substr(file.length() - it->length());
139
140                        /* XXX: This won't accept UTF-8 codes.
141                         * Thanksfully file extensions shouldn't contain any. */
142                        transform(file_lowercase.begin(), file_lowercase.end(),
143                                    file_lowercase.begin(), ::tolower);
144
145                        if (file_lowercase.compare(0, it->length(), *it) == 0) {
146                            files.push_back(file);
147                            break;
148                        }
149                    }
150                }
151            }
152        }
153
154        closedir(dirp);
155        sort(files.begin(), files.end(), case_less());
156        sort(directories.begin(), directories.end(), case_less());
157    }
158}
159
160unsigned int FileLister::size()
161{
162    return files.size() + directories.size();
163}
164
165unsigned int FileLister::dirCount()
166{
167    return directories.size();
168}
169
170unsigned int FileLister::fileCount()
171{
172    return files.size();
173}
174
175string FileLister::operator[](uint x)
176{
177    return at(x);
178}
179
180string FileLister::at(uint x)
181{
182    if (x < directories.size())
183        return directories[x];
184    else
185        return files[x-directories.size()];
186}
187
188bool FileLister::isFile(unsigned int x)
189{
190    return x >= directories.size() && x < size();
191}
192
193bool FileLister::isDirectory(unsigned int x)
194{
195    return x < directories.size();
196}
197
198void FileLister::insertFile(const string &file) {
199    files.insert(files.begin(), file);
200}
201
202void FileLister::addExclude(const string &exclude) {
203    excludes.push_back(exclude);
204}
205

Archive Download this file



interactive