git-svn-id: https://svn.microneil.com/svn/CodeDweller/branches/adeniz_1@62 d34b734f-a00e-4b39-a726-e4eeb87269abadeniz_1
// Place, Suite 330, Boston, MA 02111-1307 USA | // Place, Suite 330, Boston, MA 02111-1307 USA | ||||
//============================================================================== | //============================================================================== | ||||
#include <sys/types.h> | |||||
#include <sys/stat.h> | |||||
#ifdef _WIN32 | |||||
#include <windows.h> | |||||
#else | |||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <sys/types.h> | |||||
#include <cstring> | #include <cstring> | ||||
#include <cerrno> | #include <cerrno> | ||||
#endif | |||||
#include <sys/stat.h> | |||||
#include <stdexcept> | #include <stdexcept> | ||||
#include "filesystem.hpp" | #include "filesystem.hpp" | ||||
void FileReference::refresh() { | void FileReference::refresh() { | ||||
// Load path if necessary. | |||||
if (path.empty()) { | |||||
char *realPath = realpath(name.c_str(), NULL); | |||||
if (NULL == realPath) { | |||||
// Nothing to do if the file doesn't exist. | |||||
if (ENOENT == errno) { | |||||
return; | |||||
} | |||||
// Something went wrong. | |||||
throw std::runtime_error("Error checking file \"" + name + "\": " + | |||||
getErrorText()); | |||||
} | |||||
path.assign(realPath); | |||||
free(realPath); | |||||
} | |||||
reset(); | |||||
// Load info. | // Load info. | ||||
struct stat statBuffer; | struct stat statBuffer; | ||||
int status = stat(path.c_str(), &statBuffer); | |||||
int status = stat(name.c_str(), &statBuffer); | |||||
if (-1 == status) { | if (-1 == status) { | ||||
// File no longer exists. | // File no longer exists. | ||||
if (ENOENT == errno) { | if (ENOENT == errno) { | ||||
reset(); | |||||
return; | return; | ||||
} | } | ||||
// Something went wrong. | // Something went wrong. | ||||
throw std::runtime_error("Error updating status of file \"" + | throw std::runtime_error("Error updating status of file \"" + | ||||
path + "\": " + getErrorText()); | |||||
name + "\": " + getErrorText()); | |||||
} | } | ||||
size_bytes = 0; | size_bytes = 0; | ||||
fileExists = false; | fileExists = false; | ||||
fileIsDirectory = false; | fileIsDirectory = false; | ||||
path.clear(); | |||||
} | } | ||||
time_t FileReference::ModTimestamp() const { | time_t FileReference::ModTimestamp() const { | ||||
return size_bytes; | return size_bytes; | ||||
} | } | ||||
std::string FileReference::FullPath() const { | |||||
std::string FileReference::FullPath() { | |||||
if (!path.empty()) { | |||||
return path; | |||||
} | |||||
if (!fileExists) { | |||||
return ""; | |||||
} | |||||
#ifdef _WIN32 | |||||
// Get the size of the full path name. | |||||
DWORD nTchars = GetFullPathName(name.c_str(), 0, NULL, NULL); | |||||
if (0 == nTchars) { | |||||
throw std::runtime_error("Error getting full path length for \"" + name | |||||
+ "\": " + getErrorText()); | |||||
} | |||||
size_t bufSize = nTchars * sizeof(TCHAR); | |||||
TCHAR fullPath[bufSize]; | |||||
nTchars = GetFullPathName(name.c_str(), bufSize, fullPath, NULL); | |||||
if (0 == nTchars) { | |||||
throw std::runtime_error("Error getting full path for \"" + name | |||||
+ "\": " + getErrorText()); | |||||
} | |||||
path.assign(fullPath); | |||||
#else | |||||
char *realPath = realpath(name.c_str(), NULL); | |||||
if (NULL == realPath) { | |||||
// Nothing to do if the file doesn't exist. | |||||
if (ENOENT == errno) { | |||||
reset(); | |||||
return ""; | |||||
} | |||||
// Something went wrong. | |||||
throw std::runtime_error("Error checking file \"" + name + "\": " + | |||||
getErrorText()); | |||||
} | |||||
path.assign(realPath); | |||||
free(realPath); | |||||
#endif | |||||
return path; | return path; | ||||
} | } | ||||
/** Initialize with the name of the file. | /** Initialize with the name of the file. | ||||
The constructor updates the FileReference object with the file | |||||
status except for the full path. | |||||
@param[in] fileName is the name of the file. | @param[in] fileName is the name of the file. | ||||
*/ | */ | ||||
FileReference(std::string fileName); | FileReference(std::string fileName); | ||||
/** Return timestamp. | /** Return timestamp. | ||||
@returns the epoch modification time for file when | |||||
FileReference was created or last refreshed, or zero if the | |||||
file doesn't exist. | |||||
@returns the epoch modification time of the file if the file | |||||
existed when the FileReference object was created, or the last | |||||
time refersh() was called (whichever is more recent), 0 | |||||
otherwise. | |||||
*/ | */ | ||||
time_t ModTimestamp() const; | time_t ModTimestamp() const; | ||||
/** Get the file size. | /** Get the file size. | ||||
@returns the size of file when FileReference was created or | |||||
last refreshed, or 0 if the file doesn't exist. | |||||
@returns the size of the file if the file existed when the | |||||
FileReference object was created, or the last time refersh() | |||||
was called (whichever is more recent), 0 otherwise. | |||||
*/ | */ | ||||
size_t Size() const; | size_t Size() const; | ||||
/** Get full path. | |||||
/** Get full path if the file exists. | |||||
This method access the filesystem to get the full path of the | |||||
file. | |||||
@returns a fully referenced path to the file. | |||||
@warning This method might fail under Windows in a | |||||
multi-threaded application if the current working directory of | |||||
the application is being changed by a thread while this method | |||||
is invoked. | |||||
@returns a fully referenced path to the file if the file | |||||
exists. Otherwise, "" is returned. | |||||
*/ | */ | ||||
std:: string FullPath() const; | |||||
std:: string FullPath(); | |||||
/** Refreshes the FileReference object. | |||||
/** Refreshes the FileReference object with the current data on the file | |||||
system. | |||||
This method updates the FileReference object with the current | |||||
data on the file system, except for the full path. | |||||
*/ | */ | ||||
void refresh(); | void refresh(); | ||||
/** Check if the file exists. | /** Check if the file exists. | ||||
@returns true if the file reference name exists in the file | |||||
system, false otherwise. | |||||
@returns true if the file reference name existed in the file | |||||
system when the FileReference object was created, or the last | |||||
time refersh() was called (whichever is more recent), false | |||||
otherwise. | |||||
@throws std::runtime_error if an error occurs. | @throws std::runtime_error if an error occurs. | ||||
/** Check if the file is a directory. | /** Check if the file is a directory. | ||||
@returns true if the name provided on construction resulted in | |||||
finding a directory not a file, and false otherwise or if the | |||||
file doesn't exist. | |||||
@returns true if the file reference name existed and was a | |||||
directory in the file system when the FileReference object was | |||||
created, or the last time refersh() was called (whichever is | |||||
more recent), false otherwise. | |||||
*/ | */ | ||||
bool isDirectory() const; | bool isDirectory() const; | ||||
// | // | ||||
static std::string getErrorText(); | static std::string getErrorText(); | ||||
/// Reset all members but the name and path. */ | |||||
/// Reset all members but the name. */ | |||||
void reset(); | void reset(); | ||||
/** Name provided to constructor. */ | /** Name provided to constructor. */ |