From f3ac764684c64fbdd2094853a80b23e570cd5d9c Mon Sep 17 00:00:00 2001 From: Dominick Allen Date: Tue, 15 Oct 2024 20:56:26 -0500 Subject: Conver to using static constructors for string, sqlite, files. --- include/fud_string.hpp | 79 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 6 deletions(-) (limited to 'include/fud_string.hpp') diff --git a/include/fud_string.hpp b/include/fud_string.hpp index 1939c7d..6880cb7 100644 --- a/include/fud_string.hpp +++ b/include/fud_string.hpp @@ -18,6 +18,8 @@ #ifndef FUD_STRING_HPP #define FUD_STRING_HPP +#include "fud_assert.hpp" +#include "fud_result.hpp" #include "fud_status.hpp" #include "fud_string_view.hpp" #include "fud_utf8.hpp" @@ -32,13 +34,77 @@ namespace fud { constexpr size_t SSO_BUF_LENGTH = 15; constexpr size_t SSO_BUF_SIZE = SSO_BUF_LENGTH + 1; +using StringResult = Result; + class String { public: - String() = default; - explicit String(const utf8* cString); - explicit String(const char* cString); + static StringResult makeFromCString(const char* cString); + + static StringResult makeFromUtf8(const utf8* utf8String); + + template + static StringResult makeFromCString(Strings... cStrings) + { + size_t totalLength = 0; + Array lengths{}; + Array strPointers{}; + size_t index = 0; + for (const auto* cStringItem: {cStrings...}) { + // for (size_t index = 0; index < strPointers.size(); ++index) { + // const auto* cString = strPointers[index]; + const char* cString = nullptr; + if constexpr (std::is_same_v) { + cString = cStringItem; + } else if constexpr (std::is_same_v) { + cString = reinterpret_cast(cStringItem); + } else { + static_assert(!std::is_same_v); + } + strPointers[index] = cString; + + auto lengthResult = cStringLength(cString); + if (lengthResult < 0 || lengthResult >= SSIZE_MAX) { + return StringResult::error(FudStatus::InvalidInput); + } + auto stringLength = static_cast(lengthResult); + if (SIZE_MAX - totalLength < stringLength) { + return StringResult::error(FudStatus::Failure); + } + totalLength += stringLength; + lengths[index] = stringLength; + index++; + } + + String output{}; + auto* data = output.m_buffer.data(); + output.m_length = totalLength; + if (output.m_length >= output.m_capacity) { + output.m_capacity = output.m_length + 1; + data = static_cast(fudAlloc(output.m_capacity)); + if (data == nullptr) { + return StringResult::error(FudStatus::AllocFailure); + } + output.m_data = data; + } + + size_t cumulativeLength = 0; + for (size_t idx = 0; idx < strPointers.size(); ++idx) { + const auto* cString = strPointers[idx]; + auto copyStatus = copyMem(data, output.m_capacity - cumulativeLength, cString, lengths[idx]); + fudAssert(copyStatus == FudStatus::Success); + cumulativeLength += lengths[idx]; + } + + auto terminateStatus = output.nullTerminate(); + fudAssert(terminateStatus == FudStatus::Success); + + return StringResult::okay(std::move(output)); + } + + String() noexcept = default; String(const String& rhs); String(String&& rhs) noexcept; + ~String(); String& operator=(const String& rhs); @@ -109,7 +175,8 @@ class String { return m_capacity - 1U - m_length; } - [[nodiscard]] inline StringView asView() const { + [[nodiscard]] inline StringView asView() const + { return StringView(*this); } @@ -127,9 +194,9 @@ class String { FudStatus append(StringView source); - [[nodiscard]] String catenate(const String& rhs) const; + [[nodiscard]] StringResult catenate(const String& rhs) const; - [[nodiscard]] String catenate(const char* rhs) const; + [[nodiscard]] StringResult catenate(const char* rhs) const; [[nodiscard]] bool compare(const String& rhs) const; -- cgit v1.2.3