#include "wx/intl.h"
#include "wx/log.h"
#include "wx/utils.h"
+ #include "wx/crt.h"
#endif
#include "wx/filename.h"
#include "wx/tokenzr.h"
#include "wx/config.h" // for wxExpandEnvVars
#include "wx/dynlib.h"
+#include "wx/dir.h"
#if defined(__WIN32__) && defined(__MINGW32__)
#include "wx/msw/gccpriv.h"
#endif
#if defined(__WXMAC__)
- #include "wx/mac/private.h" // includes mac headers
+ #include "wx/osx/private.h" // includes mac headers
#endif
// utime() is POSIX so should normally be available on all Unices
#endif
-wxULongLong wxInvalidSize = (unsigned)-1;
+#if wxUSE_LONGLONG
+extern const wxULongLong wxInvalidSize = (unsigned)-1;
+#endif // wxUSE_LONGLONG
// ----------------------------------------------------------------------------
Write
};
- wxFileHandle(const wxString& filename, OpenMode mode)
+ wxFileHandle(const wxString& filename, OpenMode mode, int flags = 0)
{
m_hFile = ::CreateFile
(
- filename, // name
+ filename.fn_str(), // name
mode == Read ? GENERIC_READ // access mask
: GENERIC_WRITE,
FILE_SHARE_READ | // sharing mode
FILE_SHARE_WRITE, // (allow everything)
NULL, // no secutity attr
OPEN_EXISTING, // creation disposition
- 0, // no flags
+ flags, // flags
NULL // no template file
);
if ( m_hFile == INVALID_HANDLE_VALUE )
{
- wxLogSysError(_("Failed to open '%s' for %s"),
- filename.c_str(),
- mode == Read ? _("reading") : _("writing"));
+ if ( mode == Read )
+ wxLogSysError(_("Failed to open '%s' for reading"),
+ filename.c_str());
+ else
+ wxLogSysError(_("Failed to open '%s' for writing"),
+ filename.c_str());
}
}
return path;
}
+// return true if the format used is the DOS/Windows one and the string looks
+// like a UNC path
+static bool IsUNCPath(const wxString& path, wxPathFormat format)
+{
+ return format == wxPATH_DOS &&
+ path.length() >= 4 && // "\\a" can't be a UNC path
+ path[0u] == wxFILE_SEP_PATH_DOS &&
+ path[1u] == wxFILE_SEP_PATH_DOS &&
+ path[2u] != wxFILE_SEP_PATH_DOS;
+}
+
// ============================================================================
// implementation
// ============================================================================
const wxString& name,
const wxString& ext,
bool hasExt,
- wxPathFormat format )
+ wxPathFormat format)
{
- SetPath( path, format );
+ // we should ignore paths which look like UNC shares because we already
+ // have the volume here and the UNC notation (\\server\path) is only valid
+ // for paths which don't start with a volume, so prevent SetPath() from
+ // recognizing "\\foo\bar" in "c:\\foo\bar" as an UNC path
+ //
+ // note also that this is a rather ugly way to do what we want (passing
+ // some kind of flag telling to ignore UNC paths to SetPath() would be
+ // better) but this is the safest thing to do to avoid breaking backwards
+ // compatibility in 2.8
+ if ( IsUNCPath(path, format) )
+ {
+ // remove one of the 2 leading backslashes to ensure that it's not
+ // recognized as an UNC path by SetPath()
+ wxString pathNonUNC(path, 1, wxString::npos);
+ SetPath(pathNonUNC, format);
+ }
+ else // no UNC complications
+ {
+ SetPath(path, format);
+ }
m_volume = volume;
m_ext = ext;
// always recognize fullpath as directory, even if it doesn't end with a
// slash
wxString fullpath = fullpathOrig;
- if ( !wxEndsWithPathSeparator(fullpath) )
+ if ( !fullpath.empty() && !wxEndsWithPathSeparator(fullpath) )
{
fullpath += GetPathSeparator(format);
}
wxString volume, path, name, ext;
bool hasExt;
- // do some consistency checks in debug mode: the name should be really just
- // the filename and the path should be really just a path
-#ifdef __WXDEBUG__
+ // do some consistency checks: the name should be really just the filename
+ // and the path should be really just a path
wxString volDummy, pathDummy, nameDummy, extDummy;
SplitPath(fullname, &volDummy, &pathDummy, &name, &ext, &hasExt, format);
wxASSERT_MSG( nameDummy.empty() && extDummy.empty(),
_T("the path shouldn't contain file name nor extension") );
-#else // !__WXDEBUG__
- SplitPath(fullname, NULL /* no volume */, NULL /* no path */,
- &name, &ext, &hasExt, format);
- SplitPath(fullpath, &volume, &path, NULL, NULL, format);
-#endif // __WXDEBUG__/!__WXDEBUG__
-
Assign(volume, path, name, ext, hasExt, format);
}
DWORD attributes = FILE_ATTRIBUTE_TEMPORARY |
FILE_FLAG_DELETE_ON_CLOSE;
- HANDLE h = ::CreateFile(filename, access, 0, NULL,
+ HANDLE h = ::CreateFile(filename.fn_str(), access, 0, NULL,
disposition, attributes, NULL);
- return wxOpenOSFHandle(h, 0);
+ return wxOpenOSFHandle(h, wxO_BINARY);
}
#endif // wxOpenOSFHandle
return file->Open(path, _T("w+b"));
#else // wx_fdopen
int fd = wxTempOpen(path, deleteOnClose);
- if (fd != -1)
+ if (fd == -1)
return false;
file->Attach(wx_fdopen(fd, "w+b"));
return file->IsOpened();
if (dir.empty())
{
- dir = wxGetenv(_T("TMPDIR"));
- if (dir.empty())
- {
- dir = wxGetenv(_T("TMP"));
- if (dir.empty())
- {
- dir = wxGetenv(_T("TEMP"));
- }
- }
+ dir = wxFileName::GetTempDir();
}
#if defined(__WXWINCE__)
- if (dir.empty())
- {
- // FIXME. Create \temp dir?
- if (wxFileName::DirExists(wxT("\\temp")))
- dir = wxT("\\temp");
- }
path = dir + wxT("\\") + name;
int i = 1;
while (wxFileName::FileExists(path))
}
#elif defined(__WINDOWS__) && !defined(__WXMICROWIN__)
-
- if ( dir.empty() )
- {
- if ( !::GetTempPath(MAX_PATH, wxStringBuffer(dir, MAX_PATH + 1)) )
- {
- wxLogLastError(_T("GetTempPath"));
- }
-
- if ( dir.empty() )
- {
- // GetTempFileName() fails if we pass it an empty string
- dir = _T('.');
- }
- }
- else // we have a dir to create the file in
- {
- // ensure we use only the back slashes as GetTempFileName(), unlike all
- // the other APIs, is picky and doesn't accept the forward ones
- dir.Replace(_T("/"), _T("\\"));
- }
-
- if ( !::GetTempFileName(dir, name, 0, wxStringBuffer(path, MAX_PATH + 1)) )
+ if ( !::GetTempFileName(dir.fn_str(), name.fn_str(), 0,
+ wxStringBuffer(path, MAX_PATH + 1)) )
{
wxLogLastError(_T("GetTempFileName"));
}
#else // !Windows
- if ( dir.empty() )
- {
- // default
-#if defined(__DOS__) || defined(__OS2__)
- dir = _T(".");
-#elif defined(__WXMAC__)
- dir = wxMacFindFolder(short(kOnSystemDisk), kTemporaryFolderType, kCreateFolder);
-#else
- dir = _T("/tmp");
-#endif
- }
-
path = dir;
if ( !wxEndsWithPathSeparator(dir) &&
path += _T("XXXXXX");
// we need to copy the path to the buffer in which mkstemp() can modify it
- wxCharBuffer buf( wxConvFile.cWX2MB( path ) );
+ wxCharBuffer buf(path.fn_str());
// cast is safe because the string length doesn't change
int fdTemp = mkstemp( (char*)(const char*) buf );
// directory operations
// ----------------------------------------------------------------------------
+// helper of GetTempDir(): check if the given directory exists and return it if
+// it does or an empty string otherwise
+namespace
+{
+
+wxString CheckIfDirExists(const wxString& dir)
+{
+ return wxFileName::DirExists(dir) ? dir : wxString();
+}
+
+} // anonymous namespace
+
+wxString wxFileName::GetTempDir()
+{
+ // first try getting it from environment: this allows overriding the values
+ // used by default if the user wants to create temporary files in another
+ // directory
+ wxString dir = CheckIfDirExists(wxGetenv("TMPDIR"));
+ if ( dir.empty() )
+ {
+ dir = CheckIfDirExists(wxGetenv("TMP"));
+ if ( dir.empty() )
+ dir = CheckIfDirExists(wxGetenv("TEMP"));
+ }
+
+ // if no environment variables are set, use the system default
+ if ( dir.empty() )
+ {
+#if defined(__WXWINCE__)
+ dir = CheckIfDirExists(wxT("\\temp"));
+#elif defined(__WINDOWS__) && !defined(__WXMICROWIN__)
+ if ( !::GetTempPath(MAX_PATH, wxStringBuffer(dir, MAX_PATH + 1)) )
+ {
+ wxLogLastError(_T("GetTempPath"));
+ }
+#elif defined(__WXMAC__) && wxOSX_USE_CARBON
+ dir = wxMacFindFolder(short(kOnSystemDisk), kTemporaryFolderType, kCreateFolder);
+#endif // systems with native way
+ }
+
+ // fall back to hard coded value
+ if ( dir.empty() )
+ {
+#ifdef __UNIX_LIKE__
+ dir = CheckIfDirExists("/tmp");
+ if ( dir.empty() )
+#endif // __UNIX_LIKE__
+ dir = ".";
+ }
+
+ return dir;
+}
+
bool wxFileName::Mkdir( int perm, int flags )
{
return wxFileName::Mkdir(GetPath(), perm, flags);
size_t count = dirs.GetCount();
for ( size_t i = 0; i < count; i++ )
{
- if ( i > 0 ||
-#if defined(__WXMAC__) && !defined(__DARWIN__)
- // relative pathnames are exactely the other way round under mac...
- !filename.IsAbsolute()
-#else
- filename.IsAbsolute()
-#endif
- )
+ if ( i > 0 || filename.IsAbsolute() )
currPath += wxFILE_SEP_PATH;
currPath += dirs[i];
return ::wxMkdir( dir, perm );
}
-bool wxFileName::Rmdir()
+bool wxFileName::Rmdir(int flags)
{
- return wxFileName::Rmdir( GetPath() );
+ return wxFileName::Rmdir( GetPath(), flags );
}
-bool wxFileName::Rmdir( const wxString &dir )
+bool wxFileName::Rmdir(const wxString& dir, int flags)
{
- return ::wxRmdir( dir );
+#ifdef __WXMSW__
+ if ( flags & wxPATH_RMDIR_RECURSIVE )
+ {
+ // SHFileOperation needs double null termination string
+ // but without separator at the end of the path
+ wxString path(dir);
+ if ( path.Last() == wxFILE_SEP_PATH )
+ path.RemoveLast();
+ path += _T('\0');
+
+ SHFILEOPSTRUCT fileop;
+ wxZeroMemory(fileop);
+ fileop.wFunc = FO_DELETE;
+ fileop.pFrom = path.fn_str();
+ fileop.fFlags = FOF_SILENT | FOF_NOCONFIRMATION;
+ #ifndef __WXWINCE__
+ // FOF_NOERRORUI is not defined in WinCE
+ fileop.fFlags |= FOF_NOERRORUI;
+ #endif
+
+ int ret = SHFileOperation(&fileop);
+ if ( ret != 0 )
+ {
+ // SHFileOperation may return non-Win32 error codes, so the error
+ // message can be incorrect
+ wxLogApiError(_T("SHFileOperation"), ret);
+ return false;
+ }
+
+ return true;
+ }
+ else if ( flags & wxPATH_RMDIR_FULL )
+#else // !__WXMSW__
+ if ( flags != 0 ) // wxPATH_RMDIR_FULL or wxPATH_RMDIR_RECURSIVE
+#endif // !__WXMSW__
+ {
+ wxString path(dir);
+ if ( path.Last() != wxFILE_SEP_PATH )
+ path += wxFILE_SEP_PATH;
+
+ wxDir d(path);
+
+ if ( !d.IsOpened() )
+ return false;
+
+ wxString filename;
+
+ // first delete all subdirectories
+ bool cont = d.GetFirst(&filename, "", wxDIR_DIRS | wxDIR_HIDDEN);
+ while ( cont )
+ {
+ wxFileName::Rmdir(path + filename, flags);
+ cont = d.GetNext(&filename);
+ }
+
+#ifndef __WXMSW__
+ if ( flags & wxPATH_RMDIR_RECURSIVE )
+ {
+ // delete all files too
+ cont = d.GetFirst(&filename, "", wxDIR_FILES | wxDIR_HIDDEN);
+ while ( cont )
+ {
+ ::wxRemoveFile(path + filename);
+ cont = d.GetNext(&filename);
+ }
+ }
+#endif // !__WXMSW__
+ }
+
+ return ::wxRmdir(dir);
}
// ----------------------------------------------------------------------------
}
}
-
// the existing path components
wxArrayString dirs = GetDirs();
format = GetFormat(format);
- // make the path absolute
+ // set up the directory to use for making the path absolute later
if ( (flags & wxPATH_NORM_ABSOLUTE) && !IsAbsolute(format) )
{
if ( cwd.empty() )
{
curDir.AssignDir(cwd);
}
-
- // the path may be not absolute because it doesn't have the volume name
- // but in this case we shouldn't modify the directory components of it
- // but just set the current volume
- if ( !HasVolume() && curDir.HasVolume() )
- {
- SetVolume(curDir.GetVolume());
-
- if ( !m_relative )
- {
- // yes, it was the case - we don't need curDir then
- curDir.Clear();
- }
- }
}
// handle ~ stuff under Unix only
wxString dir = dirs[0u];
if ( !dir.empty() && dir[0u] == _T('~') )
{
+ // to make the path absolute use the home directory
curDir.AssignDir(wxGetUserHome(dir.c_str() + 1));
+ // if we are expanding the tilde, then this path
+ // *should* be already relative (since we checked for
+ // the tilde only in the first char of the first dir);
+ // if m_relative==false, it's because it was initialized
+ // from a string which started with /~; in that case
+ // we reach this point but then need m_relative=true
+ // for relative->absolute expansion later
+ m_relative = true;
+
dirs.RemoveAt(0u);
}
}
// transform relative path into abs one
if ( curDir.IsOk() )
{
- wxArrayString dirsNew = curDir.GetDirs();
- size_t count = dirs.GetCount();
- for ( size_t n = 0; n < count; n++ )
+ // this path may be relative because it doesn't have the volume name
+ // and still have m_relative=true; in this case we shouldn't modify
+ // our directory components but just set the current volume
+ if ( !HasVolume() && curDir.HasVolume() )
+ {
+ SetVolume(curDir.GetVolume());
+
+ if ( !m_relative )
{
- dirsNew.Add(dirs[n]);
+ // yes, it was the case - we don't need curDir then
+ curDir.Clear();
+ }
}
- dirs = dirsNew;
+ // finally, prepend curDir to the dirs array
+ wxArrayString dirsNew = curDir.GetDirs();
+ WX_PREPEND_ARRAY(dirs, dirsNew);
+
+ // if we used e.g. tilde expansion previously and wxGetUserHome didn't
+ // return for some reason an absolute path, then curDir maybe not be absolute!
+ if ( curDir.IsAbsolute(format) )
+ {
+ // we have prepended an absolute path and thus we are now an absolute
+ // file name too
+ m_relative = false;
+ }
+ // else if (flags & wxPATH_NORM_ABSOLUTE):
+ // should we warn the user that we didn't manage to make the path absolute?
}
// now deal with ".", ".." and the rest
}
}
- if ( (flags & wxPATH_NORM_CASE) && !IsCaseSensitive(format) )
- {
- dir.MakeLower();
- }
-
m_dirs.Add(dir);
}
wxString filename;
if (GetShortcutTarget(GetFullPath(format), filename))
{
- // Repeat this since we may now have a new path
- if ( (flags & wxPATH_NORM_CASE) && !IsCaseSensitive(format) )
- {
- filename.MakeLower();
- }
m_relative = false;
Assign(filename);
}
}
#endif
- if ( (flags & wxPATH_NORM_CASE) && !IsCaseSensitive(format) )
+#if defined(__WIN32__)
+ if ( (flags & wxPATH_NORM_LONG) && (format == wxPATH_DOS) )
{
- // VZ: expand env vars here too?
+ Assign(GetLongPath());
+ }
+#endif // Win32
+ // Change case (this should be kept at the end of the function, to ensure
+ // that the path doesn't change any more after we normalize its case)
+ if ( (flags & wxPATH_NORM_CASE) && !IsCaseSensitive(format) )
+ {
m_volume.MakeLower();
m_name.MakeLower();
m_ext.MakeLower();
+
+ // directory entries must be made lower case as well
+ count = m_dirs.GetCount();
+ for ( size_t i = 0; i < count; i++ )
+ {
+ m_dirs[i].MakeLower();
+ }
}
- // we do have the path now
- //
- // NB: need to do this before (maybe) calling Assign() below
- m_relative = false;
+ return true;
+}
-#if defined(__WIN32__)
- if ( (flags & wxPATH_NORM_LONG) && (format == wxPATH_DOS) )
- {
- Assign(GetLongPath());
- }
-#endif // Win32
+#ifndef __WXWINCE__
+bool wxFileName::ReplaceEnvVariable(const wxString& envname,
+ const wxString& replacementFmtString,
+ wxPathFormat format)
+{
+ // look into stringForm for the contents of the given environment variable
+ wxString val;
+ if (envname.empty() ||
+ !wxGetEnv(envname, &val))
+ return false;
+ if (val.empty())
+ return false;
+
+ wxString stringForm = GetPath(wxPATH_GET_VOLUME, format);
+ // do not touch the file name and the extension
+
+ wxString replacement = wxString::Format(replacementFmtString, envname);
+ stringForm.Replace(val, replacement);
+
+ // Now assign ourselves the modified path:
+ Assign(stringForm, GetFullName(), format);
+
+ return true;
+}
+#endif
+
+bool wxFileName::ReplaceHomeDir(wxPathFormat format)
+{
+ wxString homedir = wxGetHomeDir();
+ if (homedir.empty())
+ return false;
+
+ wxString stringForm = GetPath(wxPATH_GET_VOLUME, format);
+ // do not touch the file name and the extension
+
+ stringForm.Replace(homedir, "~");
+
+ // Now assign ourselves the modified path:
+ Assign(stringForm, GetFullName(), format);
return true;
}
wxString* arguments)
{
wxString path, file, ext;
- wxSplitPath(shortcutPath, & path, & file, & ext);
+ wxFileName::SplitPath(shortcutPath, & path, & file, & ext);
HRESULT hres;
IShellLink* psl;
wxString path(GetFullPath());
#if defined(__WXMSW__) && defined(__WIN32__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
- DWORD sz = ::GetShortPathName(path, NULL, 0);
+ DWORD sz = ::GetShortPathName(path.fn_str(), NULL, 0);
if ( sz != 0 )
{
wxString pathOut;
if ( ::GetShortPathName
(
- path,
+ path.fn_str(),
wxStringBuffer(pathOut, sz),
sz
) != 0 )
wxString pathOut,
path = GetFullPath();
-#if defined(__WIN32__) && !defined(__WXMICROWIN__)
+#if defined(__WIN32__) && !defined(__WXWINCE__) && !defined(__WXMICROWIN__)
-#if wxUSE_DYNAMIC_LOADER
+#if wxUSE_DYNLIB_CLASS
typedef DWORD (WINAPI *GET_LONG_PATH_NAME)(const wxChar *, wxChar *, DWORD);
// this is MT-safe as in the worst case we're going to resolve the function
if ( s_pfnGetLongPathName )
{
- DWORD dwSize = (*s_pfnGetLongPathName)(path, NULL, 0);
+ DWORD dwSize = (*s_pfnGetLongPathName)(path.fn_str(), NULL, 0);
if ( dwSize > 0 )
{
if ( (*s_pfnGetLongPathName)
(
- path,
+ path.fn_str(),
wxStringBuffer(pathOut, dwSize),
dwSize
) != 0 )
}
}
}
-#endif // wxUSE_DYNAMIC_LOADER
+#endif // wxUSE_DYNLIB_CLASS
// The OS didn't support GetLongPathName, or some other error.
// We need to call FindFirstFile on each component in turn.
size_t count = dirs.GetCount();
for ( size_t i = 0; i < count; i++ )
{
+ const wxString& dir = dirs[i];
+
// We're using pathOut to collect the long-name path, but using a
// temporary for appending the last path component which may be
// short-name
- tmpPath = pathOut + dirs[i];
-
- if ( tmpPath.empty() )
- continue;
-
- // can't see this being necessary? MF
- if ( tmpPath.Last() == GetVolumeSeparator(wxPATH_DOS) )
+ tmpPath = pathOut + dir;
+
+ // We must not process "." or ".." here as they would be (unexpectedly)
+ // replaced by the corresponding directory names so just leave them
+ // alone
+ //
+ // And we can't pass a drive and root dir to FindFirstFile (VZ: why?)
+ if ( tmpPath.empty() || dir == '.' || dir == ".." ||
+ tmpPath.Last() == GetVolumeSeparator(wxPATH_DOS) )
{
- // Can't pass a drive and root dir to FindFirstFile,
- // so continue to next dir
tmpPath += wxFILE_SEP_PATH;
pathOut = tmpPath;
continue;
}
- hFind = ::FindFirstFile(tmpPath, &findFileData);
+ hFind = ::FindFirstFile(tmpPath.fn_str(), &findFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
// Error: most likely reason is that path doesn't exist, so
{
#if defined(__WXMSW__) || defined(__OS2__) || defined(__DOS__)
format = wxPATH_DOS;
-#elif defined(__WXMAC__) && !defined(__DARWIN__)
- format = wxPATH_MAC;
#elif defined(__VMS)
format = wxPATH_VMS;
#else
return format;
}
+#ifdef wxHAS_FILESYSTEM_VOLUMES
+
+/* static */
+wxString wxFileName::GetVolumeString(char drive, int flags)
+{
+ wxASSERT_MSG( !(flags & ~wxPATH_GET_SEPARATOR), "invalid flag specified" );
+
+ wxString vol(drive);
+ vol += wxFILE_SEP_DSK;
+ if ( flags & wxPATH_GET_SEPARATOR )
+ vol += wxFILE_SEP_PATH;
+
+ return vol;
+}
+
+#endif // wxHAS_FILESYSTEM_VOLUMES
+
// ----------------------------------------------------------------------------
// path splitting function
// ----------------------------------------------------------------------------
wxString fullpath = fullpathWithVolume;
// special Windows UNC paths hack: transform \\share\path into share:path
- if ( format == wxPATH_DOS )
+ if ( IsUNCPath(fullpath, format) )
{
- if ( fullpath.length() >= 4 &&
- fullpath[0u] == wxFILE_SEP_PATH_DOS &&
- fullpath[1u] == wxFILE_SEP_PATH_DOS )
- {
- fullpath.erase(0, 2);
+ fullpath.erase(0, 2);
- size_t posFirstSlash =
- fullpath.find_first_of(GetPathTerminators(format));
- if ( posFirstSlash != wxString::npos )
- {
- fullpath[posFirstSlash] = wxFILE_SEP_DSK;
+ size_t posFirstSlash =
+ fullpath.find_first_of(GetPathTerminators(format));
+ if ( posFirstSlash != wxString::npos )
+ {
+ fullpath[posFirstSlash] = wxFILE_SEP_DSK;
- // UNC paths are always absolute, right? (FIXME)
- fullpath.insert(posFirstSlash + 1, 1, wxFILE_SEP_PATH_DOS);
- }
+ // UNC paths are always absolute, right? (FIXME)
+ fullpath.insert(posFirstSlash + 1, 1, wxFILE_SEP_PATH_DOS);
}
}
}
}
+/* static */
+wxString wxFileName::StripExtension(const wxString& fullpath)
+{
+ wxFileName fn(fullpath);
+ fn.SetExt("");
+ return fn.GetFullPath();
+}
+
// ----------------------------------------------------------------------------
// time functions
// ----------------------------------------------------------------------------
const wxDateTime *dtCreate)
{
#if defined(__WIN32__)
+ FILETIME ftAccess, ftCreate, ftWrite;
+
+ if ( dtCreate )
+ ConvertWxToFileTime(&ftCreate, *dtCreate);
+ if ( dtAccess )
+ ConvertWxToFileTime(&ftAccess, *dtAccess);
+ if ( dtMod )
+ ConvertWxToFileTime(&ftWrite, *dtMod);
+
+ wxString path;
+ int flags;
if ( IsDir() )
{
- // VZ: please let me know how to do this if you can
- wxFAIL_MSG( _T("SetTimes() not implemented for the directories") );
+ if ( wxGetOsVersion() == wxOS_WINDOWS_9X )
+ {
+ wxLogError(_("Setting directory access times is not supported "
+ "under this OS version"));
+ return false;
+ }
+
+ path = GetPath();
+ flags = FILE_FLAG_BACKUP_SEMANTICS;
}
else // file
{
- wxFileHandle fh(GetFullPath(), wxFileHandle::Write);
- if ( fh.IsOk() )
- {
- FILETIME ftAccess, ftCreate, ftWrite;
-
- if ( dtCreate )
- ConvertWxToFileTime(&ftCreate, *dtCreate);
- if ( dtAccess )
- ConvertWxToFileTime(&ftAccess, *dtAccess);
- if ( dtMod )
- ConvertWxToFileTime(&ftWrite, *dtMod);
+ path = GetFullPath();
+ flags = 0;
+ }
- if ( ::SetFileTime(fh,
- dtCreate ? &ftCreate : NULL,
- dtAccess ? &ftAccess : NULL,
- dtMod ? &ftWrite : NULL) )
- {
- return true;
- }
+ wxFileHandle fh(path, wxFileHandle::Write, flags);
+ if ( fh.IsOk() )
+ {
+ if ( ::SetFileTime(fh,
+ dtCreate ? &ftCreate : NULL,
+ dtAccess ? &ftAccess : NULL,
+ dtMod ? &ftWrite : NULL) )
+ {
+ return true;
}
}
#elif defined(__UNIX_LIKE__) || (defined(__DOS__) && defined(__WATCOMC__))
return true;
}
#elif defined(__UNIX_LIKE__) || defined(__WXMAC__) || defined(__OS2__) || (defined(__DOS__) && defined(__WATCOMC__))
+ // no need to test for IsDir() here
wxStructStat stBuf;
if ( wxStat( GetFullPath().c_str(), &stBuf) == 0 )
{
// file size functions
// ----------------------------------------------------------------------------
+#if wxUSE_LONGLONG
+
/* static */
wxULongLong wxFileName::GetSize(const wxString &filename)
{
DWORD lpFileSizeHigh;
DWORD ret = GetFileSize(f, &lpFileSizeHigh);
- if (ret == INVALID_FILE_SIZE)
+ if ( ret == INVALID_FILE_SIZE && ::GetLastError() != NO_ERROR )
return wxInvalidSize;
- // compose the low-order and high-order byte sizes
- return wxULongLong(ret | (lpFileSizeHigh << sizeof(WORD)*2));
-
-#else // ! __WIN32__
-
+ return wxULongLong(lpFileSizeHigh, ret);
+#else // ! __WIN32__
wxStructStat st;
#ifndef wxNEED_WX_UNISTD_H
if (wxStat( filename.fn_str() , &st) != 0)
return GetHumanReadableSize(GetSize(), failmsg, precision);
}
+#endif // wxUSE_LONGLONG
// ----------------------------------------------------------------------------
// Mac-specific functions
// ----------------------------------------------------------------------------
-#ifdef __WXMAC__
+#if defined( __WXOSX_MAC__ ) && wxOSX_USE_CARBON
+
+namespace
+{
-const short kMacExtensionMaxLength = 16 ;
class MacDefaultExtensionRecord
{
-public :
- MacDefaultExtensionRecord()
- {
- m_ext[0] = 0 ;
- m_type = m_creator = 0 ;
- }
- MacDefaultExtensionRecord( const MacDefaultExtensionRecord& from )
- {
- wxStrcpy( m_ext , from.m_ext ) ;
- m_type = from.m_type ;
- m_creator = from.m_creator ;
- }
- MacDefaultExtensionRecord( const wxChar * extension , OSType type , OSType creator )
- {
- wxStrncpy( m_ext , extension , kMacExtensionMaxLength ) ;
- m_ext[kMacExtensionMaxLength] = 0 ;
- m_type = type ;
- m_creator = creator ;
- }
- wxChar m_ext[kMacExtensionMaxLength] ;
- OSType m_type ;
- OSType m_creator ;
-} ;
+public:
+ MacDefaultExtensionRecord()
+ {
+ m_type =
+ m_creator = 0 ;
+ }
+
+ // default copy ctor, assignment operator and dtor are ok
+
+ MacDefaultExtensionRecord(const wxString& ext, OSType type, OSType creator)
+ : m_ext(ext)
+ {
+ m_type = type;
+ m_creator = creator;
+ }
-WX_DECLARE_OBJARRAY(MacDefaultExtensionRecord, MacDefaultExtensionArray) ;
+ wxString m_ext;
+ OSType m_type;
+ OSType m_creator;
+};
+
+WX_DECLARE_OBJARRAY(MacDefaultExtensionRecord, MacDefaultExtensionArray);
-bool gMacDefaultExtensionsInited = false ;
+bool gMacDefaultExtensionsInited = false;
#include "wx/arrimpl.cpp"
-WX_DEFINE_EXPORTED_OBJARRAY(MacDefaultExtensionArray) ;
+WX_DEFINE_EXPORTED_OBJARRAY(MacDefaultExtensionArray);
-MacDefaultExtensionArray gMacDefaultExtensions ;
+MacDefaultExtensionArray gMacDefaultExtensions;
// load the default extensions
-MacDefaultExtensionRecord gDefaults[] =
+const MacDefaultExtensionRecord gDefaults[] =
{
- MacDefaultExtensionRecord( wxT("txt") , 'TEXT' , 'ttxt' ) ,
- MacDefaultExtensionRecord( wxT("tif") , 'TIFF' , '****' ) ,
- MacDefaultExtensionRecord( wxT("jpg") , 'JPEG' , '****' ) ,
-} ;
+ MacDefaultExtensionRecord( "txt", 'TEXT', 'ttxt' ),
+ MacDefaultExtensionRecord( "tif", 'TIFF', '****' ),
+ MacDefaultExtensionRecord( "jpg", 'JPEG', '****' ),
+};
-static void MacEnsureDefaultExtensionsLoaded()
+void MacEnsureDefaultExtensionsLoaded()
{
if ( !gMacDefaultExtensionsInited )
{
{
gMacDefaultExtensions.Add( gDefaults[i] ) ;
}
- gMacDefaultExtensionsInited = true ;
+ gMacDefaultExtensionsInited = true;
}
}
+} // anonymous namespace
+
bool wxFileName::MacSetTypeAndCreator( wxUint32 type , wxUint32 creator )
{
FSRef fsRef ;
void wxFileName::MacRegisterDefaultTypeAndCreator( const wxString& ext , wxUint32 type , wxUint32 creator )
{
- MacEnsureDefaultExtensionsLoaded() ;
- MacDefaultExtensionRecord rec ;
- rec.m_type = type ;
- rec.m_creator = creator ;
- wxStrncpy( rec.m_ext , ext.Lower().c_str() , kMacExtensionMaxLength ) ;
- gMacDefaultExtensions.Add( rec ) ;
+ MacEnsureDefaultExtensionsLoaded();
+ MacDefaultExtensionRecord rec(ext.Lower(), type, creator);
+ gMacDefaultExtensions.Add( rec );
}
-#endif
+
+#endif // defined( __WXOSX_MAC__ ) && wxOSX_USE_CARBON