// -*-c++-*- //------------------------------------------------------------------------------ // xword - (http://xword.sourceforge.net) // Copyright 2002 Patrick Crosby //------------------------------------------------------------------------------ // FileUtil.cpp // // $Id: FileUtil.cpp,v 1.3 2002/01/23 19:43:03 pcrosby Exp $ //------------------------------------------------------------------------------ // 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., 59 Temple // Place, Suite 330, Boston, MA 02111-1307 USA //------------------------------------------------------------------------------ #include #include "FileUtil.h" #include #include #include #include #include #include #include #include #include #include "ErrorManager.h" #include "String.h" #include "Namespace.h" using namespace std; NAMESPACE_OPEN //------------------------------------------------------------------------------ bool FileUtil::GetDirectoryList(const Filename& strPath, DirectoryList& listResult) { listResult.clear(); DIR* pDir; struct dirent* pEntry; if (!(pDir = opendir(strPath.c_str()))) { std::string strError("Couldn't open directory: " + strPath); throw invalid_argument(strError); } errno = 0; pEntry = readdir(pDir); while (pEntry != NULL) { std::string strName = pEntry->d_name; if (strName != "." && strName != "..") { listResult.push_back(strName); } errno = 0; pEntry = readdir(pDir); } if (errno) { EM::I()->Error(strerror(errno)); throw(file_error(strerror(errno))); } closedir(pDir); return true; } //------------------------------------------------------------------------------ /* std::string FileUtil::GetActualPath(const std::string& strPath) { std::string strResult = strPath; if (strResult[0] == '~') { strResult.erase(0, 1); strResult.insert(0, "/"); strResult.insert(0, getenv("HOME")); } return strResult; } */ //------------------------------------------------------------------------------ void FileUtil::CreateDirectory(const Filename& strPath) { #ifdef HAVE_MKDIR mkdir(strPath.c_str(), 0x1ed); #else EM::I()->Error("you don't have mkdir...i'm not sure what to do to create a directory"); throw(runtime_error("you don't have mkdir...i'm not sure what to do to create a directory")); #endif } //------------------------------------------------------------------------------ void FileUtil::AssertDirectoryExists(const Filename& strPath) { if (!FileExists(strPath)) { CreateDirectory(strPath); } if (!FileExists(strPath)) { std::string s = "couldn't create directory: " + strPath; EM::I()->Error(s); throw(file_error(s)); } } //------------------------------------------------------------------------------ Filename FileUtil::GetAvailableFile(const Filename& strBase) { if (!FileExists(strBase)) { return strBase; } else { Filename strResult(strBase); int i = 0; do { i++; String s(i); strResult = strBase + " " + s; } while (i < 100000 && FileExists(strResult)); if (i < 100000) { return strResult; } else { throw(file_error("you've really got too many files with the same prefix...")); } } return strBase; } //------------------------------------------------------------------------------ Filename FileUtil::GetAvailableFile(const Filename& strBase, const std::string& strExt) { if (!FileExists(strBase + strExt)) { return strBase + strExt; } else { Filename strResult(strBase); int i = 0; do { i++; String s(i); strResult = strBase + " " + s + strExt; } while (i < 100000 && FileExists(strResult)); if (i < 100000) { return strResult; } else { throw(file_error("you've really got too many files with the same prefix...")); } } return strBase; } //------------------------------------------------------------------------------ bool FileUtil::FileExists(const Filename& strPath) { FILE* pFile = fopen(strPath.c_str(), "r"); bool bResult = pFile != NULL; if (bResult) { fclose(pFile); } return bResult; } //------------------------------------------------------------------------------ void FileUtil::CreateFile(const Filename& strPath) { int fd = open(strPath.c_str(), O_CREAT | O_WRONLY, 0644); if (fd < 0) { throw(file_error("couldn't create " + strPath)); } close(fd); } //------------------------------------------------------------------------------ void FileUtil::AssertFileExists(const Filename& strPath) { if (!FileExists(strPath)) { CreateFile(strPath); } if (!FileExists(strPath)) { std::string s = "couldn't create file: " + strPath; EM::I()->Error(s); throw(file_error(s)); } } //------------------------------------------------------------------------------ off_t FileUtil::GetSize(const Filename& strPath) { off_t nResult = -1; struct stat sb; if (0 == stat(strPath.c_str(), &sb)) { nResult = sb.st_size; } return nResult; } //------------------------------------------------------------------------------ bool FileUtil::Skip(FILE* pFile, long nlOffset, int nWhence) { #ifndef PIPE_BUF char buffer[4096]; #else char buffer[PIPE_BUF]; #endif int read; if (0 == fseek(pFile, nlOffset, nWhence)) return false; if (nWhence != SEEK_CUR || nlOffset < 0) { // PATRICK: figure out what this really means... EM::I()->Error("fskip problem: Mostly the return status of functions is not evaluate so it is more secure to polute ."); throw(file_error("Skip error")); } while (nlOffset > 0) { read = (unsigned long)nlOffset > sizeof(buffer) ? sizeof(buffer) : nlOffset; if ((read = fread(buffer, 1, read, pFile)) <= 0) { return false; } nlOffset -= read; } return true; } //------------------------------------------------------------------------------ void FileUtil::Delete(const Filename& strPath) { unlink(strPath.c_str()); } //------------------------------------------------------------------------------ void FileUtil::Rename(const Filename& strOldPath, const Filename& strNewPath) { rename(strOldPath.c_str(), strNewPath.c_str()); } //------------------------------------------------------------------------------ void FileUtil::Link(const Filename& strSource, const Filename& strLinkPath) { symlink(strSource.c_str(), strLinkPath.c_str()); } //------------------------------------------------------------------------------ std::string FileUtil::CleanFilename(const std::string& s) { std::string strResult(s); std::string::size_type nPos = strResult.find('/'); while (nPos != std::string::npos) { EM::I()->Trace("nPos = " + String(nPos)); strResult.replace(nPos, 1, "-"); nPos = strResult.find('/'); } return strResult; } //------------------------------------------------------------------------------ NAMESPACE_CLOSE //------------------------------------------------------------------------------