source: main/tags/2.27/gsdl/lib/fileutil.cpp@ 35514

Last change on this file since 35514 was 1648, checked in by sjboddie, 24 years ago

Added some comments about weird windows behavioural patterns

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 9.8 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 // freeing this memory can cause a runtime error on some (particularly
163 // debug) versions of VC++
164 delete dirpath;
165
166 if (hSearch == INVALID_HANDLE_VALUE) {
167 return false;
168 }
169 return true;
170}
171
172bool read_dir (const text_t &dirname, text_tarray &filelist) {
173
174 WIN32_FIND_DATA FileData;
175 HANDLE hSearch;
176 char *dirpath = dirname.getcstr();
177 strcat (dirpath, "\\*");
178
179 hSearch = FindFirstFile(dirpath, &FileData);
180 // freeing this memory can cause a runtime error on some (particularly
181 // debug) versions of VC++
182 delete dirpath;
183
184 if (hSearch == INVALID_HANDLE_VALUE) {
185 return false;
186 }
187
188 text_t filename = FileData.cFileName;
189 if (filename != "." && filename != ".." && filename != "CVS")
190 filelist.push_back (filename);
191
192 while (FindNextFile(hSearch, &FileData)) {
193 filename = FileData.cFileName;
194 if (filename == "." || filename == ".." || filename == "CVS")
195 continue;
196 filelist.push_back (filename);
197 }
198
199 FindClose(hSearch);
200
201 return true;
202}
203
204#else
205
206#include <dirent.h>
207
208bool directory_exists (const text_t &dirname) {
209
210 char *tmp = dirname.getcstr();
211 DIR *dirin = opendir (tmp);
212 delete tmp;
213
214 if (dirin == NULL) return false;
215 closedir (dirin);
216 return true;
217}
218
219bool read_dir (const text_t &dirname, text_tarray &filelist) {
220
221 filelist.erase (filelist.begin(), filelist.end());
222
223 char *tmp = dirname.getcstr();
224 DIR *dirin = opendir (tmp);
225 delete tmp;
226
227 if (dirin == NULL) return false;
228
229 dirent *dirp;
230
231 text_t filename;
232 while ((dirp = readdir (dirin)) != NULL) {
233 filename = dirp->d_name;
234 if (filename == "." || filename == ".." || filename == "CVS")
235 continue;
236 filelist.push_back (filename);
237 }
238 closedir (dirin);
239 return true;
240}
241
242#endif
243
244// returns true if things look like they happened ok
245bool file_copy (const text_t &fromfile, const text_t &tofile) {
246
247 char *fromfilec = fromfile.getcstr();
248 char *tofilec = tofile.getcstr();
249 bool fail = false;
250
251#ifdef __WIN32__
252 if (CopyFile (fromfilec, tofilec, FALSE) == 0) fail = true;
253
254#else
255
256 // I'm sure there's a better way to do this - for now I don't have
257 // time to find it though
258 ifstream from (fromfilec);
259 if (!from) {
260 fail = true;
261 } else {
262 ofstream to (tofilec);
263 if (!to) {
264 fail = true;
265 from.close();
266 } else {
267 char c;
268 from.get(c);
269 while (!from.eof ()) {
270 to.put(c);
271 from.get(c);
272 }
273 from.close();
274 to.close();
275 }
276 }
277
278#endif
279
280 delete fromfilec;
281 delete tofilec;
282 if (fail) return false;
283 return true;
284}
285
286
287text_t file_tail (const text_t &filename, int numlines) {
288 if (numlines < 1) numlines = 1;
289 int numchars = 256*numlines;
290
291 text_tarray lines;
292 text_t ret;
293
294 char *filenamec = filename.getcstr();
295 char linec[256];
296 ifstream file_in (filenamec);
297 delete filenamec;
298 if (file_in) {
299
300 // this should be here to keep things reasonably fast
301 // when there's a long file to tail but I can't work out
302 // how to tell when it's rewound past the beginning of the file
303 // (which causes some problems)
304
305 // file_in.seekg (-numchars, ios::end);
306
307 while (!file_in.eof()) {
308 file_in.getline (linec, 256);
309 ret.setcstr(linec);
310 text_t::const_iterator here = ret.begin();
311 text_t::const_iterator end = ret.end();
312 // make sure line has content
313 while (here != end) {
314 if (*here != '\n' && *here != ' ') {
315 lines.push_back (ret);
316 break;
317 }
318 here ++;
319 }
320 }
321 file_in.close();
322 }
323
324 ret.clear();
325 int numlinesgot = lines.size();
326 int sindex = 0;
327 if (numlinesgot > numlines) sindex = numlinesgot - numlines;
328 for (int i = sindex; i < numlinesgot; i++) {
329 ret += lines[i] + "\n";
330 }
331
332 return ret;
333}
334
335// returns the last numlines lines (or last numlines*256
336// characters) of file
337/*
338text_t file_tail (const text_t &filename) {
339
340
341 text_t return_str, tmpstr;
342 char *filenamec = filename.getcstr();
343 char linec[256];
344
345 ifstream file_in (filenamec);
346 delete filenamec;
347 if (file_in) {
348 file_in.seekg (-256, ios::end);
349 file_in.getline (linec, 256, EOF);
350 file_in.close();
351
352 tmpstr.setcstr (linec);
353 text_t::const_iterator here = tmpstr.begin();
354 text_t::const_iterator end = tmpstr.end();
355 while (here != end) {
356 // handle trailing carriage returns
357 while (*here == '\n') {
358 here++;
359 if (here == end) return return_str;
360 else if (*here != '\n') return_str.clear();
361 }
362 if (*here == '\\') return_str.push_back ('\\');
363 return_str.push_back (*here);
364 here ++;
365 }
366 }
367 return return_str;
368}
369*/
370#ifdef __WIN32__
371
372#include <direct.h>
373// returns true if directory was created successfully
374bool mk_dir (const text_t &dirname) {
375 char *dirnamec = dirname.getcstr();
376 int rv = _mkdir (dirnamec);
377 delete dirnamec;
378 if (rv == 0) return true;
379 return false;
380}
381
382#else
383
384#include <sys/stat.h>
385#include <sys/types.h>
386#include <fcntl.h>
387#include <unistd.h>
388// returns true if directory was created successfully
389bool mk_dir (const text_t &dirname) {
390 mode_t mode = 0777;
391 char *dirnamec = dirname.getcstr();
392 int rv = mkdir (dirnamec, mode);
393 delete dirnamec;
394 if (rv == 0) return true;
395 return false;
396}
397
398#endif
399
400// read in file from filename and load into content
401bool read_file (const text_t &filename, text_t &content) {
402
403 content.clear();
404
405 char *filenamec = filename.getcstr();
406#ifdef GSDL_USE_IOS_H
407 ifstream file_in (filenamec, ios::in | ios::nocreate);
408#else
409 ifstream file_in (filenamec, ios::in);
410#endif
411 delete filenamec;
412
413 if (file_in) {
414 char c;
415 file_in.get(c);
416 while (!file_in.eof ()) {
417 content.push_back(c);
418 file_in.get(c);
419 }
420 file_in.close();
421 } else {
422 return false;
423 }
424 return true;
425}
Note: See TracBrowser for help on using the repository browser.