1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxFileName - encapsulates a file path
4 // Author: Robert Roebling, Vadim Zeitlin
7 // Copyright: (c) 2000 Robert Roebling
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 #ifndef _WX_FILENAME_H_
12 #define _WX_FILENAME_H_
14 #include "wx/arrstr.h"
15 #include "wx/filefn.h"
16 #include "wx/datetime.h"
18 #include "wx/longlong.h"
22 class WXDLLIMPEXP_FWD_BASE wxFile
;
26 class WXDLLIMPEXP_FWD_BASE wxFFile
;
29 // this symbol is defined for the platforms where file systems use volumes in
31 #if defined(__WINDOWS__) || defined(__DOS__) || defined(__OS2__)
32 #define wxHAS_FILESYSTEM_VOLUMES
35 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 // the various values for the path format: this mainly affects the path
40 // separator but also whether or not the path has the drive part (as under
44 wxPATH_NATIVE
= 0, // the path format for the current platform
46 wxPATH_BEOS
= wxPATH_UNIX
,
49 wxPATH_WIN
= wxPATH_DOS
,
50 wxPATH_OS2
= wxPATH_DOS
,
53 wxPATH_MAX
// Not a valid value for specifying path format
56 // different conventions that may be used with GetHumanReadableSize()
59 wxSIZE_CONV_TRADITIONAL
, // 1024 bytes = 1 KB
60 wxSIZE_CONV_IEC
, // 1024 bytes = 1 KiB
61 wxSIZE_CONV_SI
// 1000 bytes = 1 KB
64 // the kind of normalization to do with the file name: these values can be
65 // or'd together to perform several operations at once
68 wxPATH_NORM_ENV_VARS
= 0x0001, // replace env vars with their values
69 wxPATH_NORM_DOTS
= 0x0002, // squeeze all .. and .
70 wxPATH_NORM_TILDE
= 0x0004, // Unix only: replace ~ and ~user
71 wxPATH_NORM_CASE
= 0x0008, // if case insensitive => tolower
72 wxPATH_NORM_ABSOLUTE
= 0x0010, // make the path absolute
73 wxPATH_NORM_LONG
= 0x0020, // make the path the long form
74 wxPATH_NORM_SHORTCUT
= 0x0040, // resolve the shortcut, if it is a shortcut
75 wxPATH_NORM_ALL
= 0x00ff & ~wxPATH_NORM_CASE
78 // what exactly should GetPath() return?
81 wxPATH_NO_SEPARATOR
= 0x0000, // for symmetry with wxPATH_GET_SEPARATOR
82 wxPATH_GET_VOLUME
= 0x0001, // include the volume if applicable
83 wxPATH_GET_SEPARATOR
= 0x0002 // terminate the path with the separator
89 wxPATH_MKDIR_FULL
= 0x0001 // create directories recursively
95 wxPATH_RMDIR_FULL
= 0x0001, // delete with subdirectories if empty
96 wxPATH_RMDIR_RECURSIVE
= 0x0002 // delete all recursively (dangerous!)
102 wxFILE_EXISTS_REGULAR
= 0x0001, // check for existence of a regular file
103 wxFILE_EXISTS_DIR
= 0x0002, // check for existence of a directory
104 wxFILE_EXISTS_SYMLINK
= 0x1004, // check for existence of a symbolic link;
105 // also sets wxFILE_EXISTS_NO_FOLLOW as
106 // it would never be satisfied otherwise
107 wxFILE_EXISTS_DEVICE
= 0x0008, // check for existence of a device
108 wxFILE_EXISTS_FIFO
= 0x0016, // check for existence of a FIFO
109 wxFILE_EXISTS_SOCKET
= 0x0032, // check for existence of a socket
110 // gap for future types
111 wxFILE_EXISTS_NO_FOLLOW
= 0x1000, // don't dereference a contained symlink
112 wxFILE_EXISTS_ANY
= 0x1FFF // check for existence of anything
116 // error code of wxFileName::GetSize()
117 extern WXDLLIMPEXP_DATA_BASE(const wxULongLong
) wxInvalidSize
;
118 #endif // wxUSE_LONGLONG
122 // ----------------------------------------------------------------------------
123 // wxFileName: encapsulates a file path
124 // ----------------------------------------------------------------------------
126 class WXDLLIMPEXP_BASE wxFileName
129 // constructors and assignment
132 wxFileName() { Clear(); }
133 wxFileName(const wxFileName
& filepath
) { Assign(filepath
); }
135 // from a full filename: if it terminates with a '/', a directory path
136 // is contructed (the name will be empty), otherwise a file name and
137 // extension are extracted from it
138 wxFileName( const wxString
& fullpath
, wxPathFormat format
= wxPATH_NATIVE
)
139 { Assign( fullpath
, format
); m_dontFollowLinks
= false; }
141 // from a directory name and a file name
142 wxFileName(const wxString
& path
,
143 const wxString
& name
,
144 wxPathFormat format
= wxPATH_NATIVE
)
145 { Assign(path
, name
, format
); m_dontFollowLinks
= false; }
147 // from a volume, directory name, file base name and extension
148 wxFileName(const wxString
& volume
,
149 const wxString
& path
,
150 const wxString
& name
,
152 wxPathFormat format
= wxPATH_NATIVE
)
153 { Assign(volume
, path
, name
, ext
, format
); m_dontFollowLinks
= false; }
155 // from a directory name, file base name and extension
156 wxFileName(const wxString
& path
,
157 const wxString
& name
,
159 wxPathFormat format
= wxPATH_NATIVE
)
160 { Assign(path
, name
, ext
, format
); m_dontFollowLinks
= false; }
162 // the same for delayed initialization
164 void Assign(const wxFileName
& filepath
);
166 void Assign(const wxString
& fullpath
,
167 wxPathFormat format
= wxPATH_NATIVE
);
169 void Assign(const wxString
& volume
,
170 const wxString
& path
,
171 const wxString
& name
,
174 wxPathFormat format
= wxPATH_NATIVE
);
176 void Assign(const wxString
& volume
,
177 const wxString
& path
,
178 const wxString
& name
,
180 wxPathFormat format
= wxPATH_NATIVE
)
181 { Assign(volume
, path
, name
, ext
, !ext
.empty(), format
); }
183 void Assign(const wxString
& path
,
184 const wxString
& name
,
185 wxPathFormat format
= wxPATH_NATIVE
);
187 void Assign(const wxString
& path
,
188 const wxString
& name
,
190 wxPathFormat format
= wxPATH_NATIVE
);
192 void AssignDir(const wxString
& dir
, wxPathFormat format
= wxPATH_NATIVE
);
194 // assorted assignment operators
196 wxFileName
& operator=(const wxFileName
& filename
)
197 { if (this != &filename
) Assign(filename
); return *this; }
199 wxFileName
& operator=(const wxString
& filename
)
200 { Assign(filename
); return *this; }
202 // reset all components to default, uninitialized state
205 // static pseudo constructors
206 static wxFileName
FileName(const wxString
& file
,
207 wxPathFormat format
= wxPATH_NATIVE
);
208 static wxFileName
DirName(const wxString
& dir
,
209 wxPathFormat format
= wxPATH_NATIVE
);
213 // is the filename valid at all?
216 // we're fine if we have the path or the name or if we're a root dir
217 return m_dirs
.size() != 0 || !m_name
.empty() || !m_relative
||
218 !m_ext
.empty() || m_hasExt
;
221 // does the file with this name exist?
222 bool FileExists() const;
223 static bool FileExists( const wxString
&file
);
225 // does the directory with this name exist?
226 bool DirExists() const;
227 static bool DirExists( const wxString
&dir
);
229 // does anything at all with this name (i.e. file, directory or some
230 // other file system object such as a device, socket, ...) exist?
231 bool Exists(int flags
= wxFILE_EXISTS_ANY
) const;
232 static bool Exists(const wxString
& path
, int flags
= wxFILE_EXISTS_ANY
);
235 // checks on most common flags for files/directories;
236 // more platform-specific features (like e.g. Unix permissions) are not
237 // available in wxFileName
239 bool IsDirWritable() const { return wxIsWritable(GetPath()); }
240 static bool IsDirWritable(const wxString
&path
) { return wxDirExists(path
) && wxIsWritable(path
); }
242 bool IsDirReadable() const { return wxIsReadable(GetPath()); }
243 static bool IsDirReadable(const wxString
&path
) { return wxDirExists(path
) && wxIsReadable(path
); }
245 // NOTE: IsDirExecutable() is not present because the meaning of "executable"
246 // directory is very platform-dependent and also not so useful
248 bool IsFileWritable() const { return wxIsWritable(GetFullPath()); }
249 static bool IsFileWritable(const wxString
&path
) { return wxFileExists(path
) && wxIsWritable(path
); }
251 bool IsFileReadable() const { return wxIsReadable(GetFullPath()); }
252 static bool IsFileReadable(const wxString
&path
) { return wxFileExists(path
) && wxIsReadable(path
); }
254 bool IsFileExecutable() const { return wxIsExecutable(GetFullPath()); }
255 static bool IsFileExecutable(const wxString
&path
) { return wxFileExists(path
) && wxIsExecutable(path
); }
257 // set the file permissions to a combination of wxPosixPermissions enum
259 bool SetPermissions(int permissions
);
264 // set the file last access/mod and creation times
265 // (any of the pointers may be NULL)
266 bool SetTimes(const wxDateTime
*dtAccess
,
267 const wxDateTime
*dtMod
,
268 const wxDateTime
*dtCreate
) const;
270 // set the access and modification times to the current moment
273 // return the last access, last modification and create times
274 // (any of the pointers may be NULL)
275 bool GetTimes(wxDateTime
*dtAccess
,
277 wxDateTime
*dtCreate
) const;
279 // convenience wrapper: get just the last mod time of the file
280 wxDateTime
GetModificationTime() const
283 (void)GetTimes(NULL
, &dtMod
, NULL
);
286 #endif // wxUSE_DATETIME
288 #if defined( __WXOSX_MAC__ ) && wxOSX_USE_CARBON
289 bool MacSetTypeAndCreator( wxUint32 type
, wxUint32 creator
) ;
290 bool MacGetTypeAndCreator( wxUint32
*type
, wxUint32
*creator
) const;
291 // gets the 'common' type and creator for a certain extension
292 static bool MacFindDefaultTypeAndCreator( const wxString
& ext
, wxUint32
*type
, wxUint32
*creator
) ;
293 // registers application defined extensions and their default type and creator
294 static void MacRegisterDefaultTypeAndCreator( const wxString
& ext
, wxUint32 type
, wxUint32 creator
) ;
295 // looks up the appropriate type and creator from the registration and then sets
296 bool MacSetDefaultTypeAndCreator() ;
299 // various file/dir operations
301 // retrieve the value of the current working directory
302 void AssignCwd(const wxString
& volume
= wxEmptyString
);
303 static wxString
GetCwd(const wxString
& volume
= wxEmptyString
);
305 // change the current working directory
307 static bool SetCwd( const wxString
&cwd
);
309 // get the value of user home (Unix only mainly)
310 void AssignHomeDir();
311 static wxString
GetHomeDir();
313 // get the system temporary directory
314 static wxString
GetTempDir();
316 #if wxUSE_FILE || wxUSE_FFILE
317 // get a temp file name starting with the specified prefix
318 void AssignTempFileName(const wxString
& prefix
);
319 static wxString
CreateTempFileName(const wxString
& prefix
);
323 // get a temp file name starting with the specified prefix and open the
324 // file passed to us using this name for writing (atomically if
326 void AssignTempFileName(const wxString
& prefix
, wxFile
*fileTemp
);
327 static wxString
CreateTempFileName(const wxString
& prefix
,
332 // get a temp file name starting with the specified prefix and open the
333 // file passed to us using this name for writing (atomically if
335 void AssignTempFileName(const wxString
& prefix
, wxFFile
*fileTemp
);
336 static wxString
CreateTempFileName(const wxString
& prefix
,
338 #endif // wxUSE_FFILE
340 // directory creation and removal.
341 bool Mkdir(int perm
= wxS_DIR_DEFAULT
, int flags
= 0) const;
342 static bool Mkdir(const wxString
&dir
, int perm
= wxS_DIR_DEFAULT
,
345 bool Rmdir(int flags
= 0) const;
346 static bool Rmdir(const wxString
&dir
, int flags
= 0);
348 // operations on the path
350 // normalize the path: with the default flags value, the path will be
351 // made absolute, without any ".." and "." and all environment
352 // variables will be expanded in it
354 // this may be done using another (than current) value of cwd
355 bool Normalize(int flags
= wxPATH_NORM_ALL
,
356 const wxString
& cwd
= wxEmptyString
,
357 wxPathFormat format
= wxPATH_NATIVE
);
359 // get a path path relative to the given base directory, i.e. opposite
362 // pass an empty string to get a path relative to the working directory
364 // returns true if the file name was modified, false if we failed to do
365 // anything with it (happens when the file is on a different volume,
367 bool MakeRelativeTo(const wxString
& pathBase
= wxEmptyString
,
368 wxPathFormat format
= wxPATH_NATIVE
);
370 // make the path absolute
372 // this may be done using another (than current) value of cwd
373 bool MakeAbsolute(const wxString
& cwd
= wxEmptyString
,
374 wxPathFormat format
= wxPATH_NATIVE
)
375 { return Normalize(wxPATH_NORM_DOTS
| wxPATH_NORM_ABSOLUTE
|
376 wxPATH_NORM_TILDE
, cwd
, format
); }
379 // If the path is a symbolic link (Unix-only), indicate that all
380 // filesystem operations on this path should be performed on the link
381 // itself and not on the file it points to, as is the case by default.
383 // No effect if this is not a symbolic link.
384 void DontFollowLink()
386 m_dontFollowLinks
= true;
389 // If the path is a symbolic link (Unix-only), returns whether various
390 // file operations should act on the link itself, or on its target.
392 // This does not test if the path is really a symlink or not.
393 bool ShouldFollowLink() const
395 return !m_dontFollowLinks
;
398 #if defined(__WIN32__) && !defined(__WXWINCE__) && wxUSE_OLE
399 // if the path is a shortcut, return the target and optionally,
401 bool GetShortcutTarget(const wxString
& shortcutPath
,
402 wxString
& targetFilename
,
403 wxString
* arguments
= NULL
) const;
407 // if the path contains the value of the environment variable named envname
408 // then this function replaces it with the string obtained from
409 // wxString::Format(replacementFmtString, value_of_envname_variable)
412 // wxFileName fn("/usr/openwin/lib/someFile");
413 // fn.ReplaceEnvVariable("OPENWINHOME");
414 // // now fn.GetFullPath() == "$OPENWINHOME/lib/someFile"
415 bool ReplaceEnvVariable(const wxString
& envname
,
416 const wxString
& replacementFmtString
= "$%s",
417 wxPathFormat format
= wxPATH_NATIVE
);
420 // replaces, if present in the path, the home directory for the given user
421 // (see wxGetHomeDir) with a tilde
422 bool ReplaceHomeDir(wxPathFormat format
= wxPATH_NATIVE
);
427 // compares with the rules of the given platforms format
428 bool SameAs(const wxFileName
& filepath
,
429 wxPathFormat format
= wxPATH_NATIVE
) const;
431 // compare with another filename object
432 bool operator==(const wxFileName
& filename
) const
433 { return SameAs(filename
); }
434 bool operator!=(const wxFileName
& filename
) const
435 { return !SameAs(filename
); }
437 // compare with a filename string interpreted as a native file name
438 bool operator==(const wxString
& filename
) const
439 { return SameAs(wxFileName(filename
)); }
440 bool operator!=(const wxString
& filename
) const
441 { return !SameAs(wxFileName(filename
)); }
443 // are the file names of this type cases sensitive?
444 static bool IsCaseSensitive( wxPathFormat format
= wxPATH_NATIVE
);
446 // is this filename absolute?
447 bool IsAbsolute(wxPathFormat format
= wxPATH_NATIVE
) const;
449 // is this filename relative?
450 bool IsRelative(wxPathFormat format
= wxPATH_NATIVE
) const
451 { return !IsAbsolute(format
); }
453 // Returns the characters that aren't allowed in filenames
454 // on the specified platform.
455 static wxString
GetForbiddenChars(wxPathFormat format
= wxPATH_NATIVE
);
457 // Information about path format
459 // get the string separating the volume from the path for this format,
460 // return an empty string if this format doesn't support the notion of
462 static wxString
GetVolumeSeparator(wxPathFormat format
= wxPATH_NATIVE
);
464 // get the string of path separators for this format
465 static wxString
GetPathSeparators(wxPathFormat format
= wxPATH_NATIVE
);
467 // get the string of path terminators, i.e. characters which terminate the
469 static wxString
GetPathTerminators(wxPathFormat format
= wxPATH_NATIVE
);
471 // get the canonical path separator for this format
472 static wxUniChar
GetPathSeparator(wxPathFormat format
= wxPATH_NATIVE
)
473 { return GetPathSeparators(format
)[0u]; }
475 // is the char a path separator for this format?
476 static bool IsPathSeparator(wxChar ch
, wxPathFormat format
= wxPATH_NATIVE
);
478 // is this is a DOS path which beings with a windows unique volume name
479 // ('\\?\Volume{guid}\')?
480 static bool IsMSWUniqueVolumeNamePath(const wxString
& path
,
481 wxPathFormat format
= wxPATH_NATIVE
);
484 size_t GetDirCount() const { return m_dirs
.size(); }
485 bool AppendDir(const wxString
& dir
);
486 void PrependDir(const wxString
& dir
);
487 bool InsertDir(size_t before
, const wxString
& dir
);
488 void RemoveDir(size_t pos
);
489 void RemoveLastDir() { RemoveDir(GetDirCount() - 1); }
492 void SetExt( const wxString
&ext
) { m_ext
= ext
; m_hasExt
= !m_ext
.empty(); }
493 void ClearExt() { m_ext
.clear(); m_hasExt
= false; }
494 void SetEmptyExt() { m_ext
.clear(); m_hasExt
= true; }
495 wxString
GetExt() const { return m_ext
; }
496 bool HasExt() const { return m_hasExt
; }
498 void SetName( const wxString
&name
) { m_name
= name
; }
499 wxString
GetName() const { return m_name
; }
500 bool HasName() const { return !m_name
.empty(); }
502 void SetVolume( const wxString
&volume
) { m_volume
= volume
; }
503 wxString
GetVolume() const { return m_volume
; }
504 bool HasVolume() const { return !m_volume
.empty(); }
506 // full name is the file name + extension (but without the path)
507 void SetFullName(const wxString
& fullname
);
508 wxString
GetFullName() const;
510 const wxArrayString
& GetDirs() const { return m_dirs
; }
512 // flags are combination of wxPATH_GET_XXX flags
513 wxString
GetPath(int flags
= wxPATH_GET_VOLUME
,
514 wxPathFormat format
= wxPATH_NATIVE
) const;
516 // Replace current path with this one
517 void SetPath( const wxString
&path
, wxPathFormat format
= wxPATH_NATIVE
);
519 // Construct full path with name and ext
520 wxString
GetFullPath( wxPathFormat format
= wxPATH_NATIVE
) const;
522 // Return the short form of the path (returns identity on non-Windows platforms)
523 wxString
GetShortPath() const;
525 // Return the long form of the path (returns identity on non-Windows platforms)
526 wxString
GetLongPath() const;
528 // Is this a file or directory (not necessarily an existing one)
529 bool IsDir() const { return m_name
.empty() && m_ext
.empty(); }
533 // get the canonical path format for this platform
534 static wxPathFormat
GetFormat( wxPathFormat format
= wxPATH_NATIVE
);
536 // split a fullpath into the volume, path, (base) name and extension
537 // (all of the pointers can be NULL)
538 static void SplitPath(const wxString
& fullpath
,
544 wxPathFormat format
= wxPATH_NATIVE
);
546 static void SplitPath(const wxString
& fullpath
,
553 SplitPath(fullpath
, volume
, path
, name
, ext
, NULL
, format
);
556 // compatibility version: volume is part of path
557 static void SplitPath(const wxString
& fullpath
,
561 wxPathFormat format
= wxPATH_NATIVE
);
563 // split a path into volume and pure path part
564 static void SplitVolume(const wxString
& fullpathWithVolume
,
567 wxPathFormat format
= wxPATH_NATIVE
);
569 // strip the file extension: "foo.bar" => "foo" (but ".baz" => ".baz")
570 static wxString
StripExtension(const wxString
& fullpath
);
572 #ifdef wxHAS_FILESYSTEM_VOLUMES
573 // return the string representing a file system volume, or drive
574 static wxString
GetVolumeString(char drive
, int flags
= wxPATH_GET_SEPARATOR
);
575 #endif // wxHAS_FILESYSTEM_VOLUMES
580 // returns the size of the given filename
581 wxULongLong
GetSize() const;
582 static wxULongLong
GetSize(const wxString
&file
);
584 // returns the size in a human readable form
586 GetHumanReadableSize(const wxString
& nullsize
= _("Not available"),
588 wxSizeConvention conv
= wxSIZE_CONV_TRADITIONAL
) const;
590 GetHumanReadableSize(const wxULongLong
& sz
,
591 const wxString
& nullsize
= _("Not available"),
593 wxSizeConvention conv
= wxSIZE_CONV_TRADITIONAL
);
594 #endif // wxUSE_LONGLONG
597 // deprecated methods, don't use any more
598 // --------------------------------------
600 #ifndef __DIGITALMARS__
601 wxString
GetPath( bool withSep
, wxPathFormat format
= wxPATH_NATIVE
) const
602 { return GetPath(withSep
? wxPATH_GET_SEPARATOR
: 0, format
); }
604 wxString
GetPathWithSep(wxPathFormat format
= wxPATH_NATIVE
) const
605 { return GetPath(wxPATH_GET_VOLUME
| wxPATH_GET_SEPARATOR
, format
); }
608 // check whether this dir is valid for Append/Prepend/InsertDir()
609 static bool IsValidDirComponent(const wxString
& dir
);
611 // the drive/volume/device specification (always empty for Unix)
614 // the path components of the file
615 wxArrayString m_dirs
;
617 // the file name and extension (empty for directories)
621 // when m_dirs is empty it may mean either that we have no path at all or
622 // that our path is '/', i.e. the root directory
624 // we use m_relative to distinguish between these two cases, it will be
625 // true in the former and false in the latter
627 // NB: the path is not absolute just because m_relative is false, it still
628 // needs the drive (i.e. volume) in some formats (Windows)
631 // when m_ext is empty, it may be because we don't have any extension or
632 // because we have an empty extension
634 // the difference is important as file with name "foo" and without
635 // extension has full name "foo" while with empty extension it is "foo."
638 // by default, symlinks are dereferenced but this flag can be set with
639 // DontFollowLink() to change this and make different operations work on
640 // this file path itself instead of the target of the symlink
641 bool m_dontFollowLinks
;
644 #endif // _WX_FILENAME_H_