Added File manipulation methods. Added Time conversion methods. Thread last error string can now be obtained from the system.
git-svn-id: http://yate.null.ro/svn/yate/trunk@2416 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
4e51840e9e
commit
31350b4fbe
|
@ -52,6 +52,8 @@
|
|||
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <utime.h>
|
||||
#endif
|
||||
|
||||
#ifndef SHUT_RD
|
||||
|
@ -73,6 +75,36 @@ using namespace TelEngine;
|
|||
|
||||
static Mutex s_mutex;
|
||||
|
||||
|
||||
#ifdef _WINDOWS
|
||||
|
||||
// The number of seconds from January 1, 1601 (Windows FILETIME)
|
||||
// to EPOCH January 1, 1970
|
||||
#define FILETIME_EPOCH_SEC 11644473600
|
||||
|
||||
// Convert from FILETIME (100 nsec units since January 1, 1601)
|
||||
// to time_t (seconds since January 1, 1970)
|
||||
static inline unsigned int ftToEpoch(FILETIME& ft)
|
||||
{
|
||||
// FILETIME in seconds
|
||||
u_int64_t rval = ((ULARGE_INTEGER*)&ft)->QuadPart / 10000000;
|
||||
// EPOCH time in seconds
|
||||
rval -= FILETIME_EPOCH_SEC;
|
||||
return (unsigned int)rval;
|
||||
}
|
||||
|
||||
// Convert from time_t (seconds since January 1, 1970)
|
||||
// to FILETIME (100 nsec units since January 1, 1601)
|
||||
static void epochToFt(unsigned int secEpoch, FILETIME& ft)
|
||||
{
|
||||
u_int64_t time = (secEpoch + FILETIME_EPOCH_SEC) * 10000000;
|
||||
ft.dwLowDateTime = (DWORD)time;
|
||||
ft.dwHighDateTime = (DWORD)(time >> 32);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
SocketAddr::SocketAddr(const struct sockaddr* addr, socklen_t len)
|
||||
: m_address(0), m_length(0)
|
||||
{
|
||||
|
@ -536,8 +568,14 @@ bool File::openPath(const char* name, bool canWrite, bool canRead,
|
|||
copyError();
|
||||
return false;
|
||||
}
|
||||
if (append)
|
||||
SetFilePointer(h,0,NULL,FILE_END);
|
||||
// Move file pointer if append. Result might be the same as the error code
|
||||
if (append &&
|
||||
::SetFilePointer(h,0,NULL,FILE_END) == INVALID_SET_FILE_POINTER &&
|
||||
::GetLastError() != NO_ERROR) {
|
||||
copyError();
|
||||
::CloseHandle(h);
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
int flags = 0;
|
||||
if (canWrite)
|
||||
|
@ -561,26 +599,55 @@ bool File::openPath(const char* name, bool canWrite, bool canRead,
|
|||
return true;
|
||||
}
|
||||
|
||||
unsigned int File::length()
|
||||
int64_t File::length()
|
||||
{
|
||||
if (!valid())
|
||||
return 0;
|
||||
#ifdef _WINDOWS
|
||||
DWORD sz = GetFileSize(m_handle,NULL);
|
||||
if (sz == (DWORD)-1) {
|
||||
LARGE_INTEGER li;
|
||||
li.LowPart = ::GetFileSize(m_handle,(LPDWORD)(&li.HighPart));
|
||||
if (li.LowPart == INVALID_FILE_SIZE && ::GetLastError() != NO_ERROR) {
|
||||
copyError();
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
return sz;
|
||||
return li.QuadPart;
|
||||
#else
|
||||
off_t pos = ::lseek(m_handle,0,SEEK_CUR);
|
||||
if (pos == (off_t)-1) {
|
||||
int64_t pos = seek(SeekCurrent);
|
||||
if (pos < 0) {
|
||||
copyError();
|
||||
return 0;
|
||||
}
|
||||
off_t len = ::lseek(m_handle,0,SEEK_END);
|
||||
::lseek(m_handle,pos,SEEK_SET);
|
||||
return (len == (off_t)-1) ? 0 : len;
|
||||
int64_t len = seek(SeekEnd);
|
||||
seek(SeekBegin,pos);
|
||||
return len;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set the file read/write pointer
|
||||
int64_t File::seek(SeekPos pos, int64_t offset)
|
||||
{
|
||||
if (!valid())
|
||||
return -1;
|
||||
#ifdef _WINDOWS
|
||||
int whence = (pos == SeekBegin) ? FILE_BEGIN : ((pos == SeekEnd) ? FILE_END : FILE_CURRENT);
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = offset;
|
||||
li.LowPart = ::SetFilePointer(m_handle,li.LowPart,&li.HighPart,whence);
|
||||
// Check low 32bit value and the last error
|
||||
// It might have the same as the error code
|
||||
if (li.LowPart == INVALID_SET_FILE_POINTER && ::GetLastError() != NO_ERROR) {
|
||||
copyError();
|
||||
return -1;
|
||||
}
|
||||
return li.QuadPart;
|
||||
#else
|
||||
int whence = (pos == SeekBegin) ? SEEK_SET : ((pos == SeekEnd) ? SEEK_END : SEEK_CUR);
|
||||
off_t p = ::lseek(m_handle,(off_t)offset,whence);
|
||||
if (p == (off_t)-1) {
|
||||
copyError();
|
||||
return -1;
|
||||
}
|
||||
return (int64_t)p;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -652,11 +719,212 @@ bool File::createPipe(File& reader, File& writer)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool File::remove(const char* name)
|
||||
// Retrive the file's modification time (the file must be already opened)
|
||||
bool File::getFileTime(unsigned int& secEpoch)
|
||||
{
|
||||
if (null(name))
|
||||
#ifdef _WINDOWS
|
||||
FILETIME ftWrite;
|
||||
if (::GetFileTime(handle(),NULL,NULL,&ftWrite)) {
|
||||
clearError();
|
||||
secEpoch = ftToEpoch(ftWrite);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
struct stat st;
|
||||
if (0 == ::fstat(handle(),&st)) {
|
||||
clearError();
|
||||
secEpoch = st.st_mtime;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
copyError();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Build the MD5 hex digest of an opened file.
|
||||
bool File::md5(String& buffer)
|
||||
{
|
||||
if (-1 == seek())
|
||||
return false;
|
||||
return !::unlink(name);
|
||||
MD5 md5;
|
||||
unsigned char buf[65536];
|
||||
bool ok = false;
|
||||
unsigned int retry = 3;
|
||||
while (retry) {
|
||||
int n = readData(buf,sizeof(buf));
|
||||
if (n < 0) {
|
||||
if (canRetry())
|
||||
retry--;
|
||||
else
|
||||
retry = 0;
|
||||
continue;
|
||||
}
|
||||
if (n == 0) {
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
DataBlock tmp(buf,n,false);
|
||||
md5 << tmp;
|
||||
tmp.clear(false);
|
||||
}
|
||||
if (ok)
|
||||
buffer = md5.hexDigest();
|
||||
else
|
||||
buffer = "";
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
// Set last error and return false
|
||||
static inline bool getLastError(int* error)
|
||||
{
|
||||
if (error)
|
||||
*error = Thread::lastError();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if a file name is non null
|
||||
// Set error and return false if it is
|
||||
static inline bool fileNameOk(const char* name, int* error)
|
||||
{
|
||||
if (!null(name))
|
||||
return true;
|
||||
if (error)
|
||||
#ifdef _WINDOWS
|
||||
*error = ERROR_INVALID_PARAMETER;
|
||||
#else
|
||||
*error = EINVAL;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set a file's modification time
|
||||
bool File::setFileTime(const char* name, unsigned int secEpoch, int* error)
|
||||
{
|
||||
if (!fileNameOk(name,error))
|
||||
return false;
|
||||
#ifdef _WINDOWS
|
||||
File f;
|
||||
if (f.openPath(name,true)) {
|
||||
FILETIME ftWrite;
|
||||
epochToFt(secEpoch,ftWrite);
|
||||
bool ok = (0 != ::SetFileTime(f.handle(),NULL,NULL,&ftWrite));
|
||||
if (!ok && error)
|
||||
*error = ::GetLastError();
|
||||
f.terminate();
|
||||
return ok;
|
||||
}
|
||||
#else
|
||||
struct stat st;
|
||||
if (0 == ::stat(name,&st)) {
|
||||
struct utimbuf tb;
|
||||
tb.actime = st.st_atime;
|
||||
tb.modtime = secEpoch;
|
||||
if (0 == ::utime(name,&tb))
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return getLastError(error);
|
||||
}
|
||||
|
||||
// Retrieve a file's modification time
|
||||
bool File::getFileTime(const char* name, unsigned int& secEpoch, int* error)
|
||||
{
|
||||
if (!fileNameOk(name,error))
|
||||
return false;
|
||||
#ifdef _WINDOWS
|
||||
WIN32_FILE_ATTRIBUTE_DATA fa;
|
||||
if (::GetFileAttributesExA(name,GetFileExInfoStandard,&fa)) {
|
||||
secEpoch = ftToEpoch(fa.ftLastWriteTime);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
struct stat st;
|
||||
if (0 == ::stat(name,&st)) {
|
||||
secEpoch = st.st_mtime;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return getLastError(error);
|
||||
}
|
||||
|
||||
// Check if a file exists
|
||||
bool File::exists(const char* name, int* error)
|
||||
{
|
||||
if (!fileNameOk(name,error))
|
||||
return false;
|
||||
#ifdef _WINDOWS
|
||||
WIN32_FIND_DATA d;
|
||||
HANDLE h = ::FindFirstFile(name,&d);
|
||||
if (h != invalidHandle()) {
|
||||
::FindClose(h);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
if (0 == ::access(name,F_OK))
|
||||
return true;
|
||||
#endif
|
||||
return getLastError(error);
|
||||
}
|
||||
|
||||
// Rename (move) a file (or directory) entry from the filesystem
|
||||
bool File::rename(const char* oldFile, const char* newFile, int* error)
|
||||
{
|
||||
if (!(fileNameOk(oldFile,error) && fileNameOk(newFile,error)))
|
||||
return false;
|
||||
#ifdef _WINDOWS
|
||||
DWORD flags = MOVEFILE_COPY_ALLOWED | // Allow moving file on another volume
|
||||
MOVEFILE_REPLACE_EXISTING | // Replace existing
|
||||
MOVEFILE_WRITE_THROUGH; // Don't return until copy/delete is performed
|
||||
if (::MoveFileExA(oldFile,newFile,flags))
|
||||
return true;
|
||||
#else
|
||||
if (0 == ::rename(oldFile,newFile))
|
||||
return true;
|
||||
#endif
|
||||
return getLastError(error);
|
||||
}
|
||||
|
||||
bool File::remove(const char* name, int* error)
|
||||
{
|
||||
if (!fileNameOk(name,error))
|
||||
return false;
|
||||
#ifdef _WINDOWS
|
||||
if (::DeleteFileA(name))
|
||||
return true;
|
||||
#else
|
||||
if (0 == ::unlink(name))
|
||||
return true;
|
||||
#endif
|
||||
return getLastError(error);
|
||||
}
|
||||
|
||||
// Build the MD5 hex digest of a file.
|
||||
bool File::md5(const char* name, String& buffer, int* error)
|
||||
{
|
||||
File f;
|
||||
bool ok = false;
|
||||
if (f.openPath(name,false,true) && f.md5(buffer))
|
||||
ok = true;
|
||||
else if (error)
|
||||
*error = f.error();
|
||||
f.terminate();
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Create a folder (directory)
|
||||
bool File::mkDir(const char* path, int* error)
|
||||
{
|
||||
if (!fileNameOk(path,error))
|
||||
return false;
|
||||
#ifdef _WINDOWS
|
||||
if (::CreateDirectoryA(path,NULL))
|
||||
return true;
|
||||
#else
|
||||
if (0 == ::mkdir(path,(mode_t)-1))
|
||||
return true;
|
||||
#endif
|
||||
return getLastError(error);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -520,6 +520,83 @@ void Time::toTimeval(struct timeval* tv, u_int64_t usec)
|
|||
}
|
||||
}
|
||||
|
||||
// Build EPOCH time from date/time components
|
||||
unsigned int Time::toEpoch(int year, unsigned int month, unsigned int day,
|
||||
unsigned int hour, unsigned int minute, unsigned int sec, int offset)
|
||||
{
|
||||
Debug(DebugAll,"Time::toEpoch(%d,%u,%u,%u,%u,%u,%d)",
|
||||
year,month,day,hour,minute,sec,offset);
|
||||
if (year < 1970)
|
||||
return (unsigned int)-1;
|
||||
if (month < 1 || month > 12 || !day)
|
||||
return (unsigned int)-1;
|
||||
if (hour == 24 && (minute || sec))
|
||||
return (unsigned int)-1;
|
||||
else if (hour > 23 || minute > 59 || sec > 59)
|
||||
return (unsigned int)-1;
|
||||
// Check if month and day are correct in the given year
|
||||
month--;
|
||||
unsigned int m[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||
if (isLeap(year))
|
||||
m[1] = 29;
|
||||
if (day > m[month])
|
||||
return (unsigned int)-1;
|
||||
// Count the number of days since EPOCH
|
||||
int64_t days = (year - 1970) * 365;
|
||||
// Add a day for each leap year from 1970 to 'year' (not including)
|
||||
for (int y = 1970; y < year; y += 4)
|
||||
if (isLeap(y))
|
||||
days++;
|
||||
// Add days ellapsed in given year
|
||||
for (unsigned int i = 0; i < month; i++)
|
||||
days += m[i];
|
||||
days += day - 1;
|
||||
int64_t ret = (days * 24 + hour) * 3600 + minute * 60 + sec + offset;
|
||||
|
||||
// Check for incorrect time or overflow
|
||||
if (ret < 0 || ret > (unsigned int)-1)
|
||||
return (unsigned int)-1;
|
||||
return (unsigned int)ret;
|
||||
}
|
||||
|
||||
// Split a given EPOCH time into its date/time components
|
||||
bool Time::toDateTime(unsigned int epochTimeSec, int& year, unsigned int& month,
|
||||
unsigned int& day, unsigned int& hour, unsigned int& minute, unsigned int& sec)
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
FILETIME ft;
|
||||
SYSTEMTIME st;
|
||||
// 11644473600: the number of seconds from 1601, January 1st (FILETIME)
|
||||
// to EPOCH (1970, January 1st)
|
||||
// Remember: FILETIME keeps the number of 100 nsec units
|
||||
u_int64_t time = (11644473600 + epochTimeSec) * 10000000;
|
||||
ft.dwLowDateTime = (DWORD)time;
|
||||
ft.dwHighDateTime = (DWORD)(time >> 32);
|
||||
if (!FileTimeToSystemTime(&ft,&st))
|
||||
return false;
|
||||
year = st.wYear;
|
||||
month = st.wMonth;
|
||||
day = st.wDay;
|
||||
hour = st.wHour;
|
||||
minute = st.wMinute;
|
||||
sec = st.wSecond;
|
||||
#else
|
||||
struct tm t;
|
||||
time_t time = (time_t)epochTimeSec;
|
||||
if (!gmtime_r(&time,&t))
|
||||
return false;
|
||||
year = 1900 + t.tm_year;
|
||||
month = t.tm_mon + 1;
|
||||
day = t.tm_mday;
|
||||
hour = t.tm_hour;
|
||||
minute = t.tm_min;
|
||||
sec = t.tm_sec;
|
||||
#endif
|
||||
Debug(DebugAll,"Time::toDateTime(%u,%d,%u,%u,%u,%u,%u)",
|
||||
epochTimeSec,year,month,day,hour,minute,sec);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GenObject::alive() const
|
||||
{
|
||||
|
|
|
@ -640,4 +640,36 @@ void Thread::preExec()
|
|||
#endif
|
||||
}
|
||||
|
||||
// Get the last thread error
|
||||
int Thread::lastError()
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
return ::GetLastError();
|
||||
#else
|
||||
return errno;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Get an error string from system.
|
||||
bool Thread::errorString(String& buffer, int code)
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
LPTSTR buf = 0;
|
||||
DWORD res = FormatMessageA(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,code,0,(LPTSTR)&buf,0,0);
|
||||
if (buf) {
|
||||
if (res > 0)
|
||||
buffer.assign(buf,res);
|
||||
::LocalFree(buf);
|
||||
}
|
||||
#else
|
||||
buffer = ::strerror(code);
|
||||
#endif
|
||||
if (buffer)
|
||||
return true;
|
||||
buffer << "Unknown error (code=" << code << ")";
|
||||
return false;
|
||||
}
|
||||
|
||||
/* vi: set ts=8 sw=4 sts=4 noet: */
|
||||
|
|
163
yateclass.h
163
yateclass.h
|
@ -2549,6 +2549,44 @@ public:
|
|||
*/
|
||||
static u_int32_t secNow();
|
||||
|
||||
/**
|
||||
* Build EPOCH time from date/time components
|
||||
* @param year The year component of the date. Must be greater then 1969
|
||||
* @param month The month component of the date (1 to 12)
|
||||
* @param day The day component of the date (1 to 31)
|
||||
* @param hour The hour component of the time (0 to 23). The hour can be 24
|
||||
* if minute and sec are 0
|
||||
* @param minute The minute component of the time (0 to 59)
|
||||
* @param sec The seconds component of the time (0 to 59)
|
||||
* @param offset Optional number of seconds to be added/substracted
|
||||
* to/from result. It can't exceed the number of seconds in a day
|
||||
* @return EPOCH time in seconds, -1 on failure
|
||||
*/
|
||||
static unsigned int toEpoch(int year, unsigned int month, unsigned int day,
|
||||
unsigned int hour, unsigned int minute, unsigned int sec, int offset = 0);
|
||||
|
||||
/**
|
||||
* Split a given EPOCH time into its date/time components
|
||||
* @param epochTimeSec EPOCH time in seconds
|
||||
* @param year The year component of the date
|
||||
* @param month The month component of the date (1 to 12)
|
||||
* @param day The day component of the date (1 to 31)
|
||||
* @param hour The hour component of the time (0 to 23)
|
||||
* @param minute The minute component of the time (0 to 59)
|
||||
* @param sec The seconds component of the time (0 to 59)
|
||||
* @return True on succes, false if conversion failed
|
||||
*/
|
||||
static bool toDateTime(unsigned int epochTimeSec, int& year, unsigned int& month,
|
||||
unsigned int& day, unsigned int& hour, unsigned int& minute, unsigned int& sec);
|
||||
|
||||
/**
|
||||
* Check if an year is a leap one
|
||||
* @param year The year to check
|
||||
* @return True if the given year is a leap one
|
||||
*/
|
||||
static inline bool isLeap(unsigned int year)
|
||||
{ return (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)); }
|
||||
|
||||
private:
|
||||
u_int64_t m_time;
|
||||
};
|
||||
|
@ -3771,6 +3809,34 @@ public:
|
|||
*/
|
||||
static void preExec();
|
||||
|
||||
/**
|
||||
* Get the last thread error
|
||||
* @return The value returned by GetLastError() (on Windows) or
|
||||
* the value of C library 'errno' variable otherwise
|
||||
*/
|
||||
static int lastError();
|
||||
|
||||
/**
|
||||
* Get the last thread error's string from system.
|
||||
* @param buffer The destination string
|
||||
* @return True if an error string was retrieved. If false is returned, the buffer
|
||||
* is filled with a generic string indicating an unknown error and its code
|
||||
*/
|
||||
static inline bool errorString(String& buffer)
|
||||
{ return errorString(buffer,lastError()); }
|
||||
|
||||
/**
|
||||
* Get an error string from system.
|
||||
* On Windows the code parameter must be a code returned by GetLastError().
|
||||
* Otherwise, the error code should be a valid value for the C library 'errno'
|
||||
* variable
|
||||
* @param buffer The destination string
|
||||
* @param code The error code
|
||||
* @return True if an error string was retrieved. If false is returned, the buffer
|
||||
* is filled with a generic string indicating an unknown error and its code
|
||||
*/
|
||||
static bool errorString(String& buffer, int code);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Creates and starts a new thread
|
||||
|
@ -4160,6 +4226,15 @@ protected:
|
|||
class YATE_API File : public Stream
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Enumerate seek start position
|
||||
*/
|
||||
enum SeekPos {
|
||||
SeekBegin, // Seek from file begine
|
||||
SeekEnd, // Seek from file end
|
||||
SeekCurrent // Seek from current position
|
||||
};
|
||||
|
||||
/**
|
||||
* Default constructor, creates a closed file
|
||||
*/
|
||||
|
@ -4243,7 +4318,23 @@ public:
|
|||
* Find the length of the file if it has one
|
||||
* @return Length of the file or zero if length is not defined
|
||||
*/
|
||||
virtual unsigned int length();
|
||||
virtual int64_t length();
|
||||
|
||||
/**
|
||||
* Set the file read/write pointer
|
||||
* @param pos The seek start as enumeration
|
||||
* @param offset The number of bytes to move the pointer from starting position
|
||||
* @return The new position of the file read/write pointer. Negative on failure
|
||||
*/
|
||||
virtual int64_t seek(SeekPos pos, int64_t offset = 0);
|
||||
|
||||
/**
|
||||
* Set the file read/write pointer from begin of file
|
||||
* @param offset The position in file to move the pointer
|
||||
* @return The new position of the file read/write pointer. Negative on failure
|
||||
*/
|
||||
inline int64_t seek(int64_t offset = 0)
|
||||
{ return seek(SeekBegin,offset); }
|
||||
|
||||
/**
|
||||
* Write data to an open file
|
||||
|
@ -4261,12 +4352,80 @@ public:
|
|||
*/
|
||||
virtual int readData(void* buffer, int length);
|
||||
|
||||
/**
|
||||
* Retrive the file's modification time (the file must be already opened)
|
||||
* @param secEpoch File creation time (seconds since Epoch)
|
||||
* @return True on success
|
||||
*/
|
||||
bool getFileTime(unsigned int& secEpoch);
|
||||
|
||||
/**
|
||||
* Build the MD5 hex digest of a file. The file must be opened for read access.
|
||||
* This method will move the file pointer
|
||||
* @param buffer Destination buffer
|
||||
* @return True on success
|
||||
*/
|
||||
virtual bool md5(String& buffer);
|
||||
|
||||
/**
|
||||
* Set a file's modification time.
|
||||
* @param name Path and name of the file
|
||||
* @param secEpoch File modification time (seconds since Epoch)
|
||||
* @param error Optional pointer to error code to be filled on failure
|
||||
* @return True on success
|
||||
*/
|
||||
static bool setFileTime(const char* name, unsigned int secEpoch, int* error = 0);
|
||||
|
||||
/**
|
||||
* Retrieve a file's modification time
|
||||
* @param name Path and name of the file
|
||||
* @param secEpoch File modification time (seconds since Epoch)
|
||||
* @param error Optional pointer to error code to be filled on failure
|
||||
* @return True on success
|
||||
*/
|
||||
static bool getFileTime(const char* name, unsigned int& secEpoch, int* error = 0);
|
||||
|
||||
/**
|
||||
* Check if a file exists
|
||||
* @param name The file to check
|
||||
* @param error Optional pointer to error code to be filled on failure
|
||||
* @return True if the file exists
|
||||
*/
|
||||
static bool exists(const char* name, int* error = 0);
|
||||
|
||||
/**
|
||||
* Rename (move) a file (or directory) entry from the filesystem
|
||||
* @param oldFile Path and name of the file to rename
|
||||
* @param newFile The new path and name of the file
|
||||
* @param error Optional pointer to error code to be filled on failure
|
||||
* @return True if the file was successfully renamed (moved)
|
||||
*/
|
||||
static bool rename(const char* oldFile, const char* newFile, int* error = 0);
|
||||
|
||||
/**
|
||||
* Deletes a file entry from the filesystem
|
||||
* @param name Absolute path and name of the file to delete
|
||||
* @param error Optional pointer to error code to be filled on failure
|
||||
* @return True if the file was successfully deleted
|
||||
*/
|
||||
static bool remove(const char* name);
|
||||
static bool remove(const char* name, int* error = 0);
|
||||
|
||||
/**
|
||||
* Build the MD5 hex digest of a file.
|
||||
* @param name The file to build MD5 from
|
||||
* @param buffer Destination buffer
|
||||
* @param error Optional pointer to error code to be filled on failure
|
||||
* @return True on success
|
||||
*/
|
||||
static bool md5(const char* name, String& buffer, int* error = 0);
|
||||
|
||||
/**
|
||||
* Create a folder (directory). It only creates the last directory in the path
|
||||
* @param path The folder path
|
||||
* @param error Optional pointer to error code to be filled on failure
|
||||
* @return True on success
|
||||
*/
|
||||
static bool mkDir(const char* path, int* error = 0);
|
||||
|
||||
/**
|
||||
* Create a pair of unidirectionally pipe connected streams
|
||||
|
|
Loading…
Reference in New Issue