Michael Hansen
12 years ago
6 changed files with 655 additions and 243 deletions
@ -0,0 +1,367 @@ |
|||||||
|
/*==LICENSE==*
|
||||||
|
|
||||||
|
CyanWorlds.com Engine - MMOG client, server and tools |
||||||
|
Copyright (C) 2011 Cyan Worlds, Inc. |
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify |
||||||
|
it under the terms of the GNU General Public License as published by |
||||||
|
the Free Software Foundation, either version 3 of the License, or |
||||||
|
(at your option) any later version. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License |
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Additional permissions under GNU GPL version 3 section 7 |
||||||
|
|
||||||
|
If you modify this Program, or any covered work, by linking or |
||||||
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
||||||
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
||||||
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
||||||
|
(or a modified version of those libraries), |
||||||
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
||||||
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
||||||
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
||||||
|
licensors of this Program grant you additional |
||||||
|
permission to convey the resulting work. Corresponding Source for a |
||||||
|
non-source form of such a combination shall include the source code for |
||||||
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
||||||
|
work. |
||||||
|
|
||||||
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
||||||
|
or by snail mail at: |
||||||
|
Cyan Worlds, Inc. |
||||||
|
14617 N Newport Hwy |
||||||
|
Mead, WA 99021 |
||||||
|
|
||||||
|
*==LICENSE==*/ |
||||||
|
|
||||||
|
#include "plFileSystem.h" |
||||||
|
|
||||||
|
#if HS_BUILD_FOR_WIN32 |
||||||
|
# include "hsWindows.h" |
||||||
|
# include <shlobj.h> |
||||||
|
#else |
||||||
|
# include <limits.h> |
||||||
|
# include <unistd.h> |
||||||
|
# include <sys/types.h> |
||||||
|
# include <cstdlib> |
||||||
|
# include <functional> |
||||||
|
#endif |
||||||
|
#include <sys/stat.h> |
||||||
|
#include "plProduct.h" |
||||||
|
|
||||||
|
/* NOTE For this file: Windows uses UTF-16 filenames, and does not support
|
||||||
|
* the use of UTF-8 in their ANSI API. In order to ensure proper unicode |
||||||
|
* support, we convert the UTF-8 format stored in plString to UTF-16 before |
||||||
|
* passing them along to Windows. |
||||||
|
*/ |
||||||
|
|
||||||
|
plString plFileName::GetFileName() const |
||||||
|
{ |
||||||
|
int end = fName.FindLast('/'); |
||||||
|
if (end < 0) |
||||||
|
end = fName.FindLast('\\'); |
||||||
|
if (end < 0) |
||||||
|
return fName; |
||||||
|
|
||||||
|
return fName.Substr(end + 1); |
||||||
|
} |
||||||
|
|
||||||
|
plString plFileName::GetFileExt() const |
||||||
|
{ |
||||||
|
int dot = fName.FindLast('.'); |
||||||
|
|
||||||
|
// Be sure not to get a dot in the directory!
|
||||||
|
int end = fName.FindLast('/'); |
||||||
|
if (end < 0) |
||||||
|
end = fName.FindLast('\\'); |
||||||
|
|
||||||
|
if (dot > end) |
||||||
|
return fName.Substr(dot + 1); |
||||||
|
|
||||||
|
return plString::Null; |
||||||
|
} |
||||||
|
|
||||||
|
plString plFileName::GetFileNameNoExt() const |
||||||
|
{ |
||||||
|
int dot = fName.FindLast('.'); |
||||||
|
|
||||||
|
int end = fName.FindLast('/'); |
||||||
|
if (end < 0) |
||||||
|
end = fName.FindLast('\\'); |
||||||
|
|
||||||
|
// Be sure not to get a dot in the directory!
|
||||||
|
if (dot > end) |
||||||
|
return fName.Substr(end + 1, dot - end - 1); |
||||||
|
return fName.Substr(end + 1); |
||||||
|
} |
||||||
|
|
||||||
|
plFileName plFileName::StripFileName() const |
||||||
|
{ |
||||||
|
int end = fName.FindLast('/'); |
||||||
|
if (end < 0) |
||||||
|
end = fName.FindLast('\\'); |
||||||
|
if (end < 0) |
||||||
|
return ""; |
||||||
|
|
||||||
|
return fName.Left(end); |
||||||
|
} |
||||||
|
|
||||||
|
plFileName plFileName::StripFileExt() const |
||||||
|
{ |
||||||
|
int dot = fName.FindLast('.'); |
||||||
|
|
||||||
|
// Be sure not to get a dot in the directory!
|
||||||
|
int end = fName.FindLast('/'); |
||||||
|
if (end < 0) |
||||||
|
end = fName.FindLast('\\'); |
||||||
|
|
||||||
|
if (dot > end) |
||||||
|
return fName.Left(dot); |
||||||
|
|
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
plFileName plFileName::Normalize(char slash) const |
||||||
|
{ |
||||||
|
plStringBuffer<char> norm; |
||||||
|
char *norm_p = norm.CreateWritableBuffer(fName.GetSize()); |
||||||
|
for (const char *p = fName.c_str(); *p; ++p) { |
||||||
|
if (*p == '/' || *p == '\\') |
||||||
|
*norm_p++ = slash; |
||||||
|
else |
||||||
|
*norm_p++ = *p; |
||||||
|
} |
||||||
|
*norm_p = 0; |
||||||
|
return plString(norm); |
||||||
|
} |
||||||
|
|
||||||
|
plFileName plFileName::AbsolutePath() const |
||||||
|
{ |
||||||
|
if (!IsValid()) |
||||||
|
return *this; |
||||||
|
|
||||||
|
plFileName path = Normalize(); |
||||||
|
|
||||||
|
#if HS_BUILD_FOR_WIN32 |
||||||
|
plStringBuffer<wchar_t> wideName = path.fName.ToWchar(); |
||||||
|
wchar_t path_sm[MAX_PATH]; |
||||||
|
uint32_t path_length = GetFullPathNameW(wideName, MAX_PATH, path_sm, nullptr); |
||||||
|
if (path_length >= MAX_PATH) { |
||||||
|
// Buffer not big enough
|
||||||
|
wchar_t *path_lg = new wchar_t[path_length]; |
||||||
|
GetFullPathNameW(wideName, path_length, path_lg, nullptr); |
||||||
|
path = plString::FromWchar(path_lg); |
||||||
|
delete [] path_lg; |
||||||
|
} else { |
||||||
|
path = plString::FromWchar(path_sm); |
||||||
|
} |
||||||
|
#else |
||||||
|
char *path_a = realpath(path.c_str(), nullptr); |
||||||
|
hsAssert(path_a, "Failure to get absolute path (unsupported libc?)"); |
||||||
|
path = path_a; |
||||||
|
free(path_a); |
||||||
|
#endif |
||||||
|
|
||||||
|
return path; |
||||||
|
} |
||||||
|
|
||||||
|
plFileName plFileName::Join(const plFileName &base, const plFileName &path) |
||||||
|
{ |
||||||
|
if (!base.IsValid()) |
||||||
|
return path; |
||||||
|
if (!path.IsValid()) |
||||||
|
return base; |
||||||
|
|
||||||
|
char last = base.fName.CharAt(base.GetSize() - 1); |
||||||
|
char first = path.fName.CharAt(0); |
||||||
|
if (last != '/' && last != '\\') { |
||||||
|
if (first != '/' && first != '\\') { |
||||||
|
return plString::Format("%s" PATH_SEPARATOR_STR "%s", |
||||||
|
base.fName.c_str(), path.fName.c_str()); |
||||||
|
} |
||||||
|
return base.fName + path.fName; |
||||||
|
} else if (first != '/' && first != '\\') { |
||||||
|
return base.fName + path.fName; |
||||||
|
} |
||||||
|
// Both have a slash, but we only need one
|
||||||
|
return base.fName + path.fName.Substr(1); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* plFileInfo */ |
||||||
|
plFileInfo::plFileInfo(const plFileName &filename) |
||||||
|
: fFileSize(-1), fCreateTime(), fModifyTime(), fFlags() |
||||||
|
{ |
||||||
|
if (!filename.IsValid()) |
||||||
|
return; |
||||||
|
|
||||||
|
#if HS_BUILD_FOR_WIN32 |
||||||
|
struct __stat64 info; |
||||||
|
if (!_wstat64(filename.AsString().ToWchar(), &info) == 0) |
||||||
|
return; |
||||||
|
#else |
||||||
|
struct stat info; |
||||||
|
if (!stat(filename.AsString().c_str(), &info) == 0) |
||||||
|
return; |
||||||
|
#endif |
||||||
|
|
||||||
|
fFlags |= kEntryExists; |
||||||
|
fFileSize = info.st_size; |
||||||
|
fCreateTime = info.st_ctime; |
||||||
|
fModifyTime = info.st_mtime; |
||||||
|
if (info.st_mode & S_IFDIR) |
||||||
|
fFlags |= kIsDirectory; |
||||||
|
if (info.st_mode & S_IFREG) |
||||||
|
fFlags |= kIsNormalFile; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* plFileSystem */ |
||||||
|
plFileName plFileSystem::GetCWD() |
||||||
|
{ |
||||||
|
plFileName cwd; |
||||||
|
|
||||||
|
#if HS_BUILD_FOR_WIN32 |
||||||
|
wchar_t cwd_sm[MAX_PATH]; |
||||||
|
uint32_t cwd_length = GetCurrentDirectoryW(MAX_PATH, cwd_sm); |
||||||
|
if (cwd_length >= MAX_PATH) { |
||||||
|
// Buffer not big enough
|
||||||
|
wchar_t *cwd_lg = new wchar_t[cwd_length]; |
||||||
|
GetCurrentDirectoryW(cwd_length, cwd_lg); |
||||||
|
cwd = plString::FromWchar(cwd_lg); |
||||||
|
delete [] cwd_lg; |
||||||
|
} else { |
||||||
|
cwd = plString::FromWchar(cwd_sm); |
||||||
|
} |
||||||
|
#else |
||||||
|
char *cwd_a = getcwd(nullptr, 0); |
||||||
|
hsAssert(cwd_a, "Failure to get working directory (unsupported libc?)"); |
||||||
|
cwd = cwd_a; |
||||||
|
free(cwd_a); |
||||||
|
#endif |
||||||
|
|
||||||
|
return cwd; |
||||||
|
} |
||||||
|
|
||||||
|
FILE *plFileSystem::Open(const plFileName &filename, const char *mode) |
||||||
|
{ |
||||||
|
#if HS_BUILD_FOR_WIN32 |
||||||
|
wchar_t wmode[8]; |
||||||
|
size_t mlen = strlen(mode); |
||||||
|
hsAssert(mlen < arrsize(wmode), "Mode string too long"); |
||||||
|
|
||||||
|
// Quick and dirty, because mode should only ever be ANSI chars
|
||||||
|
for (size_t i = 0; i < mlen; ++i) { |
||||||
|
hsAssert(!(mode[i] & 0x80), "I SAID mode should ONLY ever be ANSI chars!"); |
||||||
|
wmode[i] = static_cast<wchar_t>(mode[i]); |
||||||
|
} |
||||||
|
wmode[mlen] = 0; |
||||||
|
|
||||||
|
return _wfopen(filename.AsString().ToWchar(), wmode); |
||||||
|
#else |
||||||
|
return fopen(filename.AsString().c_str(), mode); |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
bool plFileSystem::Unlink(const plFileName &filename) |
||||||
|
{ |
||||||
|
#if HS_BUILD_FOR_WIN32 |
||||||
|
return _wunlink(filename.AsString().ToWchar()) == 0; |
||||||
|
#else |
||||||
|
return unlink(filename.AsString().c_str()) == 0; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
bool plFileSystem::Move(const plFileName &from, const plFileName &to) |
||||||
|
{ |
||||||
|
#if HS_BUILD_FOR_WIN32 |
||||||
|
return MoveFileW(from.AsString().ToWchar(), to.AsString().ToWchar()); |
||||||
|
#else |
||||||
|
if (!Copy(from, to)) |
||||||
|
return false; |
||||||
|
return Unlink(from); |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
bool plFileSystem::Copy(const plFileName &from, const plFileName &to) |
||||||
|
{ |
||||||
|
#if HS_BUILD_FOR_WIN32 |
||||||
|
return CopyFileW(from.AsString().ToWchar(), to.AsString().ToWchar(), FALSE); |
||||||
|
#else |
||||||
|
typedef std::unique_ptr<FILE, std::function<int (FILE *)>> _FileRef; |
||||||
|
|
||||||
|
_FileRef ffrom(Open(from, "rb"), fclose); |
||||||
|
_FileRef fto(Open(to, "wb"), fclose); |
||||||
|
if (!ffrom.get() || !fto.get()) |
||||||
|
return false; |
||||||
|
|
||||||
|
size_t count; |
||||||
|
uint8_t buffer[4096]; |
||||||
|
while (!feof(ffrom.get())) { |
||||||
|
count = fread(buffer, sizeof(uint8_t), arrsize(buffer), ffrom.get()); |
||||||
|
if (ferror(ffrom.get())) |
||||||
|
return false; |
||||||
|
fwrite(data, sizeof(uint8_t), count, fto.get()); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
bool plFileSystem::CreateDir(const plFileName &dir, bool checkParents) |
||||||
|
{ |
||||||
|
if (checkParents) { |
||||||
|
plFileName parent = dir.StripFileName(); |
||||||
|
if (parent.IsValid() && !plFileInfo(parent).Exists() && !CreateDir(parent, true)) |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (plFileInfo(dir).Exists()) |
||||||
|
return true; |
||||||
|
|
||||||
|
#if HS_BUILD_FOR_WIN32 |
||||||
|
return CreateDirectoryW(dir.AsString().ToWchar(), nullptr); |
||||||
|
#else |
||||||
|
return (mkdir(dir.AsString().c_str(), 0755) == 0); |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
plFileName plFileSystem::GetUserDataPath() |
||||||
|
{ |
||||||
|
static plFileName _userData; |
||||||
|
|
||||||
|
if (!_userData.IsValid()) { |
||||||
|
#if HS_BUILD_FOR_WIN32 |
||||||
|
wchar_t path[MAX_PATH]; |
||||||
|
if (!SHGetSpecialFolderPathW(NULL, path, CSIDL_LOCAL_APPDATA, TRUE)) |
||||||
|
return ""; |
||||||
|
|
||||||
|
_userData = plFileName::Join(plString::FromWchar(path), plProduct::LongName()); |
||||||
|
#else |
||||||
|
_userData = plFileName::Join(getenv("HOME"), "." + plProduct::LongName()); |
||||||
|
#endif |
||||||
|
plFileSystem::CreateDir(_userData); |
||||||
|
} |
||||||
|
|
||||||
|
return _userData; |
||||||
|
} |
||||||
|
|
||||||
|
plFileName plFileSystem::GetInitPath() |
||||||
|
{ |
||||||
|
static plFileName _initPath = plFileName::Join(GetUserDataPath(), "Init"); |
||||||
|
plFileSystem::CreateDir(_initPath); |
||||||
|
return _initPath; |
||||||
|
} |
||||||
|
|
||||||
|
plFileName plFileSystem::GetLogPath() |
||||||
|
{ |
||||||
|
static plFileName _logPath = plFileName::Join(GetUserDataPath(), "Log"); |
||||||
|
plFileSystem::CreateDir(_logPath); |
||||||
|
return _logPath; |
||||||
|
} |
@ -0,0 +1,284 @@ |
|||||||
|
/*==LICENSE==*
|
||||||
|
|
||||||
|
CyanWorlds.com Engine - MMOG client, server and tools |
||||||
|
Copyright (C) 2011 Cyan Worlds, Inc. |
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify |
||||||
|
it under the terms of the GNU General Public License as published by |
||||||
|
the Free Software Foundation, either version 3 of the License, or |
||||||
|
(at your option) any later version. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License |
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Additional permissions under GNU GPL version 3 section 7 |
||||||
|
|
||||||
|
If you modify this Program, or any covered work, by linking or |
||||||
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
||||||
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
||||||
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
||||||
|
(or a modified version of those libraries), |
||||||
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
||||||
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
||||||
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
||||||
|
licensors of this Program grant you additional |
||||||
|
permission to convey the resulting work. Corresponding Source for a |
||||||
|
non-source form of such a combination shall include the source code for |
||||||
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
||||||
|
work. |
||||||
|
|
||||||
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
||||||
|
or by snail mail at: |
||||||
|
Cyan Worlds, Inc. |
||||||
|
14617 N Newport Hwy |
||||||
|
Mead, WA 99021 |
||||||
|
|
||||||
|
*==LICENSE==*/ |
||||||
|
|
||||||
|
#ifndef plFileSystem_Defined |
||||||
|
#define plFileSystem_Defined |
||||||
|
|
||||||
|
#include "plString.h" |
||||||
|
#include <cstdio> |
||||||
|
|
||||||
|
#if HS_BUILD_FOR_WIN32 |
||||||
|
# define PATH_SEPARATOR '\\' |
||||||
|
# define PATH_SEPARATOR_STR "\\" |
||||||
|
#else |
||||||
|
# define PATH_SEPARATOR '/' |
||||||
|
# define PATH_SEPARATOR_STR "/" |
||||||
|
#endif |
||||||
|
|
||||||
|
/** Represents a filename or path, including utilities for manipulating,
|
||||||
|
* splitting, and joining path components. |
||||||
|
* \sa plFileInfo |
||||||
|
*/ |
||||||
|
class plFileName |
||||||
|
{ |
||||||
|
public: |
||||||
|
/** Construct an empty filename. */ |
||||||
|
plFileName() { } |
||||||
|
|
||||||
|
/** Construct a filename from the UTF-8 character data in \a cstr. */ |
||||||
|
plFileName(const char *cstr) : fName(cstr) { } |
||||||
|
|
||||||
|
/** Construct a filename from the plString argument \a copy. */ |
||||||
|
plFileName(const plString ©) : fName(copy) { } |
||||||
|
|
||||||
|
/** Copy constructor. */ |
||||||
|
plFileName(const plFileName ©) : fName(copy.fName) { } |
||||||
|
|
||||||
|
/** Assignment operator. Same as plFileName(const char *). */ |
||||||
|
plFileName &operator=(const char *cstr) |
||||||
|
{ |
||||||
|
fName.operator=(cstr); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/** Assignment operator. Same as plFileName(const plString &). */ |
||||||
|
plFileName &operator=(const plString ©) |
||||||
|
{ |
||||||
|
fName.operator=(copy); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/** Assignment operator. Same as plFileName(const plFileName &). */ |
||||||
|
plFileName &operator=(const plFileName ©) |
||||||
|
{ |
||||||
|
fName.operator=(copy.fName); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/** Comparison operator. */ |
||||||
|
bool operator==(const char *other) const { return fName.operator==(other); } |
||||||
|
|
||||||
|
/** Comparison operator. */ |
||||||
|
bool operator==(const plFileName &other) const { return fName.operator==(other.fName); } |
||||||
|
|
||||||
|
/** Inverse of operator==(const char *other) const. */ |
||||||
|
bool operator!=(const char *other) const { return fName.operator!=(other); } |
||||||
|
|
||||||
|
/** Inverse of operator==(const plFileName &other) const. */ |
||||||
|
bool operator!=(const plFileName &other) const { return fName.operator!=(other.fName); } |
||||||
|
|
||||||
|
/** Operator overload for use in containers which depend on \c std::less. */ |
||||||
|
bool operator<(const plFileName &other) const { return fName.Compare(other.fName) < 0; } |
||||||
|
|
||||||
|
/** Functor which compares two filenames case-insensitively for sorting. */ |
||||||
|
struct less_i |
||||||
|
{ |
||||||
|
bool operator()(const plFileName &_L, const plFileName &_R) const |
||||||
|
{ return _L.fName.Compare(_R.fName, plString::kCaseInsensitive) < 0; } |
||||||
|
}; |
||||||
|
|
||||||
|
/** Return whether this filename is valid (not empty). */ |
||||||
|
bool IsValid() const { return !fName.IsEmpty(); } |
||||||
|
|
||||||
|
/** Return the length of the filename string (UTF-8). */ |
||||||
|
size_t GetSize() const { return fName.GetSize(); } |
||||||
|
|
||||||
|
/** Convert the filename to a string. This does not resolve relative
|
||||||
|
* paths or normalize slashes, it just returns the stored name string. |
||||||
|
*/ |
||||||
|
const plString &AsString() const { return fName; } |
||||||
|
|
||||||
|
/** Return the name portion of the path (including extension).
|
||||||
|
* For example: |
||||||
|
* <pre>plFileName("C:\\Path\\Filename.ext") => "Filename.ext"</pre> |
||||||
|
*/ |
||||||
|
plString GetFileName() const; |
||||||
|
|
||||||
|
/** Return the file extension from the filename.
|
||||||
|
* For example: |
||||||
|
* <pre>plFileName("C:\\Path\\Filename.ext") => "ext"</pre> |
||||||
|
*/ |
||||||
|
plString GetFileExt() const; |
||||||
|
|
||||||
|
/** Return the name portion of the path, excluding its extension.
|
||||||
|
* For example: |
||||||
|
* <pre>plFileName("C:\\Path\\Filename.ext") => "Filename"</pre> |
||||||
|
*/ |
||||||
|
plString GetFileNameNoExt() const; |
||||||
|
|
||||||
|
/** Return the path with the filename portion stripped off.
|
||||||
|
* For example: |
||||||
|
* <pre>plFileName("C:\\Path\\Filename.ext") => "C:\\Path"</pre> |
||||||
|
*/ |
||||||
|
plFileName StripFileName() const; |
||||||
|
|
||||||
|
/** Return the filename with the extension stripped off.
|
||||||
|
* For example: |
||||||
|
* <pre>plFileName("C:\\Path\\Filename.ext") => "C:\\Path\\Filename"</pre> |
||||||
|
*/ |
||||||
|
plFileName StripFileExt() const; |
||||||
|
|
||||||
|
/** Normalize slashes to a particular format. By default, we use the
|
||||||
|
* OS's native slash format. |
||||||
|
* For example: |
||||||
|
* <pre>plFileName("C:\\Path/Filename.ext").Normalize('\\') => "C:\\Path\\Filename.ext"</pre> |
||||||
|
*/ |
||||||
|
plFileName Normalize(char slash = PATH_SEPARATOR) const; |
||||||
|
|
||||||
|
/** Expand relative filenames and ./.. pieces to an absolute path. */ |
||||||
|
plFileName AbsolutePath() const; |
||||||
|
|
||||||
|
/** Join two path components together with the correct path separator.
|
||||||
|
* For example: |
||||||
|
* <pre>plFileName::Join("C:\\Path", "Filename.ext") => "C:\\Path\\Filename.ext"</pre> |
||||||
|
*/ |
||||||
|
static plFileName Join(const plFileName &base, const plFileName &path); |
||||||
|
|
||||||
|
/** Join three path components together with the correct path separator.
|
||||||
|
* \todo Make this more efficient. |
||||||
|
*/ |
||||||
|
static plFileName Join(const plFileName &base, const plFileName &path, |
||||||
|
const plFileName& path2) |
||||||
|
{ return Join(Join(base, path), path2); } |
||||||
|
|
||||||
|
/** Join four path components together with the correct path separator.
|
||||||
|
* \todo Make this more efficient. |
||||||
|
*/ |
||||||
|
static plFileName Join(const plFileName &base, const plFileName &path, |
||||||
|
const plFileName& path2, const plFileName &path3) |
||||||
|
{ return Join(Join(Join(base, path), path2), path3); } |
||||||
|
|
||||||
|
private: |
||||||
|
plString fName; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
/** Structure to get information about a file by name.
|
||||||
|
* \sa plFileName |
||||||
|
*/ |
||||||
|
class plFileInfo |
||||||
|
{ |
||||||
|
public: |
||||||
|
/** Construct an invalid plFileInfo which points to no file. */ |
||||||
|
plFileInfo() |
||||||
|
: fFileSize(-1), fCreateTime(), fModifyTime(), fFlags() { } |
||||||
|
|
||||||
|
/** Construct a plFileInfo and fill it with info about the specified
|
||||||
|
* file, if it exists. |
||||||
|
*/ |
||||||
|
explicit plFileInfo(const plFileName &filename); |
||||||
|
|
||||||
|
/** Retrieve the filename associated with this info structure. */ |
||||||
|
const plFileName &FileName() const { return fName; } |
||||||
|
|
||||||
|
/** Return whether the plFileInfo has been initialized. */ |
||||||
|
bool IsValid() const { return fName.IsValid(); } |
||||||
|
|
||||||
|
/** Determine whether the file exists on the filesystem. */ |
||||||
|
bool Exists() const { return (fFlags & kEntryExists); } |
||||||
|
|
||||||
|
/** Returns the size of the file on the disk, in bytes. */ |
||||||
|
int64_t FileSize() const { return fFileSize; } |
||||||
|
|
||||||
|
/** Returns the creation time of the file. */ |
||||||
|
uint64_t CreateTime() const { return fCreateTime; } |
||||||
|
|
||||||
|
/** Returns the last modification time of the file. */ |
||||||
|
uint64_t ModifyTime() const { return fModifyTime; } |
||||||
|
|
||||||
|
/** Returns \p true if this file is a directory. */ |
||||||
|
bool IsDirectory() const { return (fFlags & kIsDirectory); } |
||||||
|
|
||||||
|
/** Returns \p true if this file is a regular file. */ |
||||||
|
bool IsFile() const { return (fFlags & kIsNormalFile); } |
||||||
|
|
||||||
|
private: |
||||||
|
plFileName fName; |
||||||
|
int64_t fFileSize; |
||||||
|
uint64_t fCreateTime, fModifyTime; |
||||||
|
|
||||||
|
enum { |
||||||
|
kEntryExists = (1<<0), |
||||||
|
kIsDirectory = (1<<1), |
||||||
|
kIsNormalFile = (1<<2), |
||||||
|
}; |
||||||
|
uint32_t fFlags; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
namespace plFileSystem |
||||||
|
{ |
||||||
|
/** Get the current working directory of the application. */ |
||||||
|
plFileName GetCWD(); |
||||||
|
|
||||||
|
/** Open a file using the correct platform fopen API. */ |
||||||
|
FILE *Open(const plFileName &filename, const char *mode); |
||||||
|
|
||||||
|
/** Delete a file from the filesystem. */ |
||||||
|
bool Unlink(const plFileName &filename); |
||||||
|
|
||||||
|
/** Move or rename a file. */ |
||||||
|
bool Move(const plFileName &from, const plFileName &to); |
||||||
|
|
||||||
|
/** Copy a file to a new location. */ |
||||||
|
bool Copy(const plFileName &from, const plFileName &to); |
||||||
|
|
||||||
|
/** Create a directory. If \a checkParents is \p true, this will also
|
||||||
|
* check the whole path and create any parent directories as needed. |
||||||
|
*/ |
||||||
|
bool CreateDir(const plFileName &dir, bool checkParents = false); |
||||||
|
|
||||||
|
/** Get the User's data directory. If it doesn't exist, this will
|
||||||
|
* create it. |
||||||
|
*/ |
||||||
|
plFileName GetUserDataPath(); |
||||||
|
|
||||||
|
/** Get the Init script direcotory. If it doesn't exist, this will
|
||||||
|
* create it. */ |
||||||
|
plFileName GetInitPath(); |
||||||
|
|
||||||
|
/** Get the Log output directory. If it doesn't exist, this will
|
||||||
|
* create it. */ |
||||||
|
plFileName GetLogPath(); |
||||||
|
} |
||||||
|
|
||||||
|
#endif // plFileSystem_Defined
|
Loading…
Reference in new issue