/********************************************************************** * * fileutil.cpp -- * Copyright (C) 1999 The New Zealand Digital Library Project * * A component of the Greenstone digital library software * from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *********************************************************************/ #include "fileutil.h" #if defined(GSDL_USE_OBJECTSPACE) # include # include #elif defined(GSDL_USE_IOS_H) # include # include #else # include # include #endif // returns the proper concatenation of the two paths text_t filename_cat (text_t path1, text_t path2) { text_t::iterator here; text_t::iterator begin; text_t::iterator end; // make sure there is just one slash, of the correct type, // at the end of path1 (unless path1 is an empty string). if (!path1.empty()) { // remove all trailing slashes here = path1.end(); --here; begin = path1.begin(); while (here != begin && (*here == '/' || *here == '\\')) { --here; } ++here; path1.erase(here,path1.end()); // add one final slash #ifdef __WIN32__ path1 += "\\"; #else path1 += "/"; #endif } // remove all slashes from the start of path2 here = path2.begin(); end = path2.end(); while (here != end && (*here == '/' || *here == '\\')) { ++here; } path2.erase (path2.begin(), here); text_t fullpath = path1 + path2; // make sure all the right slashes are used here = fullpath.begin(); end = fullpath.end(); while (here != end) { #ifdef __WIN32__ if (*here == '/') *here = '\\'; #else if (*here == '\\') *here = '/'; #endif ++here ; } return fullpath; } text_t filename_cat (text_t path1, text_t path2, text_t path3) { return filename_cat(filename_cat(path1,path2),path3); } text_t filename_cat (text_t path1, text_t path2, text_t path3, text_t path4) { return filename_cat(filename_cat(filename_cat(path1,path2),path3),path4); } text_t filename_cat (text_t path1, text_t path2, text_t path3, text_t path4, text_t path5) { return filename_cat(filename_cat(filename_cat(filename_cat(path1,path2),path3), path4),path5); } text_t filename_cat (text_t path1, text_t path2, text_t path3, text_t path4, text_t path5, text_t path6) { return filename_cat(filename_cat(path1,path2,path3,path4,path5),path6); } // returns true if filename can be opened bool file_exists (const text_t &filename) { char *cstr = filename.getcstr(); #ifdef GSDL_USE_IOS_H ifstream filestream (cstr, ios::in | ios::nocreate); #else ifstream filestream (cstr, ios::in); #endif delete []cstr; if (filestream) { // file exists filestream.close (); return true; } // file does not exist return false; } // returns true if filename can be opened bool file_writable (const text_t &filename) { char *cstr = filename.getcstr(); #ifdef GSDL_USE_IOS_H ifstream filestream (cstr, ios::out | ios::nocreate); #else ifstream filestream (cstr, ios::out); #endif delete []cstr; if (filestream) { // file exists filestream.close (); return true; } // file does not exist return false; } #if defined(__WIN32__) && !defined(__GNUC__) #include bool directory_exists (const text_t &dirname) { WIN32_FIND_DATA FileData; HANDLE hSearch; text_t dir = dirname + "\\*"; char *dirpath = dir.getcstr(); hSearch = FindFirstFile(dirpath, &FileData); if (hSearch == INVALID_HANDLE_VALUE) { delete []dirpath; return false; } FindClose (hSearch); delete []dirpath; return true; } bool read_dir (const text_t &dirname, text_tset &filelist) { WIN32_FIND_DATA FileData; HANDLE hSearch; text_t dir = dirname + "\\*"; char *dirpath = dir.getcstr(); hSearch = FindFirstFile(dirpath, &FileData); if (hSearch == INVALID_HANDLE_VALUE) { delete []dirpath; return false; } text_t filename = FileData.cFileName; if (filename != "." && filename != ".." && filename != "CVS") filelist.insert (filename); while (FindNextFile(hSearch, &FileData)) { filename = FileData.cFileName; if (filename == "." || filename == ".." || filename == "CVS") continue; filelist.insert (filename); } FindClose(hSearch); delete []dirpath; return true; } bool read_dir (const text_t &dirname, text_tarray &filelist) { WIN32_FIND_DATA FileData; HANDLE hSearch; text_t dir = dirname + "\\*"; char *dirpath = dir.getcstr(); hSearch = FindFirstFile(dirpath, &FileData); if (hSearch == INVALID_HANDLE_VALUE) { delete []dirpath; return false; } text_t filename = FileData.cFileName; if (filename != "." && filename != ".." && filename != "CVS") filelist.push_back (filename); while (FindNextFile(hSearch, &FileData)) { filename = FileData.cFileName; if (filename == "." || filename == ".." || filename == "CVS") continue; filelist.push_back (filename); } FindClose(hSearch); delete []dirpath; return true; } #else #include bool directory_exists (const text_t &dirname) { char *tmp = dirname.getcstr(); DIR *dirin = opendir (tmp); delete []tmp; if (dirin == NULL) return false; closedir (dirin); return true; } bool read_dir (const text_t &dirname, text_tset &filelist) { char *tmp = dirname.getcstr(); DIR *dirin = opendir (tmp); delete []tmp; if (dirin == NULL) return false; dirent *dirp; text_t filename; while ((dirp = readdir (dirin)) != NULL) { filename = dirp->d_name; if (filename == "." || filename == ".." || filename == "CVS") continue; filelist.insert (filename); } closedir (dirin); return true; } bool read_dir (const text_t &dirname, text_tarray &filelist) { char *tmp = dirname.getcstr(); DIR *dirin = opendir (tmp); delete []tmp; if (dirin == NULL) return false; dirent *dirp; text_t filename; while ((dirp = readdir (dirin)) != NULL) { filename = dirp->d_name; if (filename == "." || filename == ".." || filename == "CVS") continue; filelist.push_back (filename); } closedir (dirin); return true; } #endif // returns true if things look like they happened ok bool file_copy (const text_t &fromfile, const text_t &tofile) { char *fromfilec = fromfile.getcstr(); char *tofilec = tofile.getcstr(); bool fail = false; #ifdef __WIN32__ if (CopyFile (fromfilec, tofilec, FALSE) == 0) fail = true; #else ifstream from (fromfilec); if (!from) { fail = true; } else { ofstream to (tofilec); if (!to) { fail = true; from.close(); } else { from >> to.rdbuf(); from.close(); to.close(); } } #endif delete []fromfilec; delete []tofilec; if (fail) return false; return true; } // This is a fairly quick and nasty attempt at doing a "tail" on a file // (i.e. returning the last numlines lines of filename). It has one // important limitation in that it expects lines to be linelength // characters long on average. This of course makes it possible that it // won't return numlines lines if there are some lines that are longer than // linelength. It also makes it fairly inefficient as it always reads in // numlines*linelength characters when it most often doesn't need them all. // For current needs it's fine though. // -- Pass a linelength of 0 to use the default linelength (256 chars). // -- The maximum value of linelength is MAXLINELENGTH text_t file_tail (const text_t &filename, int numlines, int linelength) { #define MAXLINELENGTH 2048 if (numlines < 1) numlines = 1; if (linelength < 1) linelength = 256; if (linelength > MAXLINELENGTH) linelength = MAXLINELENGTH; streampos numchars = linelength*numlines; text_tarray lines; text_t ret; char *filenamec = filename.getcstr(); char linec[MAXLINELENGTH]; ifstream file_in (filenamec); delete []filenamec; if (file_in) { file_in.seekg (0, ios::end); streampos file_length = file_in.tellg(); if (file_length < numchars) numchars = file_length; file_in.seekg (-numchars, ios::end); while (!file_in.eof()) { file_in.getline (linec, linelength); ret.setcstr(linec); text_t::const_iterator here = ret.begin(); text_t::const_iterator end = ret.end(); // make sure line has content while (here != end) { if (*here != '\n' && *here != ' ') { lines.push_back (ret); break; } ++here; } } file_in.close(); } ret.clear(); int numlinesgot = lines.size(); int sindex = 0; if (numlinesgot > numlines) sindex = numlinesgot - numlines; for (int i = sindex; i < numlinesgot; ++i) { ret += lines[i] + "\n"; } return ret; } #ifdef __WIN32__ #include // returns true if directory was created successfully bool mk_dir (const text_t &dirname) { char *dirnamec = dirname.getcstr(); int rv = _mkdir (dirnamec); delete []dirnamec; if (rv == 0) return true; return false; } #else #include #include #include #include // returns true if directory was created successfully bool mk_dir (const text_t &dirname) { mode_t mode = 0777; char *dirnamec = dirname.getcstr(); int rv = mkdir (dirnamec, mode); delete []dirnamec; if (rv == 0) return true; return false; } #endif // read in file from filename and load into content bool read_file (const text_t &filename, text_t &content) { content.clear(); char *filenamec = filename.getcstr(); #ifdef GSDL_USE_IOS_H ifstream file_in (filenamec, ios::in | ios::nocreate); #else ifstream file_in (filenamec, ios::in); #endif delete []filenamec; if (file_in) { char c; file_in.get(c); while (!file_in.eof ()) { // Casting c to an unsigned char is vital when reading non-ASCII documents content.push_back((unsigned char) c); file_in.get(c); } file_in.close(); } else { return false; } return true; }