Last active
February 27, 2020 16:29
-
-
Save averne/9dd7d59d3ea9c988d1fb11ea1e583508 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <cstdint> | |
#include <string> | |
#include <vector> | |
#include <switch.h> | |
#include "error.hpp" | |
#include "utils.hpp" | |
namespace nq::fs { | |
class Directory { | |
public: | |
constexpr inline Directory() = default; | |
constexpr inline Directory(const FsDir &handle): handle(handle) { } | |
inline Directory(FsFileSystem *fs, const std::string &path) { | |
R_TRY_LOG(open(fs, path)); | |
} | |
inline Result open(FsFileSystem *fs, const std::string &path) { | |
auto tmp = path; | |
tmp.reserve(FS_MAX_PATH); // Fails otherwise | |
return fsFsOpenDirectory(fs, tmp.c_str(), FsDirOpenMode_ReadDirs | FsDirOpenMode_ReadFiles, &this->handle); | |
} | |
inline void close() { | |
if (this->handle.s.session) | |
fsDirClose(&this->handle); | |
} | |
inline std::size_t count() { | |
s64 count = 0; | |
R_TRY_LOG(fsDirGetEntryCount(&this->handle, &count)); | |
return count; | |
} | |
std::vector<FsDirectoryEntry> list() { | |
s64 total = 0; | |
auto c = count(); | |
auto entries = std::vector<FsDirectoryEntry>(c); | |
R_TRY_LOG(fsDirRead(&this->handle, &total, c, entries.data())); | |
return entries; | |
} | |
protected: | |
FsDir handle = {}; | |
}; | |
class File { | |
public: | |
constexpr inline File() = default; | |
constexpr inline File(const FsFile &handle): handle(handle) { } | |
inline File(FsFileSystem *fs, const std::string &path, u32 mode = FsOpenMode_Read) { | |
R_TRY_LOG(open(fs, path, mode)); | |
} | |
inline Result open(FsFileSystem *fs, const std::string &path, u32 mode = FsOpenMode_Read) { | |
auto tmp = path; | |
tmp.reserve(FS_MAX_PATH); | |
return fsFsOpenFile(fs, tmp.c_str(), mode, &this->handle); | |
} | |
inline void close() { | |
if (this->handle.s.session) | |
fsFileClose(&this->handle); | |
} | |
inline std::size_t size() { | |
s64 tmp = 0; | |
R_TRY_LOG(fsFileGetSize(&this->handle, &tmp)); | |
return tmp; | |
} | |
inline void size(std::size_t size) { | |
R_TRY_LOG(fsFileSetSize(&this->handle, static_cast<s64>(size))); | |
} | |
inline std::size_t read(void *buf, std::size_t size, std::size_t offset = 0) { | |
u64 tmp = 0; | |
R_TRY_LOG(fsFileRead(&this->handle, static_cast<s64>(offset), buf, static_cast<u64>(size), FsReadOption_None, &tmp)); | |
return tmp; | |
} | |
inline void write(const void *buf, std::size_t size, std::size_t offset = 0) { | |
R_TRY_LOG(fsFileWrite(&this->handle, static_cast<s64>(offset), buf, size, FsWriteOption_None)); | |
} | |
inline void flush() { | |
R_TRY_LOG(fsFileFlush(&this->handle)); | |
} | |
protected: | |
FsFile handle = {}; | |
}; | |
class Filesystem { | |
public: | |
constexpr inline Filesystem() = default; | |
constexpr inline Filesystem(const FsFileSystem &handle): handle(handle) { } | |
inline Filesystem(FsBisPartitionId id) { | |
R_TRY_LOG(fsOpenBisFileSystem(&this->handle, id, "")); | |
} | |
static inline Filesystem sdmc() { | |
Filesystem fs; | |
R_TRY_LOG(fsOpenSdCardFileSystem(&fs.handle)); | |
return fs; | |
} | |
inline void close() { | |
fsFsClose(&this->handle); | |
} | |
inline std::size_t total_space() { | |
s64 tmp = 0; | |
R_TRY_LOG(fsFsGetTotalSpace(&this->handle, "/", &tmp)); | |
return tmp; | |
} | |
inline std::size_t free_space() { | |
s64 tmp = 0; | |
R_TRY_LOG(fsFsGetFreeSpace(&this->handle, "/", &tmp)); | |
return tmp; | |
} | |
inline Directory open_directory(const std::string &path) { | |
return Directory(&this->handle, path); | |
} | |
inline File open_file(const std::string &path, std::uint32_t mode = FsOpenMode_Read) { | |
return File(&this->handle, path, mode); | |
} | |
inline Result create_directory(const std::string &path) { | |
return fsFsCreateDirectory(&this->handle, path.c_str()); | |
} | |
inline Result create_file(const std::string &path, std::size_t size) { | |
return fsFsCreateFile(&this->handle, path.c_str(), static_cast<s64>(size), 0); | |
} | |
bool is_directory(const std::string &path) { | |
Directory d; | |
bool res = d.open(&this->handle, path); | |
d.close(); | |
return res; | |
} | |
bool is_file(const std::string &path) { | |
File f; | |
bool res = f.open(&this->handle, path); | |
f.close(); | |
return res; | |
} | |
inline FsTimeStampRaw get_timestamp(const std::string &path) { | |
FsTimeStampRaw ts = {}; | |
R_TRY_LOG(fsFsGetFileTimeStampRaw(&this->handle, path.c_str(), &ts)); | |
return ts; | |
} | |
inline std::uint64_t get_timestamp_created(const std::string &path) { | |
return get_timestamp(path).created; | |
} | |
inline std::uint64_t get_timestamp_modified(const std::string &path) { | |
return get_timestamp(path).modified; | |
} | |
inline Result move_directory(const std::string &old_path, const std::string &new_path) { | |
return fsFsRenameDirectory(&this->handle, old_path.c_str(), new_path.c_str()); | |
} | |
inline Result move_file(const std::string &old_path, const std::string &new_path) { | |
return fsFsRenameFile(&this->handle, old_path.c_str(), new_path.c_str()); | |
} | |
inline Result delete_directory(const std::string &path) { | |
return fsFsDeleteDirectoryRecursively(&this->handle, path.c_str()); | |
} | |
inline Result delete_file(const std::string &path) { | |
return fsFsDeleteFile(&this->handle, path.c_str()); | |
} | |
private: | |
FsFileSystem handle = {}; | |
}; | |
} // namespace nq::fs |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment