Browse Source

use MountPoint in Filesystem

mikymod 12 years ago
parent
commit
248b6aadac
2 changed files with 92 additions and 164 deletions
  1. 71 104
      engine/core/filesystem/Filesystem.cpp
  2. 21 60
      engine/core/filesystem/Filesystem.h

+ 71 - 104
engine/core/filesystem/Filesystem.cpp

@@ -29,17 +29,18 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "OS.h"
 #include "DiskFile.h"
 #include "Memory.h"
+#include "Hash.h"
+#include "DiskMountPoint.h"
+
 
 namespace crown
 {
 
 //-----------------------------------------------------------------------------
-Filesystem::Filesystem(const char* root_path)
+Filesystem::Filesystem() :
+	m_mount_point_head(NULL)
 {
-	CE_ASSERT(root_path != NULL, "Root path must be != NULL");
-	CE_ASSERT(os::is_absolute_path(root_path), "Root path must be absolute");
 
-	string::strncpy(m_root_path, root_path, MAX_PATH_LENGTH);
 }
 
 //-----------------------------------------------------------------------------
@@ -48,158 +49,124 @@ Filesystem::~Filesystem()
 }
 
 //-----------------------------------------------------------------------------
-const char* Filesystem::root_path() const
+void Filesystem::mount(MountPoint& mp)
 {
-	return m_root_path;
+	if (m_mount_point_head != NULL)
+	{
+		mp.m_next = m_mount_point_head; 
+	}
+
+	m_mount_point_head = ∓
 }
 
 //-----------------------------------------------------------------------------
-const char* Filesystem::build_os_path(const char* base_path, const char* relative_path)
+void Filesystem::umount(MountPoint& mp)
 {
-	static char os_path[MAX_PATH_LENGTH];
+	MountPoint* current = m_mount_point_head;
+	MountPoint* previous;
+	MountPoint* tmp;
+	(void)tmp;
 
-	string::strncpy(os_path, base_path, MAX_PATH_LENGTH);
+	if (&mp == current)
+	{	
+		tmp = current;
 
-	size_t base_path_len = string::strlen(base_path);
+		current = current->m_next;
 
-	os_path[base_path_len] = PATH_SEPARATOR;
-	os_path[base_path_len + 1] = '\0';
+		tmp = NULL;
 
-	string::strcat(os_path, relative_path);
-
-	// FIXME FIXME FIXME Replace Crown-specific path separator with OS-speficic one
-	for (size_t j = 0; j < string::strlen(os_path); j++)
+		return;
+	}
+	else
 	{
-		if (os_path[j] == '/')
+		previous = current;
+		current = current->m_next;
+
+		while (current != NULL && &mp != current)
 		{
-			os_path[j] = PATH_SEPARATOR;
+			previous = current;
+
+			current = current->m_next;
 		}
-	}
 
-	return os_path;
+		if (current != NULL)
+		{
+			tmp = current;
+
+			previous->m_next = current->m_next;
+
+			tmp = NULL;
+
+			return;
+		}
+	}
 }
 
 //-----------------------------------------------------------------------------
-bool Filesystem::get_info(const char* relative_path, FilesystemEntry& info)
+File* Filesystem::open(const char* mount_point, const char* relative_path, FileOpenMode mode)
 {
-	// Entering OS-DEPENDENT-PATH-MODE
-	// (i.e. os_path is of the form: C:\foo\relative_path or /foo/relative_path)
-
-	const char* os_path = build_os_path(m_root_path, relative_path);
-	
-	string::strncpy(info.os_path, os_path, MAX_PATH_LENGTH);
-	string::strncpy(info.relative_path, relative_path, MAX_PATH_LENGTH);
+	MountPoint* mp = find_mount_point(mount_point);
 
-	if (os::is_reg(os_path))
-	{
-		info.type = FilesystemEntry::FILE;
-		return true;
-	}
-	else if (os::is_dir(os_path))
+	if (mp)
 	{
-		info.type = FilesystemEntry::DIRECTORY;
-		return true;
+		return mp->open(relative_path, mode);
 	}
-	
-	info.type = FilesystemEntry::UNKNOWN;
 
-	return false;
+	return NULL;
 }
 
 //-----------------------------------------------------------------------------
-bool Filesystem::exists(const char* relative_path)
+void Filesystem::close(File* file)
 {
-	FilesystemEntry dummy;
-
-	return get_info(relative_path, dummy);
+	CE_DELETE(m_allocator, file);
 }
 
 //-----------------------------------------------------------------------------
-bool Filesystem::is_file(const char* relative_path)
+bool Filesystem::exists(const char* mount_point, const char* relative_path)
 {
-	FilesystemEntry info;
+	MountPoint* mp = find_mount_point(mount_point);
 
-	if (get_info(relative_path, info))
+	if (mp)
 	{
-		return info.type == FilesystemEntry::FILE;
+		return mp->exists(relative_path);
 	}
 
 	return false;
 }
 
 //-----------------------------------------------------------------------------
-bool Filesystem::is_dir(const char* relative_path)
+const char* Filesystem::os_path(const char* mount_point, const char* relative_path)
 {
-	FilesystemEntry info;
+	MountPoint* mp = find_mount_point(mount_point);
 
-	if (get_info(relative_path, info))
+	if (mp)
 	{
-		return info.type == FilesystemEntry::DIRECTORY;
+		return ((DiskMountPoint*)mp)->os_path(relative_path);
 	}
 
-	return false;
+	return NULL;
 }
 
 //-----------------------------------------------------------------------------
-bool Filesystem::create_file(const char* relative_path)
+MountPoint*	Filesystem::find_mount_point(const char* mount_point)
 {
-	const char* os_path = build_os_path(m_root_path, relative_path);
+	MountPoint* curr = m_mount_point_head;
 
-	return os::mknod(os_path);
-}
-
-//-----------------------------------------------------------------------------
-bool Filesystem::create_dir(const char* relative_path)
-{
-	const char* os_path = build_os_path(m_root_path, relative_path);
-
-	return os::mkdir(os_path);
-}
+	uint32_t type_hash = hash::murmur2_32(mount_point, string::strlen(mount_point), 0);
 
-//-----------------------------------------------------------------------------
-bool Filesystem::delete_file(const char* relative_path)
-{
-	const char* os_path = build_os_path(m_root_path, relative_path);
-
-	return os::unlink(os_path);
-}
-
-//-----------------------------------------------------------------------------
-bool Filesystem::delete_dir(const char* relative_path)
-{
-	const char* os_path = build_os_path(m_root_path, relative_path);
-
-	return os::rmdir(os_path);
-}
-
-//-----------------------------------------------------------------------------
-const char* Filesystem::os_path(const char* relative_path)
-{
-	static char os_path[MAX_PATH_LENGTH];
-
-	FilesystemEntry entry;
-
-	get_info(relative_path, entry);
-
-	string::strncpy(os_path, entry.os_path, MAX_PATH_LENGTH);
-
-	return os_path;
-}
+	while(curr != NULL)
+	{
+		if (curr->type() == type_hash)
+		{
+			return curr;
+		}
 
-//-----------------------------------------------------------------------------
-DiskFile* Filesystem::open(const char* relative_path, FileOpenMode mode)
-{
-	CE_ASSERT(exists(relative_path), "File does not exist: %s", relative_path);
-	CE_ASSERT(is_file(relative_path), "File is not a regular file: %s", relative_path);
+		curr = curr->m_next;
+	}
 
-	return CE_NEW(m_allocator, DiskFile)(mode, os_path(relative_path));
+	return NULL;
 }
 
-//-----------------------------------------------------------------------------
-void Filesystem::close(DiskFile* stream)
-{
-	CE_DELETE(m_allocator, stream);
-}
 
 } // namespace crown
 

+ 21 - 60
engine/core/filesystem/Filesystem.h

@@ -30,28 +30,12 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "OS.h"
 #include "File.h"
 #include "HeapAllocator.h"
+#include "MountPoint.h"
 
 namespace crown
 {
 
-struct FilesystemEntry
-{
-	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
-	};
-
-	FilesystemEntry() : type(UNKNOWN) {}
-
-	Type			type;								///< Type of the entry
-	char			os_path[MAX_PATH_LENGTH];			///< OS-specific path (use only for debug)
-	char			relative_path[MAX_PATH_LENGTH];		///< Relative path of the entry
-};
-
-class DiskFile;
+class File;
 
 /// Provides a platform-independent way to access files and directories
 /// on the host filesystem.
@@ -102,64 +86,41 @@ class Filesystem
 {
 public:
 
-	/// The @a root_path must be absolute.
-						Filesystem(const char* root_path);
+						Filesystem();
 						~Filesystem();
 
-	/// Returns the root path of the filesystem
-	const char*			root_path() const;
-
-	/// Returns whether the @a relative_path exists and fills @a info with
-	/// with informations about the given @a relative_path path
-	bool				get_info(const char* relative_path, FilesystemEntry& info);
-	
-	/// Returns whether the @a relative_path exists on disk
-	bool				exists(const char* relative_path);
-
-	/// Returns whether @a relative_path is a regular file
-	bool				is_file(const char* relative_path);
-
-	/// Returns whether @a relative_path is a directory
-	bool				is_dir(const char* relative_path);
-
-	/// Creates a regular file named @a relative_path
-	bool				create_file(const char* relative_path);
-
-	/// Creates a directory named @a relative_path
-	bool				create_dir(const char* relative_path);
-
-	/// Deletes the regular file @a relative_path
-	bool				delete_file(const char* relative_path);
+	///
+	void				mount(MountPoint& mp);
 
-	/// Deletes the directory @a relative_path
-	bool				delete_dir(const char* relative_path);
-
-	/// Returns the os-specific path which @a relative_path refers to.
-	/// @note
-	/// In general, you typically do not want to use it for normal
-	/// file interactions. Prefer using the other methods whenever possible.
-	const char*			os_path(const char* relative_path);
+	///
+	void				umount(MountPoint& mp);
 
 	/// Opens the file @a relative_path with the specified access @a mode
-	DiskFile*			open(const char* relative_path, FileOpenMode mode);
+	/// contained in @a mount_point
+	File*				open(const char* mount_point, const char* relative_path, FileOpenMode mode);
 
 	/// Closes a previously opened file @a stream
-	void				close(DiskFile* stream);
+	void				close(File* stream);
+
+	bool				exists(const char* mount_point, const char* relative_path);
+
+	const char*			os_path(const char* mount_point, const char* relative_path);
 
 private:
+	/// Gets __first__ mount point fetchable by @a mount_point
+	MountPoint*			find_mount_point(const char* mount_point);				
 
-	// Builds the OS-dependent path from base_path and relative_path
-	const char*			build_os_path(const char* base_path, const char* relative_path);
-	
+	// Disable copying
+						Filesystem(const Filesystem&);
+	Filesystem&			operator=(const Filesystem&);	
 private:
 
 	HeapAllocator		m_allocator;
 
 	char				m_root_path[MAX_PATH_LENGTH];
 
-	// Disable copying
-						Filesystem(const Filesystem&);
-	Filesystem&			operator=(const Filesystem&);
+	MountPoint* 		m_mount_point_head;
+
 
 	friend class		Device;
 };