Przeglądaj źródła

Major changes in Filesystem

Daniele Bartolini 13 lat temu
rodzic
commit
0187bcb44a
2 zmienionych plików z 149 dodań i 605 usunięć
  1. 54 485
      src/Filesystem.cpp
  2. 95 120
      src/Filesystem.h

+ 54 - 485
src/Filesystem.cpp

@@ -38,10 +38,8 @@ namespace crown
 {
 {
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-Filesystem::Filesystem() :
-	mIsInit(false),
-	mRootPath(Str::EMPTY),
-	mUserPath(Str::EMPTY)
+Filesystem::Filesystem(const char* root_path) :
+	m_root_path(root_path)
 {
 {
 }
 }
 
 
@@ -51,119 +49,67 @@ Filesystem::~Filesystem()
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-void Filesystem::Init(const char* rootPath, const char* userPath)
+const char* Filesystem::root_path() const
 {
 {
-	assert(!mIsInit);
-
-	if (Str::StrCmp(rootPath, Str::EMPTY) == 0)
-	{
-		// Set working paths
-		const char* envRootPath = os::get_env("CROWN_ROOT_PATH");
-
-		if (envRootPath == Str::EMPTY)
-		{
-			mRootPath = os::get_cwd();
-		}
-		else
-		{
-			mRootPath = envRootPath;
-		}
-	}
-	else
-	{
-		mRootPath = rootPath;
-	}
-
-	if (userPath == Str::EMPTY)
-	{
-		mUserPath = os::get_home();
-	}
-	else
-	{
-		mUserPath = userPath;
-	}
-
-	Log::D("Filesystem::Init()");
-	Log::D("Filesystem: Root path: %s", mRootPath.c_str());
-	Log::D("Filesystem: User path: %s", mUserPath.c_str());
-
-	mIsInit = true;
-}
-
-//-----------------------------------------------------------------------------
-const char* Filesystem::GetRootPath() const
-{
-	return mRootPath.c_str();
+	return m_root_path;
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-const char* Filesystem::GetUserPath() const
+const char* Filesystem::build_os_path(const char* base_path, const char* relative_path)
 {
 {
-	return mUserPath.c_str();
-}
-
-//-----------------------------------------------------------------------------
-void Filesystem::SetUserPath(const char* relativePath)
-{
-	mUserPath = relativePath;
-}
-
-//-----------------------------------------------------------------------------
-const char* Filesystem::BuildOSPath(const char* basePath, const char* relativePath)
-{
-	static char osPath[1024];
+	static char os_path[1024];
 
 
 	size_t i = 0;
 	size_t i = 0;
 
 
-	while (*basePath != '\0')
+	while (*base_path != '\0')
 	{
 	{
-		osPath[i++] = *basePath;
-		basePath++;
+		os_path[i++] = *base_path;
+		base_path++;
 	}
 	}
 
 
-	osPath[i++] = '/';
+	os_path[i++] = '/';
 
 
-	while (*relativePath != '\0')
+	while (*relative_path != '\0')
 	{
 	{
-		osPath[i++] = *relativePath;
-		relativePath++;
+		os_path[i++] = *relative_path;
+		relative_path++;
 	}
 	}
 
 
-	osPath[i] = '\0';
+	os_path[i] = '\0';
 
 
 	// Replace Crown-specific path separator with OS-speficic one
 	// Replace Crown-specific path separator with OS-speficic one
 	for (size_t j = 0; j < i; j++)
 	for (size_t j = 0; j < i; j++)
 	{
 	{
-		if (osPath[j] == '/')
+		if (os_path[j] == '/')
 		{
 		{
-			osPath[j] = os::PATH_SEPARATOR;
+			os_path[j] = os::PATH_SEPARATOR;
 		}
 		}
 	}
 	}
 
 
-	return osPath;
+	return os_path;
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-bool Filesystem::GetInfo(const char* basePath, const char* relativePath, FilesystemEntry& info)
+bool Filesystem::get_info(const char* base_path, const char* relative_path, FilesystemEntry& info)
 {
 {
 	// Entering OS-DEPENDENT-PATH-MODE
 	// Entering OS-DEPENDENT-PATH-MODE
-	// (i.e. osPath is of the form: C:\babbeo\relativePath or /babbeo/relativePath)
+	// (i.e. os_path is of the form: C:\babbeo\relative_path or /babbeo/relative_path)
 
 
-	const char* osPath = BuildOSPath(basePath, relativePath);
+	const char* os_path = build_os_path(base_path, relative_path);
 
 
-	if (os::is_reg(osPath))
+	if (os::is_reg(os_path))
 	{
 	{
-		info.type			= FET_FILE;
-		info.osPath			= osPath;
-		info.relativePath	= relativePath;
+		info.type = FilesystemEntry::FILE;
+		string::strcpy(info.os_path, os_path);
+		string::strcpy(info.relative_path, relative_path);
 		return true;
 		return true;
 	}
 	}
 
 
-	if (os::is_dir(osPath))
+	if (os::is_dir(os_path))
 	{
 	{
-		info.type			= FET_DIR;
-		info.osPath			= osPath;
-		info.relativePath	= relativePath;
+		info.type = FilesystemEntry::DIRECTORY;
+		string::strcpy(info.os_path, os_path);
+		string::strcpy(info.relative_path, relative_path);
 		return true;
 		return true;
 	}
 	}
 
 
@@ -171,468 +117,91 @@ bool Filesystem::GetInfo(const char* basePath, const char* relativePath, Filesys
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-bool Filesystem::Exists(const char* relativePath)
+bool Filesystem::exists(const char* relative_path)
 {
 {
 	FilesystemEntry dummy;
 	FilesystemEntry dummy;
 
 
-	return GetInfo(mRootPath.c_str(), relativePath, dummy);
+	return get_info(m_root_path, relative_path, dummy);
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-bool Filesystem::IsFile(const char* relativePath)
+bool Filesystem::is_file(const char* relative_path)
 {
 {
 	FilesystemEntry info;
 	FilesystemEntry info;
 
 
-	if (GetInfo(mRootPath.c_str(), relativePath, info))
+	if (get_info(m_root_path, relative_path, info))
 	{
 	{
-		return info.type == FET_FILE;
+		return info.type == FilesystemEntry::FILE;
 	}
 	}
 
 
 	return false;
 	return false;
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-bool Filesystem::IsDir(const char* relativePath)
+bool Filesystem::is_dir(const char* relative_path)
 {
 {
 	FilesystemEntry info;
 	FilesystemEntry info;
 
 
-	if (GetInfo(mRootPath.c_str(), relativePath, info))
+	if (get_info(m_root_path, relative_path, info))
 	{
 	{
-		return info.type == FET_DIR;
+		return info.type == FilesystemEntry::DIRECTORY;
 	}
 	}
 
 
 	return false;
 	return false;
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-bool Filesystem::CreateFile(const char* relativePath)
+bool Filesystem::create_file(const char* relative_path)
 {
 {
-	const char* osPath = BuildOSPath(mRootPath.c_str(), relativePath);
+	const char* os_path = build_os_path(m_root_path, relative_path);
 
 
-	return os::mknod(osPath);
+	return os::mknod(os_path);
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-bool Filesystem::CreateDir(const char* relativePath)
+bool Filesystem::create_dir(const char* relative_path)
 {
 {
-	const char* osPath = BuildOSPath(mRootPath.c_str(), relativePath);
+	const char* os_path = build_os_path(m_root_path, relative_path);
 
 
-	return os::mkdir(osPath);
+	return os::mkdir(os_path);
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-bool Filesystem::DeleteFile(const char* relativePath)
+bool Filesystem::delete_file(const char* relative_path)
 {
 {
-	const char* osPath = BuildOSPath(mRootPath.c_str(), relativePath);
+	const char* os_path = build_os_path(m_root_path, relative_path);
 
 
-	return os::unlink(osPath);
+	return os::unlink(os_path);
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-bool Filesystem::DeleteDir(const char* relativePath)
+bool Filesystem::delete_dir(const char* relative_path)
 {
 {
-	const char* osPath = BuildOSPath(mRootPath.c_str(), relativePath);
+	const char* os_path = build_os_path(m_root_path, relative_path);
 
 
-	return os::rmdir(osPath);
+	return os::rmdir(os_path);
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-Stream* Filesystem::OpenStream(const char* relativePath, StreamOpenMode openMode)
+Stream* Filesystem::open(const char* relative_path, StreamOpenMode mode)
 {
 {
 	FilesystemEntry info;
 	FilesystemEntry info;
 	Stream* stream;
 	Stream* stream;
 
 
-	bool exists = GetInfo(mRootPath.c_str(), relativePath, info);
-
-	assert(exists == true && "Filesystem::OpenStream: File does not exist");
-	assert(info.type != FET_DIR && "Filesystem::OpenStream: Trying to open directory...");
+	get_info(m_root_path, relative_path, info);
 
 
-	if (info.type == FET_FILE)
-	{
-		Log::D("Filesystem::OpenStream: Found %s", info.osPath.c_str());
+	Log::D("Filesystem::OpenStream: Found %s", info.os_path);
 
 
-		stream = new FileStream(openMode, info.osPath.c_str());
+	stream = new FileStream(mode, info.os_path);
 
 
-		return stream;
-	}
-
-	return NULL;
-}
-
-/**
-	file must exists.
-*/
-Stream* Filesystem::OpenRead(const char* relativePath)
-{
-	(void)relativePath;
-	return NULL;
-}
-
-Stream* Filesystem::OperWrite(const char* relativePath)
-{
-	(void)relativePath;
-	return NULL;
-}
-
-Stream* Filesystem::OpenAppend(const char* relativePath)
-{
-	(void)relativePath;
-	return NULL;
+	return stream;
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-void Filesystem::Close(Stream* stream)
+void Filesystem::close(Stream* stream)
 {
 {
 	delete stream;
 	delete stream;
 }
 }
 
 
-//-----------------------------------------------------------------------------
-void Filesystem::Print32_tReport()
-{
-	Log::I("--- Filesystem report ---");
-	Log::I("Path separator\t: '/'");
-	Log::I("Root\t\t\t: %s", mRootPath.c_str());
-	Log::I("User\t\t\t: %s", mUserPath.c_str());
-}
-
-///**
-//	Returns whether the segment is valid.
-//@note
-//	The rules for valid segments are as follows:
-//	a) The empty string is not valid.
-//	b) Any string containing the slash character ('/') is not valid.
-//	c) Common notations for current ('.') and parent ('..') directory are forbidden.
-//	d) Any string containing segment or device separator characters on the local file system,
-//	such as the backslash ('\') and colon (':') on some file systems.
-//	(Thanks org.eclipse.core.runtime for the documentation ;D).
-//@param segment
-//	The segment to be checked
-//@return
-//	True if the segment is valid, false otherwise
-//*/
-//bool Filesystem::IsValidSegment(const char* segment)
-//{
-//	size_t segmentLen = Str::StrLen(segment);
-
-//	if (segmentLen == 0)
-//	{
-//		return false;
-//	}
-
-//	if (segmentLen == 1 && segment[0] == '.')
-//	{
-//		return false;
-//	}
-
-//	if (segmentLen == 2 && segment[0] == '.' && segment[1] == '.')
-//	{
-//		return false;
-//	}
-
-//	for (size_t i = 0; i < segmentLen; i++)
-//	{
-//		if (segment[i] == '/' ||
-//			segment[i] == '\\' ||
-//			segment[i] == ':'
-//		{
-//			return false;
-//		}
-//	}
-
-//	return true;
-//}
-
-///**
-//	Returns whether the path is valid.
-//@note
-//	The rules for valid paths are as follows:
-//	a) The empty string is not valid.
-//	b) If the path is absolute, it mustn't contain any leading character.
-//@param path
-//	The path to be checked
-//@return
-//	True if the path is valid, false otherwise
-//*/
-//bool Filesystem::IsValidPath(const char* path)
-//{
-//	size_t pathLen = Str::StrLen(path);
-
-//	if (pathLen == 0)
-//	{
-//		return false;
-//	}
-
-//	if (IsRootPath(path))
-//	{
-//		return true;
-//	}
-
-//	List<Str> segmentList;
-//	if (!GetSegments(Str(path), segmentList))
-//	{
-//		return false;
-//	}
-
-//	size_t i = 0;
-//	if (IsAbsolutePath(path) && path[0] != '/')
-//	{
-//		i = 1;
-//	}
-
-//	for (; i < segmentList.GetSize(); i++)
-//	{
-//		if (!IsValidSegment(segmentList[i].c_str()))
-//		{
-//			return false;
-//		}
-//	}
-
-//	return true;
-//}
-
-///**
-//	Returns whether the path is absolute.
-//@note
-//	(i.e. starts with Path::SEPARATOR or <a-Z><Path::DEVICE_SEPARATOR><Path::SEPARATOR>).
-//@param path
-//	The path to be checked
-//@return
-//	True if absolute, false otherwise
-//*/
-//bool Filesystem::IsAbsolutePath(const char* path)
-//{
-//	size_t pathLen;
-
-//	pathLen = Str::StrLen(path);
-
-//	if (pathLen == 0)
-//	{
-//		return false;
-//	}
-
-//	if (path[0] == '/')
-//	{
-//		return true;
-//	}
-
-//	if (pathLen < 3)
-//	{
-//		return false;
-//	}
-
-//	if (Str::IsAlpha(path[0]) && path[1] == ':' && path[2] == os::PATH_SEPARATOR)
-//	{
-//		return true;
-//	}
-
-//	return false;
-//}
-
-///**
-//	Returns whether the path is the root path.
-//@note
-//	(i.e. starts and ends with Path::SEPARATOR or <a-Z><Path::DEVICE_SEPARATOR><Path::SEPARATOR>).
-//@param path
-//	The path to be checked
-//@return
-//	True if root, false otherwise
-//*/
-//bool Filesystem::IsRootPath(const char* path)
-//{
-//	size_t pathLen;
-
-//	pathLen = Str::StrLen(path);
-
-//	if (pathLen == 0)
-//	{
-//		return false;
-//	}
-
-//	if (pathLen == 1 && path[0] == PATH_SEPARATOR)
-//	{
-//		return true;
-//	}
-
-//	if (pathLen == 3 && Str::IsAlpha(path[0]) && path[1] == DEVICE_SEPARATOR && path[2] == PATH_SEPARATOR)
-//	{
-//		return true;
-//	}
-
-//	return false;
-//}
-
-///**
-//	Returns the pathname of the path.
-//@note
-//	(e.g. /home/babbeo/texture.tga -> /home/babbeo).
-//@param path
-//	The input path
-//@param ret
-//	The output pathname
-//@return
-//	True if success, false otherwise
-//*/
-//const char* Filesystem::GetPathname(const char* path)
-//{
-//	size_t pathLen;
-
-//	pathLen = Str::StrLen(path);
-
-//	const char* c = path + pathLen - 1;
-
-//	// Ignore any trailing separators
-//	while (c > path && *c == PATH_SEPARATOR)
-//	{
-//		c--;
-//	}
-
-//	// Iterate backwards until first separator
-//	while (c > path && *c != PATH_SEPARATOR)
-//	{
-//		c--;
-//	}
-
-//	//return (c == path) ? c : c - 1;
-//	return (c == path) ? c + 2 : c;
-//}
-
-///**
-//	Returns the filename of the path.
-//@note
-//	(e.g. /home/babbeo/texture.tga -> texture.tga).
-//@param path
-//	The input path
-//@param ret
-//	The output filename
-//@return
-//	True if success, false otherwise
-//*/
-//bool Filesystem::GetFilename(const char* path, char* ret)
-//{
-//	if (IsRootPath(path.c_str()))
-//	{
-//		ret = Str("");
-//		return true;
-//	}
-
-//	RemoveTrailingSeparator(path, ret);
-
-//	if (ret.FindLast(PATH_SEPARATOR) != -1)
-//	{
-//		ret = path.GetSubstring(path.FindLast(PATH_SEPARATOR) + 1, path.GetLength());
-//	}
-
-//	return true;
-//}
-
-///**
-//	Returns the basename of the path.
-//@note
-//	(e.g. /home/babbeo/texture.tga -> texture).
-//@param path
-//	The input path
-//@param ret
-//	The output basename
-//@return
-//	True if success, false otherwise
-//*/
-//bool Filesystem::GetBasename(const char* path, char* ret)
-//{
-//	if (!GetFilename(path, ret))
-//	{
-//		return false;
-//	}
-
-//	if (ret.FindLast('.') != -1)
-//	{
-//		ret = ret.GetSubstring(0, ret.FindLast('.'));
-//	}
-
-//	return true;
-//}
-
-/**
-	Returns the extension of the path.
-@note
-	(e.g. /home/babbeo/texture.tga -> .tga).
-@param path
-	The input path
-@return
-	The extension.
-*/
-const char* Filesystem::GetExtension(const char* relativePath)
-{
-	assert(relativePath != NULL);
-
-	static char extension[32];
-
-	int32_t i = Str::FindLast(relativePath, '.');
-
-	if (i == -1)
-	{
-		return Str::EMPTY;
-	}
-
-	Str::StrCpy(extension, &relativePath[i]);
-
-	return extension;
-}
-
-///**
-//	Returns the segments contained in path.
-//@param path
-//	The input path
-//@param ret
-//	The output list containing path's segments
-//@return
-//	True if success, false otherwise
-//*/
-//bool Filesystem::GetSegments(const char* path, List<Str>& ret)
-//{
-//	path.Split(PATH_SEPARATOR, ret);
-
-//	if (ret.GetSize() > 0)
-//	{
-//		return true;
-//	}
-
-//	return false;
-//}
-
-///**
-//	Fills 'ret' with the same path but without the trailing directory separator.
-//@note
-//	(e.g. /home/babbeo/texture.tga/ -> /home/babbeo/texture.tga).
-//@param path
-//	The input path
-//@param ret
-//	The ouput path
-//@return
-//	True if success, false otherwise
-//*/
-//bool Filesystem::RemoveTrailingSeparator(const char* path, char* ret)
-//{
-//	if (path.GetLength() == 0 || IsRootPath(path.c_str()))
-//	{
-//		ret = path;
-//		return true;
-//	}
-
-//	if (path[path.GetLength() - 1] == PATH_SEPARATOR)
-//	{
-//		ret = path.GetSubstring(0, path.GetLength() - 1);
-//		return true;
-//	}
-
-//	ret = path;
-//	return true;
-//}
-
-Filesystem filesystem;
-Filesystem* GetFilesystem()
-{
-	return &filesystem;
-}
-
 } // namespace crown
 } // namespace crown
 
 

+ 95 - 120
src/Filesystem.h

@@ -25,148 +25,123 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 
 #pragma once
 #pragma once
 
 
-#include "Str.h"
-#include "List.h"
+#include "String.h"
 #include "Stream.h"
 #include "Stream.h"
-#include "Log.h"
 
 
 namespace crown
 namespace crown
 {
 {
 
 
-/**
-	Enumerates the filesystem's entry types
-*/
-enum FilesystemEntryType
-{
-	FET_DIR = 0,		//!< The entry is a directory
-	FET_FILE,			//!< The entry is a file
-	FET_MEM,			//!< The entry is a memory file (i.e. does not exist on the disk)
-	FET_UNKNOWN			//!< The entry type is unknown
-};
-
 struct FilesystemEntry
 struct FilesystemEntry
 {
 {
-	FilesystemEntry() : type(FET_UNKNOWN)
+	enum Type
 	{
 	{
-	}
+		DIRECTORY = 0,				///< The entry is a directory
+		FILE,						///< The entry is a file
+		MEMORY,						///< The entry is a memory file (i.e. does not exist on the disk)
+		UNKNOWN						///< The entry type is unknown
+	};
 
 
-	void Print32_tReport()
-	{
-		Log::I("OSPath\t\t: %s", osPath.c_str());
-		Log::I("RelPath\t\t: %s", relativePath.c_str());
-		Log::I("Type:\t\t: %s", ((type == FET_FILE) ? "file" : (type == FET_DIR) ? "dir" : "unknown"));
-	}
-
-	FilesystemEntryType	type;			//!< Type of the entry
-	Str					osPath;			//!< OS-specific path (use only for debug)
-	Str					relativePath;	//!< Relative path of the entry
+	FilesystemEntry() : type(UNKNOWN) {}
+
+	Type			type;				///< Type of the entry
+	char			os_path[512];		///< OS-specific path (use only for debug)
+	char			relative_path[512];	///< Relative path of the entry
 };
 };
 
 
-class Stream;
-
-/**
-	Virtual filesystem.
-
-	Provides a platform-independent way to access files and directories
-	on the host filesystem.
-
-	Accessing files:
-	Every file and every directory is accessed through the filesystem.
-	Not a single C/C++ std file io call should be used in any other part
-	of the engine in order to maint32_tain platform independence.
-
-	Pathnames:
-	Only unix-like pathnames (i.e. case sensitive and using '/' as separator)
-	are allowed.
-	Only relative paths are allowed: the filesystem is responsible for
-	the creation of its absolute platform-specific counterpart.
-
-	Filesystem forbids pathnames containing '.' and '..' to prevent access
-	to files outside the predefined directories.
-	Platform specific characters like '/', '\\' and ':' are forbidden as well.
-
-	Although mixed-case pathnames are allowed, it is generally safer to use
-	only lower-case ones for maximum compatibility.
-
-	Filesystem provides access to two main directories:
-		1) Root directory
-			it is the directory where all of the data came from.
-			Defaults to the directory where the executable is in
-			but can be overridden by the CROWN_ROOT_PATH environment
-			variable. The root directory is set only once at the
-			engine start and cannot be changed anymore.
-		2) User directory
-			defaults to the user home directory. Used to store user-specific
-			stuffs such as config files, screenshots, savegames ecc.
-*/
+/// Filesystem.
+///
+/// Provides a platform-independent way to access files and directories
+/// on the host filesystem.
+///
+/// Accessing files:
+/// Every file and every directory must be accessed through the Filesystem.
+/// Not a single C/C++ std file io call or other similar facilities
+/// should be used in any other part of the engine in order to maintain
+/// absolute platform independence.
+///
+/// Filesystem maintains a root path which acts as base directory for every
+/// file operation; access to files outside the root path is not allowed. If
+/// you really need it, instantiate another filesystem whith the appropriate
+/// root path (e.g.)
+///
+/// Filesystem fs("/home/foo"); // fs will use "/home/foo" as root path
+///
+/// fs.is_file("bar.txt");      // file "bar.txt" is relative to the root path,
+///                             // so it refers to "/home/foo/bar.txt"
+///
+/// The filesystem will take care of the necessary path conversions.
+/// The root path can be really anything: platform-specific/absolute/relative/whatever.
+/// Examples of valid root paths.
+///
+/// 1) "/home/foo"
+/// 2) "C:\Users\Phil"
+/// 3) "\abc$\/..)?/"
+///
+/// The relative paths must follow some strict rules:
+///
+/// a) Only unix-like pathnames (i.e. case sensitive and using '/' as separator)
+///    are allowed.
+/// b) Only relative paths are allowed: the filesystem is responsible for
+///    the creation of its absolute platform-specific counterpart.
+/// c) Filesystem forbids pathnames containing '.' and '..' to prevent access to
+///    files outside the filesystem's root path.
+/// d) Platform specific characters like '/', '\\' and ':' are forbidden as well.
+/// e) Symlinks, on platforms which support them, are _not_ resolved for the same
+///    reason of c)
+/// f) Although mixed-case pathnames are allowed, it is generally safer to use
+///    only lower-case ones for maximum compatibility.
+///
+/// Examples of valid relative paths.
+///
+/// data/textures/grass.texture
+/// grass.texture
+/// foo/bar
 class Filesystem
 class Filesystem
 {
 {
-
 public:
 public:
 
 
-						Filesystem();
+						Filesystem(const char* root_path);
 						~Filesystem();
 						~Filesystem();
 
 
-	void				Init(const char* rootPath, const char* userPath);
-
-	const char*			GetRootPath() const;
-	const char*			GetUserPath() const;
-
-	void				SetUserPath(const char* relativePath);
-
-	const char*			BuildOSPath(const char* basePath, const char* relativePath);
-
-	bool				GetInfo(const char* basePath, const char* relativePath, FilesystemEntry& info);
-	bool				Exists(const char* relativePath);
-
-	bool				IsFile(const char* relativePath);
-	bool				IsDir(const char* relativePath);
-
-	bool				CreateFile(const char* relativePath);
-	bool				CreateDir(const char* relativePath);
-
-	bool				DeleteFile(const char* relativePath);
-	bool				DeleteDir(const char* relativePath);
-
-	Stream*				OpenStream(const char* relativePath, StreamOpenMode openMode);
-	Stream*				OpenRead(const char* relativePath);
-	Stream*				OperWrite(const char* relativePath);
-	Stream*				OpenAppend(const char* relativePath);
-
-	void				Close(Stream* stream);
-
-	void				Print32_tReport();
-
-	static bool			IsValidSegment(const char* segment);
-	static bool			IsValidPath(const char* path);
-	static bool			IsAbsolutePath(const char* path);
-	static bool			IsRootPath(const char* path);
-
-//	static const char*	GetPathname(const char* path);
-//	static bool			GetFilename(const char* path, char* ret);
-//	static bool			GetBasename(const char* path, char* ret);
-	static const char*	GetExtension(const char* relativePath);
-//	static bool			GetSegments(const char* path, List<Str>& ret);
-
-//	static bool			RemoveTrailingSeparator(const char* path, char* ret);
-
+						/// Returns the root path of the filesystem
+	const char*			root_path() const;
+
+						/// TODO
+	bool				get_info(const char* base_path, const char* relative_path, FilesystemEntry& info);
+	
+						/// Returns whether the @relative_path exists on disk
+	bool				exists(const char* relative_path);
+
+						/// Returns whether @relative_path is a regular file
+	bool				is_file(const char* relative_path);
+						/// Returns whether @relative_path if a directory
+	bool				is_dir(const char* relative_path);
+
+						/// Creates a regular file named @relative_path
+	bool				create_file(const char* relative_path);
+						/// Creates a directory named @relative_path
+	bool				create_dir(const char* relative_path);
+
+						/// Deletes the regular file @relative_path
+	bool				delete_file(const char* relative_path);
+						/// Deletes the directory @relative_path
+	bool				delete_dir(const char* relative_path);
+
+	Stream*				open(const char* relative_path, StreamOpenMode mode);
+	void				close(Stream* stream);
+	
 private:
 private:
 
 
-	void				_SetRootPath(const char* relativePath) { mRootPath = relativePath; }
-
-	bool				mIsInit;
-
-	Str					mRootPath;			//!< The root path.
-	Str					mUserPath;			//!< Where user settings/saves/ecc. live in
+	const char*			build_os_path(const char* basePath, const char* relative_path);
+	
+private:
 
 
-	// Disable copying
-	Filesystem(const Filesystem&);
-	Filesystem& operator=(const Filesystem&);
+	const char*			m_root_path;
 
 
-	friend class		Device;
+						// Disable copying
+						Filesystem(const Filesystem&);
+	Filesystem&			operator=(const Filesystem&);
 };
 };
 
 
-Filesystem* GetFilesystem();
-
 } // namespace crown
 } // namespace crown