This repository has been archived on 2022-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
Luma3DS-3GX/sysmodules/loader/source/file_util.h

77 lines
1.7 KiB
C
Raw Normal View History

#pragma once
#include <optional>
#include <string.h>
extern "C"
{
#include <3ds/result.h>
#include <3ds/services/fs.h>
#include <3ds/svc.h>
#include <3ds/types.h>
}
namespace util
{
inline FS_Path MakePath(const char *path)
{
return {PATH_ASCII, strnlen(path, 255) + 1, path};
}
// A small wrapper to make forgetting to close a file and
// to check read lengths impossible.
class File
{
public:
File() = default;
File(const File &other) = delete;
File &operator=(const File &) = delete;
File(File &&other) { *this = std::move(other); }
File &operator=(File &&other)
{
std::swap(m_handle, other.m_handle);
return *this;
}
~File() { Close(); }
bool Close()
{
const bool ok = !m_handle || R_SUCCEEDED(FSFILE_Close(*m_handle));
if(ok)
m_handle = std::nullopt;
return ok;
}
bool Open(const char *path, int open_flags)
{
const FS_Path archive_path = {PATH_EMPTY, 1, ""};
Handle handle;
const bool ok = R_SUCCEEDED(FSUSER_OpenFileDirectly(&handle, ARCHIVE_SDMC, archive_path,
MakePath(path), open_flags, 0));
if(ok)
m_handle = handle;
return ok;
}
bool Read(void *buffer, u32 size, u64 offset)
{
u32 bytes_read = 0;
const Result res = FSFILE_Read(*m_handle, &bytes_read, offset, buffer, size);
return R_SUCCEEDED(res) && bytes_read == size;
}
std::optional<u64> GetSize() const
{
u64 size;
if(!R_SUCCEEDED(FSFILE_GetSize(*m_handle, &size)))
return std::nullopt;
return size;
}
private:
std::optional<Handle> m_handle;
};
} // namespace util