ams: finish stdio -> fs bindings for stratosphere

This commit is contained in:
Michael Scire 2020-03-09 03:58:02 -07:00
parent d2ff0b1774
commit 08679045a3
2 changed files with 52 additions and 9 deletions

View File

@ -18,6 +18,12 @@
#include <vapours.hpp> #include <vapours.hpp>
#include <stratosphere/fs/fs_file.hpp> #include <stratosphere/fs/fs_file.hpp>
namespace ams::fs::fsa {
class IFile;
}
namespace ams::util::ini { namespace ams::util::ini {
/* Ini handler type. */ /* Ini handler type. */
@ -26,6 +32,6 @@ namespace ams::util::ini {
/* Utilities for dealing with INI file configuration. */ /* Utilities for dealing with INI file configuration. */
int ParseString(const char *ini_str, void *user_ctx, Handler h); int ParseString(const char *ini_str, void *user_ctx, Handler h);
int ParseFile(fs::FileHandle file, void *user_ctx, Handler h); int ParseFile(fs::FileHandle file, void *user_ctx, Handler h);
int ParseFile(const char *path, void *user_ctx, Handler h); int ParseFile(fs::fsa::IFile *file, void *user_ctx, Handler h);
} }

View File

@ -34,6 +34,16 @@ namespace ams::util::ini {
} }
}; };
struct IFileContext {
fs::fsa::IFile *file;
s64 offset;
s64 num_left;
explicit IFileContext(fs::fsa::IFile *f) : file(f), offset(0) {
R_ABORT_UNLESS(file->GetSize(std::addressof(this->num_left)));
}
};
char *ini_reader_file_handle(char *str, int num, void *stream) { char *ini_reader_file_handle(char *str, int num, void *stream) {
FileContext *ctx = static_cast<FileContext *>(stream); FileContext *ctx = static_cast<FileContext *>(stream);
@ -64,6 +74,38 @@ namespace ams::util::ini {
return str; return str;
} }
char *ini_reader_ifile(char *str, int num, void *stream) {
IFileContext *ctx = static_cast<IFileContext *>(stream);
if (ctx->num_left == 0 || num < 2) {
return nullptr;
}
/* Read as many bytes as we can. */
s64 cur_read = std::min<s64>(num - 1, ctx->num_left);
size_t read;
R_ABORT_UNLESS(ctx->file->Read(std::addressof(read), ctx->offset, str, cur_read, fs::ReadOption()));
AMS_ABORT_UNLESS(static_cast<s64>(read) == cur_read);
/* Only "read" up to the first \n. */
size_t offset = cur_read;
for (auto i = 0; i < cur_read; i++) {
if (str[i] == '\n') {
offset = i + 1;
break;
}
}
/* Ensure null termination. */
str[offset] = '\0';
/* Update context. */
ctx->offset += offset;
ctx->num_left -= offset;
return str;
}
} }
/* Utilities for dealing with INI file configuration. */ /* Utilities for dealing with INI file configuration. */
@ -76,14 +118,9 @@ namespace ams::util::ini {
return ini_parse_stream(ini_reader_file_handle, &ctx, h, user_ctx); return ini_parse_stream(ini_reader_file_handle, &ctx, h, user_ctx);
} }
int ParseFile(const char *path, void *user_ctx, Handler h) { int ParseFile(fs::fsa::IFile *file, void *user_ctx, Handler h) {
fs::FileHandle file; IFileContext ctx(file);
if (R_FAILED(fs::OpenFile(std::addressof(file), path, fs::OpenMode_Read))) { return ini_parse_stream(ini_reader_ifile, &ctx, h, user_ctx);
return -1;
}
ON_SCOPE_EXIT { fs::CloseFile(file); };
return ParseFile(file, user_ctx, h);
} }
} }