diff options
Diffstat (limited to 'Source/modules/asura-base/FileSystem/FileManager.cpp')
-rw-r--r-- | Source/modules/asura-base/FileSystem/FileManager.cpp | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/Source/modules/asura-base/FileSystem/FileManager.cpp b/Source/modules/asura-base/FileSystem/FileManager.cpp new file mode 100644 index 0000000..bdb4069 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/FileManager.cpp @@ -0,0 +1,198 @@ +#include <physfs/physfs.h> + +#include "../Exception.h" + +#include "File.h" +#include "FileData.h" +#include "FileManager.h" + +using namespace std; + +namespace AsuraEngine +{ + namespace FileSystem + { + +#ifdef ASURA_WINDOWS + #include <windows.h> + #include <direct.h> +#else + #include <sys/param.h> + #include <unistd.h> +#endif + + FileManager::~FileManager() + { + if (m_Inited) //PHYSFS_isInit + PHYSFS_deinit(); + } + + void FileManager::Init(const char* arg0) + { + if (!PHYSFS_init(arg0)) + throw Exception("Failed to initialize filesystem: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); + + m_Inited = true; + } + + bool FileManager::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 FileManager::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 FileManager::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 FileManager::Unmount(DataBuffer* db) + { + for (const auto& dp : m_MountData) + { + if (dp.second == db) + { + std::string archive = dp.first; + return Unmount(archive); + } + } + } + + bool FileManager::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 FileManager::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 FileManager::GetWriteDirectory() + { + return PHYSFS_getWriteDir(); + } + + File* FileManager::NewFile(const std::string& name) + { + return new File(name); + } + + bool FileManager::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 FileManager::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 FileManager::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* FileManager::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 FileManager::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 FileManager::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 |