diff options
author | Dominick Allen <djallen@librehumanitas.org> | 2024-10-15 20:56:26 -0500 |
---|---|---|
committer | Dominick Allen <djallen@librehumanitas.org> | 2024-10-15 20:56:26 -0500 |
commit | f3ac764684c64fbdd2094853a80b23e570cd5d9c (patch) | |
tree | 3b7f64480a1247455d28e23b6bb5ff63303c9170 /source | |
parent | 71976e927cca43b970cb659c03fd6908c352ea3d (diff) |
Conver to using static constructors for string, sqlite, files.
Diffstat (limited to 'source')
-rw-r--r-- | source/fud_c_file.cpp | 100 | ||||
-rw-r--r-- | source/fud_directory.cpp | 9 | ||||
-rw-r--r-- | source/fud_sqlite.cpp | 87 | ||||
-rw-r--r-- | source/fud_string.cpp | 113 | ||||
-rw-r--r-- | source/libfud.cpp | 8 |
5 files changed, 232 insertions, 85 deletions
diff --git a/source/fud_c_file.cpp b/source/fud_c_file.cpp index 3961042..a63923a 100644 --- a/source/fud_c_file.cpp +++ b/source/fud_c_file.cpp @@ -19,28 +19,51 @@ namespace fud { -CBinaryFile::CBinaryFile(const String& filename, CFileMode mode) - : m_filename{filename}, - m_mode{CBinaryFileModeFromFlags(mode)}, - m_modeFlags{mode} +CBinaryFileResult CBinaryFile::make(const String& filename, CFileMode mode) { + if (!filename.valid()) { + return CBinaryFileResult::error(FudStatus::InvalidInput); + } + auto modeResult{String::makeFromCString(CBinaryFileModeFromFlags(mode))}; + if (modeResult.isError()) { + return CBinaryFileResult::error(modeResult); + } + + CBinaryFile binaryFile{}; + binaryFile.m_filename = filename; + binaryFile.m_mode = modeResult.takeOkay(); + binaryFile.m_modeFlags = mode; + return CBinaryFileResult::okay(std::move(binaryFile)); } -CBinaryFile::CBinaryFile(const String& filename, CFileMode mode, const String& extraFlags) - : m_filename{filename}, - m_extraFlags{extraFlags}, - m_mode{String(CBinaryFileModeFromFlags(mode)).catenate(extraFlags)}, - m_modeFlags{mode} +CBinaryFileResult CBinaryFile::make(const String& filename, CFileMode mode, const char* extraFlags) { + if (!filename.valid()) { + return CBinaryFileResult::error(FudStatus::InvalidInput); + } + auto modeResult{String::makeFromCString(CBinaryFileModeFromFlags(mode), extraFlags)}; + if (modeResult.isError()) { + return CBinaryFileResult::error(modeResult); + } + + CBinaryFile binaryFile{}; + binaryFile.m_filename = filename; + binaryFile.m_mode = modeResult.takeOkay(); + binaryFile.m_modeFlags = mode; + return CBinaryFileResult::okay(std::move(binaryFile)); } CBinaryFile::CBinaryFile(CBinaryFile&& rhs) noexcept : - m_filename{std::move(rhs.m_filename)}, m_extraFlags{std::move(rhs.m_extraFlags)}, m_mode{std::move(rhs.m_mode)}, - m_modeFlags{rhs.m_modeFlags}, m_file{rhs.m_file} + m_filename{std::move(rhs.m_filename)}, + m_mode{std::move(rhs.m_mode)}, + m_modeFlags{rhs.m_modeFlags}, + m_file{rhs.m_file} { + rhs.m_file = nullptr; } -CBinaryFile::~CBinaryFile() { +CBinaryFile::~CBinaryFile() +{ close(); } @@ -49,36 +72,60 @@ CBinaryFile& CBinaryFile::operator=(CBinaryFile&& rhs) noexcept close(); m_filename = std::move(rhs.m_filename); - m_extraFlags = std::move(rhs.m_extraFlags); m_mode = std::move(rhs.m_mode); m_modeFlags = rhs.m_modeFlags; m_file = rhs.m_file; + rhs.m_file = nullptr; + return *this; } -CTextFile::CTextFile(const String& filename, CFileMode mode) - : m_filename{filename}, - m_mode{CTextFileModeFromFlags(mode)}, - m_modeFlags{mode} +CTextFileResult CTextFile::make(const String& filename, CFileMode mode) { + if (!filename.valid()) { + return CTextFileResult::error(FudStatus::InvalidInput); + } + auto modeResult{String::makeFromCString(CBinaryFileModeFromFlags(mode))}; + if (modeResult.isError()) { + return CTextFileResult::error(modeResult); + } + + CTextFile textFile{}; + textFile.m_filename = filename; + textFile.m_mode = modeResult.takeOkay(); + textFile.m_modeFlags = mode; + return CTextFileResult::okay(std::move(textFile)); } -CTextFile::CTextFile(const String& filename, CFileMode mode, const String& extraFlags) - : m_filename{filename}, - m_extraFlags{extraFlags}, - m_mode{String(CTextFileModeFromFlags(mode)).catenate(extraFlags)}, - m_modeFlags{mode} +CTextFileResult CTextFile::make(const String& filename, CFileMode mode, const char* extraFlags) { + if (!filename.valid()) { + return CTextFileResult::error(FudStatus::InvalidInput); + } + auto modeResult{String::makeFromCString(CTextFileModeFromFlags(mode), extraFlags)}; + if (modeResult.isError()) { + return CTextFileResult::error(modeResult); + } + + CTextFile textFile{}; + textFile.m_filename = filename; + textFile.m_mode = modeResult.takeOkay(); + textFile.m_modeFlags = mode; + return CTextFileResult::okay(std::move(textFile)); } CTextFile::CTextFile(CTextFile&& rhs) noexcept : - m_filename{std::move(rhs.m_filename)}, m_extraFlags{std::move(rhs.m_extraFlags)}, m_mode{std::move(rhs.m_mode)}, - m_modeFlags{rhs.m_modeFlags}, m_file{rhs.m_file} + m_filename{std::move(rhs.m_filename)}, + m_mode{std::move(rhs.m_mode)}, + m_modeFlags{rhs.m_modeFlags}, + m_file{rhs.m_file} { + rhs.m_file = nullptr; } -CTextFile::~CTextFile() { +CTextFile::~CTextFile() +{ close(); } @@ -87,11 +134,12 @@ CTextFile& CTextFile::operator=(CTextFile&& rhs) noexcept close(); m_filename = std::move(rhs.m_filename); - m_extraFlags = std::move(rhs.m_extraFlags); m_mode = std::move(rhs.m_mode); m_modeFlags = rhs.m_modeFlags; m_file = rhs.m_file; + rhs.m_file = nullptr; + return *this; } diff --git a/source/fud_directory.cpp b/source/fud_directory.cpp index 1fcebe1..1697692 100644 --- a/source/fud_directory.cpp +++ b/source/fud_directory.cpp @@ -199,13 +199,16 @@ Result<std::optional<DirectoryEntry>, FudStatus> Directory::getNextEntry() return RetType::error(m_status); } - auto entryName = String{entryNameCString}; - auto retValue = DirectoryEntry::fromStat(entryName, sBuffer); + auto entryNameResult = String::makeFromCString(entryNameCString); + if (entryNameResult.isError()) { + return RetType::error(entryNameResult); + } + auto retValue = DirectoryEntry::fromStat(entryNameResult.getOkay(), sBuffer); if (retValue.isOkay()) { m_errorCode = 0; m_status = FudStatus::Success; - return RetType::okay(std::move(retValue.getOkay())); + return RetType::okay(retValue.takeOkay()); } m_status = retValue.getError(); diff --git a/source/fud_sqlite.cpp b/source/fud_sqlite.cpp index 3e39474..449be8b 100644 --- a/source/fud_sqlite.cpp +++ b/source/fud_sqlite.cpp @@ -19,21 +19,43 @@ namespace fud { -SqliteDb::SqliteDb(const String& name, SqliteOpenMode mode, int extraFlags) : - m_name{name}, m_mode{mode}, m_extraFlags{extraFlags} +SqliteDbResult SqliteDb::make(const String& name, SqliteOpenMode mode, int extraFlags) { - initialize(); + SqliteDb sqlDb{}; + sqlDb.m_name = name; + sqlDb.m_mode = mode; + sqlDb.m_extraFlags = extraFlags; + auto status = sqlDb.initialize(); + if (status != FudStatus::Success) { + return SqliteDbResult::error(status); + } + return SqliteDbResult::okay(std::move(sqlDb)); } -SqliteDb::SqliteDb(const char* name, SqliteOpenMode mode, int extraFlags) : - m_name{name}, m_mode{mode}, m_extraFlags{extraFlags} +SqliteDbResult SqliteDb::make(const char* cStrName, SqliteOpenMode mode, int extraFlags) { - initialize(); + auto nameResult = String::makeFromCString(cStrName); + if (nameResult.isError()) { + return SqliteDbResult::error(nameResult); + } + SqliteDb sqlDb{}; + sqlDb.m_name = nameResult.takeOkay(); + sqlDb.m_mode = mode; + sqlDb.m_extraFlags = extraFlags; + auto status = sqlDb.initialize(); + if (status != FudStatus::Success) { + return SqliteDbResult::error(status); + } + return SqliteDbResult::okay(std::move(sqlDb)); } SqliteDb::SqliteDb(SqliteDb&& rhs) noexcept : - m_name{std::move(rhs.m_name)}, m_nameValid{rhs.m_nameValid}, m_dbHandle{rhs.m_dbHandle}, - m_errorCode{rhs.m_errorCode}, m_mode{rhs.m_mode}, m_extraFlags{rhs.m_extraFlags} + m_name{std::move(rhs.m_name)}, + m_nameValid{rhs.m_nameValid}, + m_dbHandle{rhs.m_dbHandle}, + m_errorCode{rhs.m_errorCode}, + m_mode{rhs.m_mode}, + m_extraFlags{rhs.m_extraFlags} { rhs.m_nameValid = false; rhs.m_dbHandle = nullptr; @@ -85,7 +107,7 @@ FudStatus SqliteDb::exec( const String& statement, int (*callback)(void*, int, char**, char**), void* context, - String* errorMessage) + std::unique_ptr<SqliteErrorMsg> errorMessage) { if (!valid()) { return FudStatus::ObjectInvalid; @@ -101,29 +123,29 @@ FudStatus SqliteDb::exec( errorMsgPtrAddress = &errorMsgPtr; } - m_errorCode = sqlite3_exec( - m_dbHandle, - statement.c_str(), - callback, - context, - errorMsgPtrAddress); + m_errorCode = sqlite3_exec(m_dbHandle, statement.c_str(), callback, context, errorMsgPtrAddress); if (errorMessage != nullptr) { - *errorMessage = String{errorMsgPtr}; + errorMessage = std::make_unique<SqliteErrorMsg>(errorMsgPtr); } return m_errorCode == SQLITE_OK ? FudStatus::Success : FudStatus::Failure; } -void SqliteDb::initialize() +FudStatus SqliteDb::initialize() { m_nameValid = m_name.utf8Valid(); if (!m_nameValid) { - return; + return FudStatus::InvalidInput; } m_errorCode = open(); + if (m_errorCode != SQLITE_OK) { + return FudStatus::Failure; + } + + return FudStatus::Success; } int SqliteDb::open() @@ -165,7 +187,10 @@ SqliteStatement::SqliteStatement(const SqliteDb& sqliteDb, const String& input) } SqliteStatement::SqliteStatement(SqliteStatement&& rhs) noexcept : - m_input{std::move(rhs.m_input)}, m_tail{rhs.m_tail}, m_status{rhs.m_status}, m_errorCode{rhs.m_errorCode}, + m_input{std::move(rhs.m_input)}, + m_tail{rhs.m_tail}, + m_status{rhs.m_status}, + m_errorCode{rhs.m_errorCode}, m_preparedStatement{rhs.m_preparedStatement} { rhs.m_tail = nullptr; @@ -213,4 +238,28 @@ FudStatus SqliteStatement::reset() return FudStatus::Success; } +SqliteErrorMsg::SqliteErrorMsg(SqliteErrorMsg&& rhs) noexcept : m_errorMsg{rhs.m_errorMsg} +{ + rhs.m_errorMsg = nullptr; +} + +SqliteErrorMsg& SqliteErrorMsg::operator=(SqliteErrorMsg&& rhs) noexcept { + if (m_errorMsg != nullptr) { + sqlite3_free(m_errorMsg); + m_errorMsg = nullptr; + } + m_errorMsg = rhs.m_errorMsg; + rhs.m_errorMsg = nullptr; + + return *this; +} + +SqliteErrorMsg::~SqliteErrorMsg() +{ + if (m_errorMsg != nullptr) { + sqlite3_free(m_errorMsg); + m_errorMsg = nullptr; + } +} + } // namespace fud diff --git a/source/fud_string.cpp b/source/fud_string.cpp index 3a9aca0..82a9fe5 100644 --- a/source/fud_string.cpp +++ b/source/fud_string.cpp @@ -46,30 +46,37 @@ ssize_t cStringLength(const char* str, size_t maxLength) return size; } -// NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast) -String::String(const utf8* cString) : String(reinterpret_cast<const char*>(cString)) -{ -} -// NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast) - -String::String(const char* cString) +StringResult String::makeFromCString(const char* cString) { auto lenResult = cStringLength(cString); if (lenResult < 0 || lenResult >= SSIZE_MAX) { - m_length = 1; - m_capacity = 0; - } else if (static_cast<size_t>(lenResult) < SSO_BUF_SIZE) { - m_length = static_cast<size_t>(lenResult); - fudAssert(copyMem(m_buffer.data(), m_buffer.size(), cString, m_length) == FudStatus::Success); - fudAssert(nullTerminate() == FudStatus::Success); - } else { - m_length = static_cast<size_t>(lenResult); - m_capacity = m_length + 1; - m_data = static_cast<utf8*>(fudAlloc(m_capacity)); - fudAssert(m_data != nullptr); - fudAssert(copyMem(m_data, m_capacity, cString, m_length) == FudStatus::Success); - fudAssert(nullTerminate() == FudStatus::Success); + return StringResult::error(FudStatus::InvalidInput); + } + + String output{}; + auto* data = output.m_buffer.data(); + output.m_length = static_cast<size_t>(lenResult); + if (output.m_length >= output.m_capacity) { + output.m_capacity = output.m_length + 1; + data = static_cast<utf8*>(fudAlloc(output.m_capacity)); + if (data == nullptr) { + return StringResult::error(FudStatus::AllocFailure); + } + output.m_data = data; } + auto copyStatus = copyMem(data, output.m_capacity, cString, output.m_length); + fudAssert(copyStatus == FudStatus::Success); + auto terminateStatus = output.nullTerminate(); + fudAssert(terminateStatus == FudStatus::Success); + + return StringResult::okay(std::move(output)); +} + +StringResult String::makeFromUtf8(const utf8* utf8String) +{ + // NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast) + return makeFromCString(reinterpret_cast<const char*>(utf8String)); + // NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast) } String::String(const String& rhs) : m_length{rhs.m_length}, m_capacity{rhs.m_capacity} @@ -364,7 +371,7 @@ FudStatus String::append(StringView source) return FudStatus::OperationInvalid; } const size_t newSize = newLength + 1; // cppcheck-suppress knownConditionTrueFalse - if (newSize < newLength) { // cppcheck-suppress knownConditionTrueFalse + if (newSize < newLength) { // cppcheck-suppress knownConditionTrueFalse return FudStatus::OperationInvalid; } if (newSize >= m_capacity) { @@ -386,22 +393,60 @@ FudStatus String::append(StringView source) return status; } -String String::catenate(const char* rhs) const +StringResult String::catenate(const char* rhs) const { - String rhsString{rhs}; - return catenate(rhsString); -} + if (!valid()) { + return StringResult::error(FudStatus::InvalidInput); + } + + auto lenResult = cStringLength(rhs); + if (lenResult < 0 || lenResult >= SSIZE_MAX) { + return StringResult::error(FudStatus::InvalidInput); + } + size_t rhsLength = static_cast<size_t>(lenResult); -String String::catenate(const String& rhs) const -{ String output{}; - output.m_length = 1; - output.m_capacity = 0; + if (SIZE_MAX - m_length < rhsLength) + { + return StringResult::error(FudStatus::Failure); + } + + output.m_length = m_length + rhsLength; + auto* destPtr = output.m_buffer.data(); + if (output.m_length >= output.m_capacity) { + output.m_capacity = output.m_length + 1; + destPtr = static_cast<utf8*>(fudAlloc(output.m_capacity)); + if (destPtr == nullptr) { + return StringResult::error(FudStatus::AllocFailure); + } + output.m_data = destPtr; + } + + auto status = copyMem(destPtr, m_capacity, data(), length()); + fudAssert(status == FudStatus::Success); + + status = copyMem(destPtr + length(), output.m_capacity - length(), rhs, rhsLength); + fudAssert(status == FudStatus::Success); + + auto terminateStatus = output.nullTerminate(); + fudAssert(terminateStatus == FudStatus::Success); + + return StringResult::okay(std::move(output)); +} + +StringResult String::catenate(const String& rhs) const +{ if (!valid() || !rhs.valid()) { - return output; + return StringResult::error(FudStatus::InvalidInput); } + if (SIZE_MAX - m_length < rhs.length()) + { + return StringResult::error(FudStatus::Failure); + } + + String output{}; output.m_length = m_length + rhs.length(); output.m_capacity = output.m_length + 1; if (output.m_capacity < SSO_BUF_SIZE) { @@ -414,12 +459,14 @@ String String::catenate(const String& rhs) const auto* destPtr = output.data(); auto status = copyMem(destPtr, m_capacity, data(), length()); fudAssert(status == FudStatus::Success); + status = copyMem(destPtr + length(), output.m_capacity - length(), rhs.data(), rhs.length()); fudAssert(status == FudStatus::Success); - static_cast<void>(status); - fudAssert(output.nullTerminate() == FudStatus::Success); - return output; + auto terminateStatus = output.nullTerminate(); + fudAssert(terminateStatus == FudStatus::Success); + + return StringResult::okay(std::move(output)); } bool String::compare(const String& rhs) const diff --git a/source/libfud.cpp b/source/libfud.cpp index 8c962ba..cec544d 100644 --- a/source/libfud.cpp +++ b/source/libfud.cpp @@ -50,12 +50,12 @@ Result<String, FudStatus> getEnv(const char* name) return RetType::error(FudStatus::NotFound); } - String envVar{resultString}; - if (!envVar.valid()) { - return RetType::error(FudStatus::Failure); + auto envVarResult = String::makeFromCString(resultString); + if (envVarResult.isError()) { + return RetType::error(envVarResult); } - return RetType::okay(std::move(envVar)); + return RetType::okay(envVarResult); } } // namespace fud |