Panda3D
Loading...
Searching...
No Matches
dSearchPath.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file dSearchPath.cxx
10 * @author drose
11 * @date 2000-07-01
12 */
13
14#include "dSearchPath.h"
15#include "filename.h"
16
17#include <algorithm>
18#include <iterator>
19
20using std::ostream;
21using std::string;
22
23/**
24 *
25 */
26DSearchPath::Results::
27Results() {
28}
29
30/**
31 *
32 */
33DSearchPath::Results::
34Results(const DSearchPath::Results &copy) :
35 _files(copy._files)
36{
37}
38
39/**
40 *
41 */
42void DSearchPath::Results::
43operator = (const DSearchPath::Results &copy) {
44 _files = copy._files;
45}
46
47/**
48 *
49 */
50DSearchPath::Results::
51~Results() {
52}
53
54/**
55 * Removes all the files from the list.
56 */
58clear() {
59 _files.clear();
60}
61
62/**
63 * Returns the number of files on the result list.
64 */
66get_num_files() const {
67 return _files.size();
68}
69
70/**
71 * Returns the nth file on the result list.
72 */
74get_file(size_t n) const {
75 assert(n < _files.size());
76 return _files[n];
77}
78
79/**
80 * Adds a new file to the result list.
81 */
83add_file(const Filename &file) {
84 _files.push_back(file);
85}
86
87/**
88 *
89 */
90void DSearchPath::Results::
91output(ostream &out) const {
92 out << "[ ";
93 if (!_files.empty()) {
94 Files::const_iterator fi = _files.begin();
95 out << (*fi);
96 ++fi;
97 while (fi != _files.end()) {
98 out << ", " << (*fi);
99 ++fi;
100 }
101 }
102 out << " ]";
103}
104
105/**
106 *
107 */
108void DSearchPath::Results::
109write(ostream &out, int indent_level) const {
110 Files::const_iterator fi;
111 for (fi = _files.begin(); fi != _files.end(); ++fi) {
112 for (int i = 0; i < indent_level; ++i) {
113 out << ' ';
114 }
115 out << (*fi) << "\n";
116 }
117}
118
119/**
120 *
121 */
122DSearchPath::
123DSearchPath(const string &path, const string &separator) {
124 append_path(path, separator);
125}
126
127/**
128 *
129 */
130DSearchPath::
131DSearchPath(const Filename &directory) {
132 append_directory(directory);
133}
134
135/**
136 * Removes all the directories from the search list.
137 */
139clear() {
140 _directories.clear();
141}
142
143/**
144 * Adds a new directory to the end of the search list.
145 */
147append_directory(const Filename &directory) {
148 _directories.push_back(directory);
149}
150
151/**
152 * Adds a new directory to the front of the search list.
153 */
155prepend_directory(const Filename &directory) {
156 _directories.insert(_directories.begin(), directory);
157}
158
159/**
160 * Adds all of the directories listed in the search path to the end of the
161 * search list.
162 */
164append_path(const string &path, const string &separator) {
165 string pathsep = separator;
166 if (pathsep.empty()) {
167 pathsep = DEFAULT_PATHSEP;
168 }
169
170 if (pathsep.empty()) {
171 append_directory(path);
172
173 } else {
174 size_t p = 0;
175 while (p < path.length()) {
176 size_t q = path.find_first_of(pathsep, p);
177 if (q == string::npos) {
178 _directories.push_back(Filename::from_os_specific(path.substr(p)));
179 return;
180 }
181 if (q != p) {
182 _directories.push_back(Filename::from_os_specific(path.substr(p, q - p)));
183 }
184 p = q + 1;
185 }
186 }
187}
188
189/**
190 * Adds all of the directories listed in the search path to the end of the
191 * search list.
192 */
194append_path(const DSearchPath &path) {
195 std::copy(path._directories.begin(), path._directories.end(),
196 std::back_inserter(_directories));
197}
198
199/**
200 * Adds all of the directories listed in the search path to the beginning of
201 * the search list.
202 */
204prepend_path(const DSearchPath &path) {
205 if (!path._directories.empty()) {
206 Directories new_directories = path._directories;
207 std::copy(_directories.begin(), _directories.end(),
208 std::back_inserter(new_directories));
209 _directories.swap(new_directories);
210 }
211}
212
213/**
214 * Returns true if the search list is empty, false otherwise.
215 */
217is_empty() const {
218 return _directories.empty();
219}
220
221/**
222 * Returns the number of directories on the search list.
223 */
224size_t DSearchPath::
225get_num_directories() const {
226 return _directories.size();
227}
228
229/**
230 * Returns the nth directory on the search list.
231 */
233get_directory(size_t n) const {
234 assert(n < _directories.size());
235 return _directories[n];
236}
237
238/**
239 * Searches all the directories in the search list for the indicated file, in
240 * order. Returns the full matching pathname of the first match if found, or
241 * the empty string if not found.
242 */
244find_file(const Filename &filename) const {
245 if (filename.is_local()) {
246 if (_directories.empty()) {
247 // Let's say an empty search path is the same as a search path
248 // containing just ".".
249 if (filename.exists()) {
250 return filename;
251 }
252
253 } else {
254 Directories::const_iterator di;
255 for (di = _directories.begin(); di != _directories.end(); ++di) {
256 Filename match((*di), filename);
257 if (match.exists()) {
258 if ((*di) == "." && filename.is_fully_qualified()) {
259 // A special case for the "." directory: to avoid prefixing an
260 // endless stream of . in front of files, if the filename already
261 // has a . prefixed (i.e. is_fully_qualified() is true), we don't
262 // prefix another one.
263 return filename;
264 } else {
265 return match;
266 }
267 }
268 }
269 }
270 }
271
272 return string();
273}
274
275/**
276 * Searches all the directories in the search list for the indicated file, in
277 * order. Fills up the results list with *all* of the matching filenames
278 * found, if any. Returns the number of matches found.
279 *
280 * It is the responsibility of the the caller to clear the results list first;
281 * otherwise, the newly-found files will be appended to the list.
282 */
284find_all_files(const Filename &filename,
285 DSearchPath::Results &results) const {
286 size_t num_added = 0;
287
288 if (filename.is_local()) {
289 if (_directories.empty()) {
290 // Let's say an empty search path is the same as a search path
291 // containing just ".".
292 if (filename.exists()) {
293 results.add_file(filename);
294 }
295
296 } else {
297 Directories::const_iterator di;
298 for (di = _directories.begin(); di != _directories.end(); ++di) {
299 Filename match((*di), filename);
300 if (match.exists()) {
301 if ((*di) == "." && filename.is_fully_qualified()) {
302 // A special case for the "." directory: to avoid prefixing an
303 // endless stream of . in front of files, if the filename already
304 // has a . prefixed (i.e. is_fully_qualified() is true), we don't
305 // prefix another one.
306 results.add_file(filename);
307 } else {
308 results.add_file(match);
309 }
310 num_added++;
311 }
312 }
313 }
314 }
315
316 return num_added;
317}
318
319/**
320 *
321 */
322void DSearchPath::
323output(ostream &out, const string &separator) const {
324 string pathsep = separator;
325 if (pathsep.empty()) {
326 pathsep = DEFAULT_PATHSEP;
327 if (!pathsep.empty()) {
328 pathsep = pathsep[0];
329 }
330 }
331
332 if (!_directories.empty()) {
333 Directories::const_iterator di = _directories.begin();
334 out << (*di);
335 ++di;
336 while (di != _directories.end()) {
337 out << pathsep << (*di);
338 ++di;
339 }
340 }
341}
342
343/**
344 *
345 */
346void DSearchPath::
347write(ostream &out, int indent_level) const {
348 Directories::const_iterator di;
349 for (di = _directories.begin(); di != _directories.end(); ++di) {
350 for (int i = 0; i < indent_level; ++i) {
351 out << ' ';
352 }
353 out << (*di) << "\n";
354 }
355}
void clear()
Removes all the files from the list.
const Filename & get_file(size_t n) const
Returns the nth file on the result list.
void add_file(const Filename &file)
Adds a new file to the result list.
size_t get_num_files() const
Returns the number of files on the result list.
This class stores a list of directories that can be searched, in order, to locate a particular file.
Definition dSearchPath.h:28
Filename find_file(const Filename &filename) const
Searches all the directories in the search list for the indicated file, in order.
bool is_empty() const
Returns true if the search list is empty, false otherwise.
void append_path(const std::string &path, const std::string &separator=std::string())
Adds all of the directories listed in the search path to the end of the search list.
get_num_directories
Returns the number of directories on the search list.
Definition dSearchPath.h:76
size_t find_all_files(const Filename &filename, Results &results) const
Searches all the directories in the search list for the indicated file, in order.
void prepend_path(const DSearchPath &path)
Adds all of the directories listed in the search path to the beginning of the search list.
void prepend_directory(const Filename &directory)
Adds a new directory to the front of the search list.
void clear()
Removes all the directories from the search list.
void append_directory(const Filename &directory)
Adds a new directory to the end of the search list.
get_directory
Returns the nth directory on the search list.
Definition dSearchPath.h:76
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
bool is_fully_qualified() const
Returns true if the filename is fully qualified, e.g.
Definition filename.I:562
bool is_local() const
Returns true if the filename is local, e.g.
Definition filename.I:549
bool exists() const
Returns true if the filename exists on the physical disk, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.