~gunchleoc/widelands/bug-1818494-ingame-zoom-freezes

« back to all changes in this revision

Viewing changes to src/fileloc.cc

  • Committer: sirver
  • Date: 2002-02-05 20:54:08 UTC
  • Revision ID: git-v1:df384fd3a5e53be1f37803d1c0381fa993844bf5
Initial revision


git-svn-id: https://widelands.svn.sourceforge.net/svnroot/widelands/trunk@2 37b2a8de-5219-0410-9f54-a31bc463ab9c

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2001 by Holger Rapp 
 
3
 * 
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License
 
6
 * as published by the Free Software Foundation; either version 2
 
7
 * of the License, or (at your option) any later version.
 
8
 * 
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 * 
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
17
 *
 
18
 */
 
19
 
 
20
#include "fileloc.h"
 
21
#include <sys/types.h>
 
22
#include <sys/stat.h>
 
23
#include <string.h>
 
24
 
 
25
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
26
 
 
27
/** class File_Locator
 
28
 *
 
29
 * searches for files in various searchdirs and subdirs.
 
30
 * Reports filenames when files are found.
 
31
 *
 
32
 * Is also able to list files in a convenient way
 
33
 */
 
34
 
 
35
/** File_Locator::File_Locator(void) 
 
36
 *
 
37
 * Some inits. Nothing special
 
38
 *
 
39
 * Args: none
 
40
 * Returns: Nothing
 
41
 */
 
42
File_Locator::File_Locator(void) {
 
43
                  la=LA_SUCCESS;
 
44
                  
 
45
                  for(unsigned int i=0; i<MAX_DIRS; i++) dirs[i][0]='\0';
 
46
                  for(unsigned int i=0; i<MAX_SUBDIRS; i++) subdirs[i][0]='\0';
 
47
                  retval[0]='\0';
 
48
                  def_writedir=0;
 
49
 
 
50
                  curdir=NULL;
 
51
                  ncurdir=-1;
 
52
                  nlisttype=-1;
 
53
                  ndirstrlen=0;
 
54
}
 
55
 
 
56
/** File_Locator::~File_Locator(void) 
 
57
 *
 
58
 * Cleanups.
 
59
 *
 
60
 * Args: None
 
61
 * Returns: Nothing
 
62
 */
 
63
File_Locator::~File_Locator(void) {
 
64
}
 
65
 
 
66
/** void File_Locator::add_searchdir(const char* dir, const unsigned int prio)
 
67
 *
 
68
 * This adds a dir to the directorys to search. the priority
 
69
 * is where to add the dir (so MAX_DIRS-1 is lowest, 0 is highest)
 
70
 *
 
71
 * Args:        dir     Directory to add
 
72
 *              prio    Priority of the dir
 
73
 * Returns: Nothing
 
74
 */
 
75
void File_Locator::add_searchdir(const char* dir, const unsigned int prio) {
 
76
                  if(prio>= MAX_DIRS) {
 
77
                                         la=LA_TOOMUCH;
 
78
                                         return;
 
79
                  }
 
80
                  
 
81
                  struct stat st;
 
82
                  if(stat(dir, &st) == -1) {
 
83
                                         la=LA_NOTEXISTING;
 
84
                                         return;
 
85
                  }
 
86
                  
 
87
                  if(!S_ISDIR(st.st_mode)) {
 
88
                                         la=LA_NOTALLOWED;
 
89
                                         return;
 
90
                  }
 
91
                  strcpy(dirs[prio], dir);
 
92
                  if(dirs[prio][strlen(dirs[prio])-1]!=CSEP) {
 
93
                                         int len=strlen(dirs[prio]);
 
94
                                         dirs[prio][len]=CSEP;
 
95
                                         dirs[prio][len+1]='\0';
 
96
                  }
 
97
                  la=LA_SUCCESS;
 
98
}
 
99
 
 
100
/* File_Locator::Last_action File_Locator::get_state(void) const
 
101
 *
 
102
 * This functions returns the error code of the last action
 
103
 *
 
104
 * Args: None
 
105
 * Returns: Success information on last action
 
106
 */
 
107
File_Locator::Last_action File_Locator::get_state(void) const {
 
108
                  return la;
 
109
}
 
110
 
 
111
/** void File_Locator::register_subdir(const int id, const char* subd) 
 
112
 *
 
113
 * This function registers a subdir with a certain type of 
 
114
 * file type (for ex: #define TYPE_TEXT 0  ; register_subdir(TYPE_TEXT, "txts"))
 
115
 *
 
116
 * Args:        id      id to identify with 
 
117
 *         subd subdir to identify with
 
118
 *      
 
119
 *      Returns: nothing
 
120
 */
 
121
void File_Locator::register_subdir(const unsigned int id, const char* subd) {
 
122
                  if(id>= MAX_SUBDIRS) {
 
123
                                         la=LA_TOOMUCH;
 
124
                                         return;
 
125
                  }
 
126
                  
 
127
                  strcpy(subdirs[id], subd);
 
128
                  if(subdirs[id][strlen(subdirs[id])-1]!=CSEP) {
 
129
                                         int len=strlen(subdirs[id]);
 
130
                                         subdirs[id][len]=CSEP;
 
131
                                         subdirs[id][len+1]='\0';
 
132
                  }
 
133
                  la=LA_SUCCESS;
 
134
}
 
135
 
 
136
/** void File_Locator::locate_file(const char* file, const int type=-1)
 
137
 *
 
138
 * This file locates a file in the registered dirs
 
139
 *
 
140
 * Args:        file    filename to find
 
141
 *              type    subdir id to use/ if -1 == don't use subdirs
 
142
 *
 
143
 * Returns: a pathname to the first valid file found
 
144
 */
 
145
const char* File_Locator::locate_file(const char* file, const int type = -1) {
 
146
                  if(type >= (int) MAX_SUBDIRS) {
 
147
                                         la=LA_NOTALLOWED;
 
148
                                         return NULL;
 
149
                  }
 
150
 
 
151
                  la=LA_NOTEXISTING;
 
152
                  
 
153
                  struct stat st;
 
154
 
 
155
                  for(unsigned int n=0; n<MAX_DIRS; n++) {
 
156
                                         if(dirs[n][0]=='\0') continue;
 
157
 
 
158
                                         strcpy(retval, dirs[n]);
 
159
                                         if(type != -1) strcat(retval, subdirs[type]);
 
160
                                         strcat(retval, file);
 
161
 
 
162
                                         // Stat this file!
 
163
                                         if(stat(retval, &st) == -1) {
 
164
                                                                // Not Found. Next one
 
165
                                                                continue;
 
166
                                         }
 
167
 
 
168
                                         // Found
 
169
                                         la=LA_SUCCESS;
 
170
                                         break;
 
171
                  }
 
172
                                         
 
173
                  if(la==LA_SUCCESS) {
 
174
                                         return retval;
 
175
                  }
 
176
                  
 
177
                  // not found
 
178
                  return NULL;
 
179
}
 
180
 
 
181
/* const char* File_Locator::get_new_filename(const char* file, const int type=-1)
 
182
 *
 
183
 * This functions returns a valid filename in the default write dir
 
184
 *
 
185
 * Args: file   Filename to create
 
186
 *              type    file type to create
 
187
 * Returns:     Path to complete filename
 
188
 */
 
189
const char* File_Locator::get_new_filename(const char* file, const int type=-1) {
 
190
                  if(type >= (int) MAX_SUBDIRS) {
 
191
                                         la=LA_NOTALLOWED;
 
192
                                         return NULL;
 
193
                  }
 
194
                  
 
195
                  la=LA_NOTALLOWED;
 
196
 
 
197
                  for(unsigned int n=def_writedir; n<MAX_DIRS; n++) {
 
198
                                         if(dirs[n][0]=='\0') continue;
 
199
                                                                
 
200
                                         strcpy(retval, dirs[n]);
 
201
                                         if(type != -1) strcat(retval, subdirs[type]);
 
202
                                         strcat(retval, file);
 
203
 
 
204
                                         la=LA_SUCCESS;
 
205
                                         break;
 
206
                  }
 
207
                  
 
208
                  if(la==LA_SUCCESS) {
 
209
                                         return retval;
 
210
                  }
 
211
 
 
212
                  // Some error
 
213
                  return NULL;
 
214
}
 
215
                                         
 
216
/* void File_Locator::set_def_writedir(const int id) 
 
217
 *
 
218
 * This functions sets the default write dir by the priority of
 
219
 * the registered searchdirs.
 
220
 *
 
221
 * Args: id             Directory of this priority should be used as default write dir
 
222
 * Returns: Nothing
 
223
 */
 
224
void File_Locator::set_def_writedir(const unsigned int id) {
 
225
                  if(id >= (int) MAX_DIRS) {
 
226
                                         la=LA_NOTALLOWED;
 
227
                                         return;
 
228
                  }
 
229
 
 
230
                  if(dirs[id][0] == '\0') {
 
231
                                         la=LA_NOTSET;
 
232
                                         return;
 
233
                  }
 
234
 
 
235
                  def_writedir=id;
 
236
                  la=LA_SUCCESS;
 
237
}
 
238
 
 
239
/* void File_Locator::init_filelisting( const int type, const unsigned char postfix[5] );
 
240
 *
 
241
 * This functions inits the filelisting. it registeres the prefix and opens the first dir
 
242
 *
 
243
 * Args: type           Which kinds of file to list
 
244
 *              postfix With what should the files end
 
245
 * Returns: Nothing
 
246
 */
 
247
void File_Locator::init_filelisting( const int type, const char postfix[5] ) {
 
248
                  if(type >= (int) MAX_SUBDIRS) {
 
249
                                         la=LA_NOTALLOWED;
 
250
                                         return;
 
251
                  }
 
252
                  
 
253
                  la=LA_NOTALLOWED;
 
254
                  
 
255
                  nlisttype=type;
 
256
                  ncurdir=0;
 
257
 
 
258
                  if(ncurdir<(int) MAX_DIRS) 
 
259
                                         open_next_dir();
 
260
 
 
261
                  if(!curdir) return;
 
262
 
 
263
                  if(postfix[0]!='\0') {
 
264
                                         strncpy(suf, postfix, 5);
 
265
                  } else {
 
266
                                         suf[0]='\0';
 
267
                  }
 
268
 
 
269
                  la=LA_SUCCESS;
 
270
 
 
271
                  return;
 
272
}
 
273
 
 
274
/** void File_Locator::open_next_dir(void) 
 
275
 *
 
276
 * PRIVATE FUNCTION
 
277
 *
 
278
 * this functions trys to open the next valid dir
 
279
 *
 
280
 * Args:        none
 
281
 * Returns: Nothing
 
282
 */
 
283
void File_Locator::open_next_dir(void)  {
 
284
                  if(ncurdir<0) return;
 
285
 
 
286
                  if(curdir) closedir(curdir);
 
287
                  curdir=NULL;
 
288
 
 
289
                  retval[0]='\0';
 
290
 
 
291
                  for(; ncurdir<(int)MAX_DIRS; ncurdir++) {
 
292
                                         if(dirs[ncurdir][0]=='\0') continue;
 
293
                                                                
 
294
                                         strcpy(retval, dirs[ncurdir]);
 
295
                                         if(nlisttype != -1) strcat(retval, subdirs[nlisttype]);
 
296
                                         ncurdir++;
 
297
 
 
298
                                         break;
 
299
                  }
 
300
 
 
301
 
 
302
                  // Try to open the dir
 
303
                  curdir=opendir(retval);
 
304
        
 
305
                  if(!curdir && ncurdir<(int)MAX_DIRS) {
 
306
                                         // dir is invalid, but there are others. try them
 
307
                                         open_next_dir();
 
308
                                         return;
 
309
                  }
 
310
                
 
311
                  ndirstrlen=strlen(retval);
 
312
                  
 
313
}
 
314
 
 
315
/** void File_Locator::end_filelisting(void) 
 
316
 *
 
317
 * This ends the file listing process, does cleanup
 
318
 *
 
319
 * Args: none
 
320
 * Returns: noting
 
321
 */
 
322
void File_Locator::end_filelisting(void) {
 
323
                  if(curdir) closedir(curdir);
 
324
                  ncurdir=-1;
 
325
                  nlisttype=-1;
 
326
                  ndirstrlen=0;
 
327
                  
 
328
                  la=LA_SUCCESS;
 
329
}
 
330
 
 
331
/** const char* File_Locator::get_next_file(void);
 
332
 *
 
333
 * This functions returns the next file in the file listing
 
334
 * process
 
335
 *
 
336
 * Args: None
 
337
 * Returns: The next file
 
338
 */
 
339
const char* File_Locator::get_next_file(void) {
 
340
                  if(la==LA_NOMOREFILES) return NULL;
 
341
                  if(ncurdir<0) {
 
342
                                         la=LA_NOTALLOWED;
 
343
                                         return NULL;
 
344
                  }
 
345
 
 
346
                  assert(curdir);
 
347
                  
 
348
                  struct dirent *file;
 
349
 
 
350
                  // reset the retval to just contain the dir
 
351
                  retval[ndirstrlen]='\0';
 
352
                  
 
353
                  file=readdir(curdir);
 
354
                  if(!file) {
 
355
                                         // Last file in dir
 
356
                                         open_next_dir();
 
357
                                         if(!curdir) {
 
358
                                                                // last file to list is done
 
359
                                                                // return NULL, set la accordingly
 
360
                                                                la=LA_NOMOREFILES;
 
361
                                                                return NULL;
 
362
                                         }
 
363
                                         return get_next_file();
 
364
                  }
 
365
 
 
366
                  // strcat the file and return it
 
367
                  strcat(retval, file->d_name);
 
368
                  
 
369
                  // Make sure the prefix is valid
 
370
                  if(suf[0]!='\0' && strlen(retval)>strlen(suf)) {
 
371
                                         unsigned int n=0;
 
372
                                         for(n=strlen(suf)-1; n>0; --n) {
 
373
                                                                if(suf[strlen(suf)-n]!=retval[strlen(retval)-n]) break;
 
374
                                         }
 
375
                                         if(n) return get_next_file();
 
376
                  }
 
377
                  
 
378
                  la=LA_SUCCESS;
 
379
                  
 
380
                  return retval;
 
381
}