wxFileName::Get/SetTimes() finally seem to work under Windows

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14827 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2002-03-27 23:17:41 +00:00
parent 12132b3789
commit 6dbb903bb9
4 changed files with 79 additions and 55 deletions

View File

@ -140,7 +140,10 @@ following functions:
\membersection{Operations}
These methods allow to work with the file creation, access and modification
times:
times. Note that not all filesystems under all platforms implement these times
in the same way. For example, the access time under Windows has a resolution of
one day (so it is really the access date and not time). The access time may be
updated when the file is executed or not depending on the platform.
\helpref{GetModificationTime}{wxfilenamegetmodificationtime}\\
\helpref{GetTimes}{wxfilenamegettimes}\\
@ -400,9 +403,9 @@ Return the short form of the path (returns identity on non-Windows platforms)
\membersection{wxFileName::GetTimes}\label{wxfilenamegettimes}
\constfunc{bool}{GetTimes}{\param{wxDateTime* }{dtAccess}, \param{wxDateTime* }{dtMod}, \param{wxDateTime* }{dtChange}}
\constfunc{bool}{GetTimes}{\param{wxDateTime* }{dtAccess}, \param{wxDateTime* }{dtMod}, \param{wxDateTime* }{dtCreate}}
return the last access, last modification and last change times
return the last access, last modification and creation times
(any of the pointers may be NULL)
@ -584,7 +587,7 @@ full name is the file name + extension (but without the path)
\membersection{wxFileName::SetTimes}\label{wxfilenamesettimes}
\func{bool}{SetTimes}{\param{const wxDateTime* }{dtCreate}, \param{const wxDateTime* }{dtAccess}, \param{const wxDateTime* }{dtMod}}
\func{bool}{SetTimes}{\param{const wxDateTime* }{dtAccess}, \param{const wxDateTime* }{dtMod}, \param{const wxDateTime* }{dtCreate}}
set the file creation and last access/mod times
(any of the pointers may be NULL)

View File

@ -173,20 +173,20 @@ public:
// time functions
// set the file creation and last access/mod times
// set the file last access/mod and creation times
// (any of the pointers may be NULL)
bool SetTimes(const wxDateTime *dtCreate,
const wxDateTime *dtAccess,
const wxDateTime *dtMod);
bool SetTimes(const wxDateTime *dtAccess,
const wxDateTime *dtMod,
const wxDateTime *dtCreate);
// set the access and modification times to the current moment
bool Touch();
// return the last access, last modification and last change times
// return the last access, last modification and create times
// (any of the pointers may be NULL)
bool GetTimes(wxDateTime *dtAccess,
wxDateTime *dtMod,
wxDateTime *dtChange) const;
wxDateTime *dtCreate) const;
// convenience wrapper: get just the last mod time of the file
wxDateTime GetModificationTime() const

View File

@ -90,7 +90,7 @@
#undef TEST_ALL
static const bool TEST_ALL = TRUE;
#else
#define TEST_WCHAR
#define TEST_FILETIME
static const bool TEST_ALL = FALSE;
#endif
@ -982,8 +982,8 @@ static void TestFileGetTimes()
{
wxFileName fn(_T("testdata.fc"));
wxDateTime dtAccess, dtMod, dtChange;
if ( !fn.GetTimes(&dtAccess, &dtMod, &dtChange) )
wxDateTime dtAccess, dtMod, dtCreate;
if ( !fn.GetTimes(&dtAccess, &dtMod, &dtCreate) )
{
wxPrintf(_T("ERROR: GetTimes() failed.\n"));
}
@ -992,9 +992,9 @@ static void TestFileGetTimes()
static const wxChar *fmt = _T("%Y-%b-%d %H:%M:%S");
wxPrintf(_T("File times for '%s':\n"), fn.GetFullPath().c_str());
wxPrintf(_T("Access: \t%s\n"), dtAccess.Format(fmt).c_str());
wxPrintf(_T("Mod/creation:\t%s\n"), dtMod.Format(fmt).c_str());
wxPrintf(_T("Change: \t%s\n"), dtChange.Format(fmt).c_str());
wxPrintf(_T("Creation: \t%s\n"), dtCreate.Format(fmt).c_str());
wxPrintf(_T("Last read: \t%s\n"), dtAccess.Format(fmt).c_str());
wxPrintf(_T("Last write: \t%s\n"), dtMod.Format(fmt).c_str());
}
}

View File

@ -135,23 +135,31 @@
class wxFileHandle
{
public:
wxFileHandle(const wxString& filename)
enum OpenMode
{
Read,
Write
};
wxFileHandle(const wxString& filename, OpenMode mode)
{
m_hFile = ::CreateFile
(
filename, // name
GENERIC_READ, // access mask
0, // no sharing
NULL, // no secutity attr
OPEN_EXISTING, // creation disposition
0, // no flags
NULL // no template file
filename, // name
mode == Read ? GENERIC_READ // access mask
: GENERIC_WRITE,
0, // no sharing
NULL, // no secutity attr
OPEN_EXISTING, // creation disposition
0, // no flags
NULL // no template file
);
if ( m_hFile == INVALID_HANDLE_VALUE )
{
wxLogSysError(_("Failed to open '%s' for reading"),
filename.c_str());
wxLogSysError(_("Failed to open '%s' for %s"),
filename.c_str(),
mode == Read ? _("reading") : _("writing"));
}
}
@ -187,32 +195,45 @@ private:
// convert between wxDateTime and FILETIME which is a 64-bit value representing
// the number of 100-nanosecond intervals since January 1, 1601.
// the number of milliseconds between the Unix Epoch (January 1, 1970) and the
// FILETIME reference point (January 1, 1601)
static const wxLongLong FILETIME_EPOCH_OFFSET = wxLongLong(0xa97, 0x30b66800);
static void ConvertFileTimeToWx(wxDateTime *dt, const FILETIME &ft)
{
wxLongLong ll(ft.dwHighDateTime, ft.dwLowDateTime);
FILETIME ftLocal;
if ( !::FileTimeToLocalFileTime(&ft, &ftLocal) )
{
wxLogLastError(_T("FileTimeToLocalFileTime"));
}
// convert 100ns to ms
ll /= 10000;
SYSTEMTIME st;
if ( !::FileTimeToSystemTime(&ftLocal, &st) )
{
wxLogLastError(_T("FileTimeToSystemTime"));
}
// move it to our Epoch
ll -= FILETIME_EPOCH_OFFSET;
*dt = wxDateTime(ll);
dt->Set(st.wDay, wxDateTime::Month(st.wMonth - 1), st.wYear,
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
}
static void ConvertWxToFileTime(FILETIME *ft, const wxDateTime& dt)
{
// do the reverse of ConvertFileTimeToWx()
wxLongLong ll = dt.GetValue();
ll += FILETIME_EPOCH_OFFSET;
ll *= 10000;
SYSTEMTIME st;
st.wDay = dt.GetDay();
st.wMonth = dt.GetMonth() + 1;
st.wYear = dt.GetYear();
st.wHour = dt.GetHour();
st.wMinute = dt.GetMinute();
st.wSecond = dt.GetSecond();
st.wMilliseconds = dt.GetMillisecond();
ft->dwHighDateTime = ll.GetHi();
ft->dwLowDateTime = ll.GetLo();
FILETIME ftLocal;
if ( !::SystemTimeToFileTime(&st, &ftLocal) )
{
wxLogLastError(_T("SystemTimeToFileTime"));
}
if ( !::LocalFileTimeToFileTime(&ftLocal, ft) )
{
wxLogLastError(_T("LocalFileTimeToFileTime"));
}
}
#endif // __WIN32__
@ -1561,9 +1582,9 @@ void wxFileName::SplitPath(const wxString& fullpath,
// time functions
// ----------------------------------------------------------------------------
bool wxFileName::SetTimes(const wxDateTime *dtCreate,
const wxDateTime *dtAccess,
const wxDateTime *dtMod)
bool wxFileName::SetTimes(const wxDateTime *dtAccess,
const wxDateTime *dtMod,
const wxDateTime *dtCreate)
{
#if defined(__UNIX_LIKE__) || (defined(__DOS__) && defined(__WATCOMC__))
if ( !dtAccess && !dtMod )
@ -1582,7 +1603,7 @@ bool wxFileName::SetTimes(const wxDateTime *dtCreate,
return TRUE;
}
#elif defined(__WIN32__)
wxFileHandle fh(GetFullPath());
wxFileHandle fh(GetFullPath(), wxFileHandle::Write);
if ( fh.IsOk() )
{
FILETIME ftAccess, ftCreate, ftWrite;
@ -1626,13 +1647,13 @@ bool wxFileName::Touch()
#else // other platform
wxDateTime dtNow = wxDateTime::Now();
return SetTimes(NULL /* don't change create time */, &dtNow, &dtNow);
return SetTimes(&dtNow, &dtNow, NULL /* don't change create time */);
#endif // platforms
}
bool wxFileName::GetTimes(wxDateTime *dtAccess,
wxDateTime *dtMod,
wxDateTime *dtChange) const
wxDateTime *dtCreate) const
{
#if defined(__UNIX_LIKE__) || defined(__WXMAC__) || (defined(__DOS__) && defined(__WATCOMC__))
wxStructStat stBuf;
@ -1642,13 +1663,13 @@ bool wxFileName::GetTimes(wxDateTime *dtAccess,
dtAccess->Set(stBuf.st_atime);
if ( dtMod )
dtMod->Set(stBuf.st_mtime);
if ( dtChange )
dtChange->Set(stBuf.st_ctime);
if ( dtCreate )
dtCreate->Set(stBuf.st_ctime);
return TRUE;
}
#elif defined(__WIN32__)
wxFileHandle fh(GetFullPath());
wxFileHandle fh(GetFullPath(), wxFileHandle::Read);
if ( fh.IsOk() )
{
FILETIME ftAccess, ftCreate, ftWrite;
@ -1656,14 +1677,14 @@ bool wxFileName::GetTimes(wxDateTime *dtAccess,
if ( ::GetFileTime(fh,
dtMod ? &ftCreate : NULL,
dtAccess ? &ftAccess : NULL,
dtChange ? &ftWrite : NULL) )
dtCreate ? &ftWrite : NULL) )
{
if ( dtMod )
ConvertFileTimeToWx(dtMod, ftCreate);
if ( dtAccess )
ConvertFileTimeToWx(dtAccess, ftAccess);
if ( dtChange )
ConvertFileTimeToWx(dtChange, ftWrite);
if ( dtCreate )
ConvertFileTimeToWx(dtCreate, ftWrite);
return TRUE;
}