xoreos  0.0.5
filelist.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include <boost/filesystem.hpp>
26 #include <boost/regex.hpp>
27 
28 #include "src/common/filelist.h"
29 #include "src/common/filepath.h"
30 
31 // boost-filesystem stuff
32 using boost::filesystem::directory_iterator;
33 
34 namespace Common {
35 
37 }
38 
39 FileList::FileList(const UString &directory, int recurseDepth) {
40  addDirectory(directory, recurseDepth);
41 }
42 
44  *this = list;
45 }
46 
48 }
49 
51  _files = list._files;
52 
53  return *this;
54 }
55 
57  _files.insert(_files.end(), list._files.begin(), list._files.end());
58 
59  return *this;
60 }
61 
63  _files.clear();
64 }
65 
66 bool FileList::empty() const {
67  return _files.empty();
68 }
69 
70 size_t FileList::size() const {
71  return _files.size();
72 }
73 
74 void FileList::sort(bool caseInsensitive) {
75  if (caseInsensitive)
77  else
79 }
80 
81 void FileList::relativize(const Common::UString &basePath) {
82  std::list<UString>::iterator file = _files.begin();
83 
84  while (file != _files.end()) {
85  *file = FilePath::relativize(basePath, *file);
86 
87  if (file->empty())
88  file = _files.erase(file);
89  else
90  ++file;
91  }
92 }
93 
95  return _files.begin();
96 }
97 
99  return _files.end();
100 }
101 
102 bool FileList::addDirectory(const UString &directory, int recurseDepth) {
103  // Not a directory? Fail.
104  if (!FilePath::isDirectory(directory))
105  return false;
106 
107  try {
108  // Iterator over the directory's contents
109  for (directory_iterator itEnd, itDir(directory.c_str()); itDir != itEnd; ++itDir) {
110  const UString path = itDir->path().generic_string();
111 
112  if (FilePath::isDirectory(path)) {
113  // It's a directory. Recurse into it if the depth limit wasn't yet reached
114 
115  if (recurseDepth != 0)
116  if (!addDirectory(path, (recurseDepth == -1) ? -1 : (recurseDepth - 1)))
117  return false;
118 
119  } else
120  // It's a path, add it to the list
121  _files.push_back(FilePath::canonicalize(path, false));
122 
123  }
124  } catch (...) {
125  return false;
126  }
127 
128  return true;
129 }
130 
131 bool FileList::addSubDirectories(const UString &directory) {
132  if (!FilePath::isDirectory(directory))
133  return false;
134 
135  try {
136  // Iterator over the directory's contents
137  for (directory_iterator itEnd, itDir(directory.c_str()); itDir != itEnd; ++itDir) {
138  const UString path = itDir->path().generic_string();
139  if (FilePath::isDirectory(path))
140  _files.push_back(FilePath::canonicalize(path, false));
141  }
142  } catch (...) {
143  return false;
144  }
145 
146  return true;
147 }
148 
149 bool FileList::getSubList(const UString &str, bool caseInsensitive, FileList &subList) const {
150  UString match = caseInsensitive ? str.toLower() : str;
151 
152  bool foundMatch = false;
153 
154  // Iterate through the whole list, adding the matches to the sub list
155  for (Files::const_iterator it = _files.begin(); it != _files.end(); ++it) {
156  bool matching = caseInsensitive ? it->toLower().endsWith(match) : it->endsWith(match);
157 
158  if (matching) {
159  subList._files.push_back(*it);
160  foundMatch = true;
161  }
162  }
163 
164  return foundMatch;
165 }
166 
167 bool FileList::getSubListGlob(const UString &glob, bool caseInsensitive, FileList &subList) const {
168  boost::regex::flag_type type = boost::regex::perl;
169  if (caseInsensitive)
170  type |= boost::regex::icase;
171  boost::regex expression(glob.c_str(), type);
172 
173  bool foundMatch = false;
174 
175  // Iterate through the whole list, adding the matches to the sub list
176  for (Files::const_iterator it = _files.begin(); it != _files.end(); ++it)
177  if (boost::regex_match(it->c_str(), expression)) {
178  subList._files.push_back(*it);
179  foundMatch = true;
180  }
181 
182  return foundMatch;
183 }
184 
185 bool FileList::contains(const UString &str, bool caseInsensitive) const {
186  return !findFirst(str, caseInsensitive).empty();
187 }
188 
189 bool FileList::containsGlob(const UString &glob, bool caseInsensitive) const {
190  return !findFirstGlob(glob, caseInsensitive).empty();
191 }
192 
193 UString FileList::findFirst(const UString &str, bool caseInsensitive) const {
194  UString match = caseInsensitive ? str.toLower() : str;
195 
196  // Iterate through the whole list, adding the matches to the sub list
197  for (Files::const_iterator it = _files.begin(); it != _files.end(); ++it) {
198  bool matching = caseInsensitive ? it->toLower().endsWith(match) : it->endsWith(match);
199 
200  if (matching)
201  return *it;
202  }
203 
204  return "";
205 }
206 
207 UString FileList::findFirstGlob(const UString &glob, bool caseInsensitive) const {
208  boost::regex::flag_type type = boost::regex::perl;
209  if (caseInsensitive)
210  type |= boost::regex::icase;
211  boost::regex expression(glob.c_str(), type);
212 
213  // Iterate through the whole list, adding the matches to the sub list
214  for (Files::const_iterator it = _files.begin(); it != _files.end(); ++it)
215  if (boost::regex_match(it->c_str(), expression))
216  return *it;
217 
218  return "";
219 }
220 
221 } // End of namespace Common
bool addSubDirectories(const UString &directory)
Add subdirectories of a directory to the list.
Definition: filelist.cpp:131
FileList & operator+=(const FileList &list)
Definition: filelist.cpp:56
Definition: 2dafile.h:39
A class holding an UTF-8 string.
Definition: ustring.h:48
static bool isDirectory(const UString &p)
Does specified path exist and is it a directory?
Definition: filepath.cpp:56
bool endsWith(const UString &with) const
Definition: ustring.cpp:315
std::list< UString >::const_iterator const_iterator
Definition: filelist.h:37
UString findFirst(const UString &str, bool caseInsensitive) const
Find the first file ending with the given string.
Definition: filelist.cpp:193
FileList & operator=(const FileList &list)
Definition: filelist.cpp:50
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
static UString canonicalize(const UString &p, bool resolveSymLinks=true)
Return the canonical, absolutized and normalized path.
Definition: filepath.cpp:230
bool empty() const
Is the string empty?
Definition: ustring.cpp:245
size_t size() const
Return the number of files in the list.
Definition: filelist.cpp:70
void relativize(const Common::UString &basePath)
Express all files in this archive as relative to the given base path.
Definition: filelist.cpp:81
bool getSubList(const UString &str, bool caseInsensitive, FileList &subList) const
Add files ending with the given string into another FileList.
Definition: filelist.cpp:149
UString toLower() const
Return a lowercased copy of the string.
Definition: ustring.cpp:481
UString findFirstGlob(const UString &glob, bool caseInsensitive) const
Find the first file matching the given regex.
Definition: filelist.cpp:207
bool empty() const
Is the list empty?
Definition: filelist.cpp:66
static UString relativize(const UString &basePath, const UString &path)
Return the path relative to the base path.
Definition: filepath.cpp:142
A list of files.
Definition: filelist.h:35
const_iterator begin() const
Return a const_iterator pointing to the beginning of the list.
Definition: filelist.cpp:94
bool addDirectory(const UString &directory, int recurseDepth=0)
Add a directory to the list.
Definition: filelist.cpp:102
A list of files.
void clear()
Clear the list.
Definition: filelist.cpp:62
void sort(bool caseInsensitive)
Sort this list alphabetically.
Definition: filelist.cpp:74
bool containsGlob(const UString &glob, bool caseInsensitive) const
Does the list contain at least one file matching the given regex?
Definition: filelist.cpp:189
bool getSubListGlob(const UString &glob, bool caseInsensitive, FileList &subList) const
Add files matching the given regex into another FileList.
Definition: filelist.cpp:167
Utility class for manipulating file paths.
const_iterator end() const
Return a const_iterator pointing past the end of the list.
Definition: filelist.cpp:98
bool contains(const UString &str, bool caseInsensitive) const
Does the list contain at least one file ending with the given string?
Definition: filelist.cpp:185