source: trunk/gsdl/lib/fileutil.cpp@ 1864

Last change on this file since 1864 was 1864, checked in by sjboddie, 23 years ago

Fixed a couple of minor things to get it compiling on windows again

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 10.9 KB
Line 
1/**********************************************************************
2 *
3 * fileutil.cpp --
4 * Copyright (C) 1999 The New Zealand Digital Library Project
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *********************************************************************/
25
26#include "fileutil.h"
27
28#if defined(GSDL_USE_OBJECTSPACE)
29# include <ospace\std\iostream>
30# include <ospace\std\fstream>
31#elif defined(GSDL_USE_IOS_H)
32# include <iostream.h>
33# include <fstream.h>
34#else
35# include <iostream>
36# include <fstream>
37#endif
38
39
40// returns the proper concatenation of the two paths
41text_t filename_cat (text_t path1, text_t path2) {
42 text_t::iterator here;
43 text_t::iterator begin;
44 text_t::iterator end;
45
46 // make sure there is just one slash, of the correct type,
47 // at the end of path1 (unless path1 is an empty string).
48 if (!path1.empty()) {
49 // remove all trailing slashes
50 here = path1.end();
51 here--;
52 begin = path1.begin();
53 while (here != begin && (*here == '/' || *here == '\\')) {
54 here--;
55 }
56 here++;
57 path1.erase(here,path1.end());
58
59 // add one final slash
60#ifdef __WIN32__
61 path1 += "\\";
62#else
63 path1 += "/";
64#endif
65 }
66
67 // remove all slashes from the start of path2
68 here = path2.begin();
69 end = path2.end();
70 while (here != end && (*here == '/' || *here == '\\')) {
71 here++;
72 }
73 path2.erase (path2.begin(), here);
74
75 text_t fullpath = path1 + path2;
76
77 // make sure all the right slashes are used
78 here = fullpath.begin();
79 end = fullpath.end();
80 while (here != end) {
81#ifdef __WIN32__
82 if (*here == '/') *here = '\\';
83#else
84 if (*here == '\\') *here = '/';
85#endif
86 here ++;
87 }
88 return fullpath;
89}
90
91text_t filename_cat (text_t path1, text_t path2, text_t path3) {
92 return filename_cat(filename_cat(path1,path2),path3);
93}
94
95text_t filename_cat (text_t path1, text_t path2, text_t path3, text_t path4) {
96 return filename_cat(filename_cat(filename_cat(path1,path2),path3),path4);
97}
98
99text_t filename_cat (text_t path1, text_t path2, text_t path3, text_t path4,
100 text_t path5) {
101 return filename_cat(filename_cat(filename_cat(filename_cat(path1,path2),path3),
102 path4),path5);
103}
104
105text_t filename_cat (text_t path1, text_t path2, text_t path3, text_t path4,
106 text_t path5, text_t path6) {
107 return filename_cat(filename_cat(path1,path2,path3,path4,path5),path6);
108}
109
110// returns true if filename can be opened
111bool file_exists (const text_t &filename) {
112 char *cstr = filename.getcstr();
113#ifdef GSDL_USE_IOS_H
114 ifstream filestream (cstr, ios::in | ios::nocreate);
115#else
116 ifstream filestream (cstr, ios::in);
117#endif
118 delete cstr;
119
120 if (filestream) {
121 // file exists
122 filestream.close ();
123 return true;
124 }
125
126 // file does not exist
127 return false;
128}
129
130// returns true if filename can be opened
131bool file_writable (const text_t &filename) {
132 char *cstr = filename.getcstr();
133#ifdef GSDL_USE_IOS_H
134 ifstream filestream (cstr, ios::out | ios::nocreate);
135#else
136 ifstream filestream (cstr, ios::out);
137#endif
138 delete cstr;
139
140 if (filestream) {
141 // file exists
142 filestream.close ();
143 return true;
144 }
145
146 // file does not exist
147 return false;
148}
149
150#if defined(__WIN32__) && !defined(__GNUC__)
151
152#include <windows.h>
153
154bool directory_exists (const text_t &dirname) {
155
156 WIN32_FIND_DATA FileData;
157 HANDLE hSearch;
158 char *dirpath = dirname.getcstr();
159 strcat (dirpath, "\\*");
160
161 hSearch = FindFirstFile(dirpath, &FileData);
162 if (hSearch == INVALID_HANDLE_VALUE) {
163 delete dirpath;
164 return false;
165 }
166
167 FindClose (hSearch);
168 // freeing this memory can cause a runtime error on some (particularly
169 // debug) versions of VC++
170 delete dirpath;
171 return true;
172}
173
174bool read_dir (const text_t &dirname, text_tset &filelist) {
175
176 WIN32_FIND_DATA FileData;
177 HANDLE hSearch;
178 char *dirpath = dirname.getcstr();
179 strcat (dirpath, "\\*");
180
181 hSearch = FindFirstFile(dirpath, &FileData);
182 if (hSearch == INVALID_HANDLE_VALUE) {
183 delete dirpath;
184 return false;
185 }
186
187 text_t filename = FileData.cFileName;
188 if (filename != "." && filename != ".." && filename != "CVS")
189 filelist.insert (filename);
190
191 while (FindNextFile(hSearch, &FileData)) {
192 filename = FileData.cFileName;
193 if (filename == "." || filename == ".." || filename == "CVS")
194 continue;
195 filelist.insert (filename);
196 }
197
198 FindClose(hSearch);
199 // freeing this memory can cause a runtime error on some (particularly
200 // debug) versions of VC++
201 delete dirpath;
202
203 return true;
204}
205
206bool read_dir (const text_t &dirname, text_tarray &filelist) {
207
208 WIN32_FIND_DATA FileData;
209 HANDLE hSearch;
210 char *dirpath = dirname.getcstr();
211 strcat (dirpath, "\\*");
212
213 hSearch = FindFirstFile(dirpath, &FileData);
214 if (hSearch == INVALID_HANDLE_VALUE) {
215 delete dirpath;
216 return false;
217 }
218
219 text_t filename = FileData.cFileName;
220 if (filename != "." && filename != ".." && filename != "CVS")
221 filelist.push_back (filename);
222
223 while (FindNextFile(hSearch, &FileData)) {
224 filename = FileData.cFileName;
225 if (filename == "." || filename == ".." || filename == "CVS")
226 continue;
227 filelist.push_back (filename);
228 }
229
230 FindClose(hSearch);
231 // freeing this memory can cause a runtime error on some (particularly
232 // debug) versions of VC++
233 delete dirpath;
234
235 return true;
236}
237
238#else
239
240#include <dirent.h>
241
242bool directory_exists (const text_t &dirname) {
243
244 char *tmp = dirname.getcstr();
245 DIR *dirin = opendir (tmp);
246 delete tmp;
247
248 if (dirin == NULL) return false;
249 closedir (dirin);
250 return true;
251}
252
253bool read_dir (const text_t &dirname, text_tset &filelist) {
254
255 char *tmp = dirname.getcstr();
256 DIR *dirin = opendir (tmp);
257 delete tmp;
258
259 if (dirin == NULL) return false;
260
261 dirent *dirp;
262
263 text_t filename;
264 while ((dirp = readdir (dirin)) != NULL) {
265 filename = dirp->d_name;
266 if (filename == "." || filename == ".." || filename == "CVS")
267 continue;
268 filelist.insert (filename);
269 }
270 closedir (dirin);
271 return true;
272}
273
274bool read_dir (const text_t &dirname, text_tarray &filelist) {
275
276 char *tmp = dirname.getcstr();
277 DIR *dirin = opendir (tmp);
278 delete tmp;
279
280 if (dirin == NULL) return false;
281
282 dirent *dirp;
283
284 text_t filename;
285 while ((dirp = readdir (dirin)) != NULL) {
286 filename = dirp->d_name;
287 if (filename == "." || filename == ".." || filename == "CVS")
288 continue;
289 filelist.push_back (filename);
290 }
291 closedir (dirin);
292 return true;
293}
294
295#endif
296
297// returns true if things look like they happened ok
298bool file_copy (const text_t &fromfile, const text_t &tofile) {
299
300 char *fromfilec = fromfile.getcstr();
301 char *tofilec = tofile.getcstr();
302 bool fail = false;
303
304#ifdef __WIN32__
305 if (CopyFile (fromfilec, tofilec, FALSE) == 0) fail = true;
306
307#else
308
309 // I'm sure there's a better way to do this - for now I don't have
310 // time to find it though
311 ifstream from (fromfilec);
312 if (!from) {
313 fail = true;
314 } else {
315 ofstream to (tofilec);
316 if (!to) {
317 fail = true;
318 from.close();
319 } else {
320 char c;
321 from.get(c);
322 while (!from.eof ()) {
323 to.put(c);
324 from.get(c);
325 }
326 from.close();
327 to.close();
328 }
329 }
330
331#endif
332
333 delete fromfilec;
334 delete tofilec;
335 if (fail) return false;
336 return true;
337}
338
339// This is a fairly quick and nasty attempt at doing a "tail" on a file
340// (i.e. returning the last numlines lines of filename). It has one
341// important limitation in that it expects lines to be linelength
342// characters long on average. This of course makes it possible that it
343// won't return numlines lines if there are some lines that are longer than
344// linelength. It also makes it fairly inefficient as it always reads in
345// numlines*linelength characters when it most often doesn't need them all.
346// For current needs it's fine though.
347// -- Pass a linelength of 0 to use the default linelength (256 chars).
348// -- The maximum value of linelength is MAXLINELENGTH
349text_t file_tail (const text_t &filename, int numlines, int linelength) {
350
351#define MAXLINELENGTH 2048
352
353 if (numlines < 1) numlines = 1;
354 if (linelength < 1) linelength = 256;
355 if (linelength > MAXLINELENGTH) linelength = MAXLINELENGTH;
356
357 streampos numchars = linelength*numlines;
358
359 text_tarray lines;
360 text_t ret;
361
362 char *filenamec = filename.getcstr();
363 char linec[MAXLINELENGTH];
364 ifstream file_in (filenamec);
365 delete filenamec;
366 if (file_in) {
367 file_in.seekg (0, ios::end);
368 streampos file_length = file_in.tellg();
369 if (file_length < numchars) numchars = file_length;
370 file_in.seekg (-numchars, ios::end);
371
372 while (!file_in.eof()) {
373 file_in.getline (linec, linelength);
374 ret.setcstr(linec);
375 text_t::const_iterator here = ret.begin();
376 text_t::const_iterator end = ret.end();
377 // make sure line has content
378 while (here != end) {
379 if (*here != '\n' && *here != ' ') {
380 lines.push_back (ret);
381 break;
382 }
383 here ++;
384 }
385 }
386 file_in.close();
387 }
388
389 ret.clear();
390 int numlinesgot = lines.size();
391 int sindex = 0;
392 if (numlinesgot > numlines) sindex = numlinesgot - numlines;
393 for (int i = sindex; i < numlinesgot; i++) {
394 ret += lines[i] + "\n";
395 }
396
397 return ret;
398}
399
400#ifdef __WIN32__
401
402#include <direct.h>
403// returns true if directory was created successfully
404bool mk_dir (const text_t &dirname) {
405 char *dirnamec = dirname.getcstr();
406 int rv = _mkdir (dirnamec);
407 delete dirnamec;
408 if (rv == 0) return true;
409 return false;
410}
411
412#else
413
414#include <sys/stat.h>
415#include <sys/types.h>
416#include <fcntl.h>
417#include <unistd.h>
418// returns true if directory was created successfully
419bool mk_dir (const text_t &dirname) {
420 mode_t mode = 0777;
421 char *dirnamec = dirname.getcstr();
422 int rv = mkdir (dirnamec, mode);
423 delete dirnamec;
424 if (rv == 0) return true;
425 return false;
426}
427
428#endif
429
430// read in file from filename and load into content
431bool read_file (const text_t &filename, text_t &content) {
432
433 content.clear();
434
435 char *filenamec = filename.getcstr();
436#ifdef GSDL_USE_IOS_H
437 ifstream file_in (filenamec, ios::in | ios::nocreate);
438#else
439 ifstream file_in (filenamec, ios::in);
440#endif
441 delete filenamec;
442
443 if (file_in) {
444 char c;
445 file_in.get(c);
446 while (!file_in.eof ()) {
447 content.push_back(c);
448 file_in.get(c);
449 }
450 file_in.close();
451 } else {
452 return false;
453 }
454 return true;
455}
Note: See TracBrowser for help on using the repository browser.