summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorDominick Allen <djallen@librehumanitas.org>2024-10-15 20:56:26 -0500
committerDominick Allen <djallen@librehumanitas.org>2024-10-15 20:56:26 -0500
commitf3ac764684c64fbdd2094853a80b23e570cd5d9c (patch)
tree3b7f64480a1247455d28e23b6bb5ff63303c9170 /source
parent71976e927cca43b970cb659c03fd6908c352ea3d (diff)
Conver to using static constructors for string, sqlite, files.
Diffstat (limited to 'source')
-rw-r--r--source/fud_c_file.cpp100
-rw-r--r--source/fud_directory.cpp9
-rw-r--r--source/fud_sqlite.cpp87
-rw-r--r--source/fud_string.cpp113
-rw-r--r--source/libfud.cpp8
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