summaryrefslogtreecommitdiff
path: root/source/modules/asura-utils/IO/FileSystem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/modules/asura-utils/IO/FileSystem.cpp')
-rw-r--r--source/modules/asura-utils/IO/FileSystem.cpp198
1 files changed, 198 insertions, 0 deletions
diff --git a/source/modules/asura-utils/IO/FileSystem.cpp b/source/modules/asura-utils/IO/FileSystem.cpp
new file mode 100644
index 0000000..9d0acf0
--- /dev/null
+++ b/source/modules/asura-utils/IO/FileSystem.cpp
@@ -0,0 +1,198 @@
+#include <physfs/physfs.h>
+
+#include "../exceptions/exception.h"
+
+#include "File.h"
+#include "FileData.h"
+#include "FileSystem.h"
+
+using namespace std;
+
+namespace AsuraEngine
+{
+ namespace IO
+ {
+
+#ifdef ASURA_WINDOWS
+ #include <windows.h>
+ #include <direct.h>
+#else
+ #include <sys/param.h>
+ #include <unistd.h>
+#endif
+
+ Filesystem::~Filesystem()
+ {
+ if (m_Inited) //PHYSFS_isInit
+ PHYSFS_deinit();
+ }
+
+ void Filesystem::Init(const char* arg0)
+ {
+ if (!PHYSFS_init(arg0))
+ throw Exception("Failed to initialize filesystem: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
+
+ m_Inited = true;
+ }
+
+ bool Filesystem::Mount(const std::string& locpath, const std::string& montpoint/* = "/"*/, bool prepend /*= false*/)
+ {
+ if (!m_Inited)
+ return false;
+
+ return PHYSFS_mount(locpath.c_str(), montpoint.c_str(), !prepend);
+ }
+
+ bool Filesystem::Mount(DataBuffer* db, const std::string& archivename, const std::string& mountpoint /*= "/"*/, bool prepend /*= false*/)
+ {
+ if (!m_Inited)
+ return false;
+ if (PHYSFS_mountMemory(db->GetData(), db->GetSize(), nullptr, archivename.c_str(), mountpoint.c_str(), !prepend))
+ {
+ m_MountData[archivename] = db;
+ return true;
+ }
+ return false;
+ }
+
+ bool Filesystem::Unmount(const std::string& locpath)
+ {
+ if (!m_Inited)
+ return false;
+
+ // ǹ鵵ӳɾ
+ auto datait = m_MountData.find(locpath);
+ if (datait != m_MountData.end() && PHYSFS_unmount(locpath.c_str()) != 0)
+ {
+ m_MountData.erase(datait);
+ return true;
+ }
+
+ return PHYSFS_unmount(locpath.c_str());
+ }
+
+ bool Filesystem::Unmount(DataBuffer* db)
+ {
+ for (const auto& dp : m_MountData)
+ {
+ if (dp.second == db)
+ {
+ std::string archive = dp.first;
+ return Unmount(archive);
+ }
+ }
+ }
+
+ bool Filesystem::GetMountPoint(const std::string& locpath, ASURA_OUT std::string& mountpoint)
+ {
+ if (!m_Inited)
+ return false;
+ const char* point = PHYSFS_getMountPoint(locpath.c_str());
+ if (point != nullptr)
+ {
+ mountpoint = point;
+ return true;
+ }
+ return false;
+ }
+
+ void Filesystem::SetWriteDirectory(const std::string locpath)
+ {
+ if (!m_Inited)
+ return;
+ if (!PHYSFS_setWriteDir(locpath.c_str()))
+ throw Exception("Failed to set write directory %s", locpath.c_str());
+ }
+
+ std::string Filesystem::GetWriteDirectory()
+ {
+ return PHYSFS_getWriteDir();
+ }
+
+ File* Filesystem::NewFile(const std::string& name)
+ {
+ return new File(name);
+ }
+
+ bool Filesystem::NewDirectory(const std::string& path)
+ {
+ if (!m_Inited)
+ return false;
+ if (!PHYSFS_getWriteDir())
+ return false;
+ if (!PHYSFS_mkdir(path.c_str()))
+ return false;
+ return true;
+ }
+
+ bool Filesystem::Write(const std::string& name, ASURA_REF DataBuffer* buffer)
+ {
+ File file(name);
+ file.Open(File::FILE_MODE_WRITE);
+ if (!file.Write(buffer))
+ throw Exception("Data could not be written.");
+ }
+
+ bool Filesystem::Append(const std::string& name, ASURA_REF DataBuffer* buffer)
+ {
+ File file(name);
+ file.Open(File::FILE_MODE_APPEND);
+ if (!file.Write(buffer))
+ throw Exception("Data could not be append.");
+ }
+
+ FileData* Filesystem::Read(const std::string& name)
+ {
+ File file = File(name);
+ file.Open(File::FILE_MODE_READ);
+ int size = file.GetSize();
+ DataBuffer* db = new DataBuffer(size);
+ if (db)
+ {
+ file.ReadAll(db);
+ FileData* fd = new FileData(name);
+ fd->BindData(db);
+ return fd;
+ }
+ return nullptr;
+ }
+
+ bool Filesystem::Remove(const std::string& path)
+ {
+ if (!m_Inited)
+ return false;
+ if (PHYSFS_getWriteDir() == 0)
+ return false;
+
+ if (!PHYSFS_delete(path.c_str()))
+ return false;
+
+ return true;
+ }
+
+ bool Filesystem::GetFileInfo(const std::string& filepath, ASURA_OUT FileInfo* info)
+ {
+ if (!m_Inited)
+ return false;
+
+ PHYSFS_Stat stat = {};
+ if (!PHYSFS_stat(filepath.c_str(), &stat))
+ return false;
+
+ info->size = (int64)stat.filesize;
+ info->modtime = (int64)stat.modtime;
+
+ if (stat.filetype == PHYSFS_FILETYPE_REGULAR)
+ info->type = FILE_TYPE_FILE;
+ else if (stat.filetype == PHYSFS_FILETYPE_DIRECTORY)
+ info->type = FILE_TYPE_DIRECTORY;
+ else if (stat.filetype == PHYSFS_FILETYPE_SYMLINK)
+ info->type = FILE_TYPE_SYMLINK;
+ else
+ info->type = FILE_TYPE_OTHER;
+
+ return true;
+ }
+
+ }
+} \ No newline at end of file