Skip to content

Instantly share code, notes, and snippets.

@averne
Last active February 27, 2020 16:29
Show Gist options
  • Save averne/9dd7d59d3ea9c988d1fb11ea1e583508 to your computer and use it in GitHub Desktop.
Save averne/9dd7d59d3ea9c988d1fb11ea1e583508 to your computer and use it in GitHub Desktop.
#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