You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
346 lines
12 KiB
346 lines
12 KiB
/*==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> |
|
#include <cstddef> |
|
|
|
#include "plFormat.h" |
|
|
|
#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); } |
|
|
|
/** Append UTF-8 data from a C-style string pointer to the end of this |
|
* filename object. Not to be confused with Join() -- do not use this |
|
* for joining path components, or you will be shot by Zrax. |
|
*/ |
|
plFileName &operator+=(const char *cstr) { return operator=(fName + cstr); } |
|
|
|
/** Append the string \a str to the end of this filename object. |
|
* Not to be confused with Join() -- do not use this for joining path |
|
* components, or you will be shot by Zrax. |
|
*/ |
|
plFileName &operator+=(const plString &str) { return operator=(fName + str); } |
|
|
|
private: |
|
plString fName; |
|
|
|
// See the comments in plString's nullptr_t constructors for more info: |
|
plFileName(std::nullptr_t) { } |
|
void operator=(std::nullptr_t) { } |
|
void operator==(std::nullptr_t) const { } |
|
void operator!=(std::nullptr_t) const { } |
|
}; |
|
|
|
/** Concatentate a plFileName with a string constant. Not to be confused with |
|
* plFileName::Join() -- do not use this for joining path components, or you |
|
* will be shot by Zrax. |
|
*/ |
|
inline plFileName operator+(const plFileName &left, const char *right) |
|
{ return left.AsString() + right; } |
|
|
|
/** Concatentate a plFileName with a string constant. Not to be confused with |
|
* plFileName::Join() -- do not use this for joining path components, or you |
|
* will be shot by Zrax. |
|
*/ |
|
inline plFileName operator+(const char *left, const plFileName &right) |
|
{ return left + right.AsString(); } |
|
|
|
|
|
// Shortcut for use in plFormat |
|
PL_FORMAT_TYPE(const plFileName &) |
|
|
|
|
|
/** 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) != 0; } |
|
|
|
/** Returns \p true if this file is a regular file. */ |
|
bool IsFile() const { return (fFlags & kIsNormalFile) != 0; } |
|
|
|
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(); |
|
|
|
/** Change the current working directory. */ |
|
bool SetCWD(const plFileName &cwd); |
|
|
|
/** 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); |
|
|
|
/** Fetch a list of files contained in the supplied \a path. |
|
* If \a pattern is specified (e.g. "*.tmp"), use that to filter |
|
* matches. Otherwise, all files in the path will be returned. |
|
* Note that returned filenames include the provided path -- to |
|
* get only the filename, call .GetFileName() on an entry. |
|
*/ |
|
std::vector<plFileName> ListDir(const plFileName &path, |
|
const char *pattern = nullptr); |
|
|
|
/** Fetch a list of subdirectories in the specified \a path. |
|
* The returned list does not include the "." or ".." entries. |
|
*/ |
|
std::vector<plFileName> ListSubdirs(const plFileName &path); |
|
|
|
/** 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(); |
|
|
|
/** Get the full path and filename of the current process. */ |
|
plFileName GetCurrentAppPath(); |
|
|
|
/** Convert a file size from bytes to a human readable size. */ |
|
plString ConvertFileSize(uint64_t size); |
|
} |
|
|
|
#endif // plFileSystem_Defined
|
|
|