Results: Implement namespaced, type-safe results.

Because I was working on multiple things at once, this commit also:
- Adds wrappers for/linker flags to wrap CXX exceptions to make them
  abort. This saves ~0x8000 of memory in every system module.
- Broadly replaces lines of the pattern if (cond) { return ResultX; }
  with R_UNLESS(!cond, ResultX());.
- Reworks the R_TRY_CATCH macros (and the result macros in general).
This commit is contained in:
Michael Scire
2019-10-24 01:40:44 -07:00
committed by SciresM
parent 15773e4755
commit 4059dc6187
169 changed files with 2172 additions and 1868 deletions

View File

@@ -33,9 +33,9 @@ namespace sts::kvdb {
Result Validate() const {
if (std::memcmp(this->magic, ArchiveHeaderMagic, sizeof(ArchiveHeaderMagic)) != 0) {
return ResultKvdbInvalidKeyValue;
return ResultInvalidKeyValue();
}
return ResultSuccess;
return ResultSuccess();
}
static ArchiveHeader Make(size_t entry_count) {
@@ -54,9 +54,9 @@ namespace sts::kvdb {
Result Validate() const {
if (std::memcmp(this->magic, ArchiveEntryMagic, sizeof(ArchiveEntryMagic)) != 0) {
return ResultKvdbInvalidKeyValue;
return ResultInvalidKeyValue();
}
return ResultSuccess;
return ResultSuccess();
}
static ArchiveEntryHeader Make(size_t ksz, size_t vsz) {
@@ -75,17 +75,17 @@ namespace sts::kvdb {
Result ArchiveReader::Peek(void *dst, size_t size) {
/* Bounds check. */
if (this->offset + size > this->buffer.GetSize() || this->offset + size <= this->offset) {
return ResultKvdbInvalidKeyValue;
return ResultInvalidKeyValue();
}
std::memcpy(dst, this->buffer.Get() + this->offset, size);
return ResultSuccess;
return ResultSuccess();
}
Result ArchiveReader::Read(void *dst, size_t size) {
R_TRY(this->Peek(dst, size));
this->offset += size;
return ResultSuccess;
return ResultSuccess();
}
Result ArchiveReader::ReadEntryCount(size_t *out) {
@@ -98,7 +98,7 @@ namespace sts::kvdb {
R_TRY(header.Validate());
*out = header.entry_count;
return ResultSuccess;
return ResultSuccess();
}
Result ArchiveReader::GetEntrySize(size_t *out_key_size, size_t *out_value_size) {
@@ -112,7 +112,7 @@ namespace sts::kvdb {
*out_key_size = header.key_size;
*out_value_size = header.value_size;
return ResultSuccess;
return ResultSuccess();
}
Result ArchiveReader::ReadEntry(void *out_key, size_t key_size, void *out_value, size_t value_size) {
@@ -130,19 +130,19 @@ namespace sts::kvdb {
R_ASSERT(this->Read(out_key, key_size));
R_ASSERT(this->Read(out_value, value_size));
return ResultSuccess;
return ResultSuccess();
}
/* Writer functionality. */
Result ArchiveWriter::Write(const void *src, size_t size) {
/* Bounds check. */
if (this->offset + size > this->buffer.GetSize() || this->offset + size <= this->offset) {
return ResultKvdbInvalidKeyValue;
return ResultInvalidKeyValue();
}
std::memcpy(this->buffer.Get() + this->offset, src, size);
this->offset += size;
return ResultSuccess;
return ResultSuccess();
}
void ArchiveWriter::WriteHeader(size_t entry_count) {

View File

@@ -41,11 +41,11 @@ namespace sts::kvdb {
if (this->backing_buffer != nullptr) {
this->entries = static_cast<decltype(this->entries)>(this->Allocate(sizeof(*this->entries) * this->capacity));
if (this->entries == nullptr) {
return ResultKvdbBufferInsufficient;
return ResultBufferInsufficient();
}
}
return ResultSuccess;
return ResultSuccess();
}
void FileKeyValueStore::Cache::Invalidate() {
@@ -159,13 +159,13 @@ namespace sts::kvdb {
const size_t file_name_len = file_name.GetLength();
const size_t key_name_len = file_name_len - FileExtensionLength;
if (file_name_len < FileExtensionLength + 2 || !file_name.EndsWith(FileExtension) || key_name_len % 2 != 0) {
return ResultKvdbInvalidKeyValue;
return ResultInvalidKeyValue();
}
/* Validate that we have space for the converted key. */
const size_t key_size = key_name_len / 2;
if (key_size > max_out_size) {
return ResultKvdbBufferInsufficient;
return ResultBufferInsufficient();
}
/* Convert the hex key back. */
@@ -177,7 +177,7 @@ namespace sts::kvdb {
}
*out_size = key_size;
return ResultSuccess;
return ResultSuccess();
}
Result FileKeyValueStore::Initialize(const char *dir) {
@@ -189,7 +189,7 @@ namespace sts::kvdb {
{
struct stat st;
if (stat(dir, &st) != 0 || !(S_ISDIR(st.st_mode))) {
return ResultFsPathNotFound;
return fs::ResultPathNotFound();
}
}
@@ -198,7 +198,7 @@ namespace sts::kvdb {
/* Initialize our cache. */
R_TRY(this->cache.Initialize(cache_buffer, cache_buffer_size, cache_capacity));
return ResultSuccess;
return ResultSuccess();
}
Result FileKeyValueStore::Get(size_t *out_size, void *out_value, size_t max_out_size, const void *key, size_t key_size) {
@@ -206,7 +206,7 @@ namespace sts::kvdb {
/* Ensure key size is small enough. */
if (key_size > MaxKeySize) {
return ResultKvdbKeyCapacityInsufficient;
return ResultKeyCapacityInsufficient();
}
/* Try to get from cache. */
@@ -214,7 +214,7 @@ namespace sts::kvdb {
auto size = this->cache.TryGet(out_value, max_out_size, key, key_size);
if (size) {
*out_size = *size;
return ResultSuccess;
return ResultSuccess();
}
}
@@ -222,9 +222,7 @@ namespace sts::kvdb {
FILE *fp = fopen(this->GetPath(key, key_size), "rb");
if (fp == nullptr) {
R_TRY_CATCH(fsdevGetLastResult()) {
R_CATCH(ResultFsPathNotFound) {
return ResultKvdbKeyNotFound;
}
R_CONVERT(fs::ResultPathNotFound, ResultKeyNotFound())
} R_END_TRY_CATCH;
}
ON_SCOPE_EXIT { fclose(fp); };
@@ -236,7 +234,7 @@ namespace sts::kvdb {
/* Ensure there's enough space for the value. */
if (max_out_size < value_size) {
return ResultKvdbBufferInsufficient;
return ResultBufferInsufficient();
}
/* Read the value. */
@@ -247,7 +245,7 @@ namespace sts::kvdb {
/* Cache the newly read value. */
this->cache.Set(key, key_size, out_value, value_size);
return ResultSuccess;
return ResultSuccess();
}
Result FileKeyValueStore::GetSize(size_t *out_size, const void *key, size_t key_size) {
@@ -255,7 +253,7 @@ namespace sts::kvdb {
/* Ensure key size is small enough. */
if (key_size > MaxKeySize) {
return ResultKvdbKeyCapacityInsufficient;
return ResultKeyCapacityInsufficient();
}
/* Try to get from cache. */
@@ -263,7 +261,7 @@ namespace sts::kvdb {
auto size = this->cache.TryGetSize(key, key_size);
if (size) {
*out_size = *size;
return ResultSuccess;
return ResultSuccess();
}
}
@@ -271,9 +269,7 @@ namespace sts::kvdb {
FILE *fp = fopen(this->GetPath(key, key_size), "rb");
if (fp == nullptr) {
R_TRY_CATCH(fsdevGetLastResult()) {
R_CATCH(ResultFsPathNotFound) {
return ResultKvdbKeyNotFound;
}
R_CONVERT(fs::ResultPathNotFound, ResultKeyNotFound())
} R_END_TRY_CATCH;
}
ON_SCOPE_EXIT { fclose(fp); };
@@ -281,7 +277,7 @@ namespace sts::kvdb {
/* Get the value size. */
fseek(fp, 0, SEEK_END);
*out_size = ftell(fp);
return ResultSuccess;
return ResultSuccess();
}
Result FileKeyValueStore::Set(const void *key, size_t key_size, const void *value, size_t value_size) {
@@ -289,7 +285,7 @@ namespace sts::kvdb {
/* Ensure key size is small enough. */
if (key_size > MaxKeySize) {
return ResultKvdbKeyCapacityInsufficient;
return ResultKeyCapacityInsufficient();
}
/* When the cache contains the key being set, Nintendo invalidates the cache. */
@@ -316,7 +312,7 @@ namespace sts::kvdb {
/* Flush the value file. */
fflush(fp);
return ResultSuccess;
return ResultSuccess();
}
Result FileKeyValueStore::Remove(const void *key, size_t key_size) {
@@ -324,7 +320,7 @@ namespace sts::kvdb {
/* Ensure key size is small enough. */
if (key_size > MaxKeySize) {
return ResultKvdbKeyCapacityInsufficient;
return ResultKeyCapacityInsufficient();
}
/* When the cache contains the key being set, Nintendo invalidates the cache. */
@@ -335,13 +331,11 @@ namespace sts::kvdb {
/* Remove the file. */
if (std::remove(this->GetPath(key, key_size)) != 0) {
R_TRY_CATCH(fsdevGetLastResult()) {
R_CATCH(ResultFsPathNotFound) {
return ResultKvdbKeyNotFound;
}
R_CONVERT(fs::ResultPathNotFound, ResultKeyNotFound())
} R_END_TRY_CATCH;
}
return ResultSuccess;
return ResultSuccess();
}
}