diff options
Diffstat (limited to 'source/fud_string.cpp')
-rw-r--r-- | source/fud_string.cpp | 105 |
1 files changed, 73 insertions, 32 deletions
diff --git a/source/fud_string.cpp b/source/fud_string.cpp index 82a9fe5..f33224a 100644 --- a/source/fud_string.cpp +++ b/source/fud_string.cpp @@ -48,22 +48,40 @@ ssize_t cStringLength(const char* str, size_t maxLength) StringResult String::makeFromCString(const char* cString) { + return makeFromCString(cString, &globalFudAllocator); +} + +StringResult String::makeFromCString(const char* cString, Allocator* allocator) +{ + if (allocator == nullptr) { + return StringResult::error(FudStatus::NullPointer); + } + auto lenResult = cStringLength(cString); if (lenResult < 0 || lenResult >= SSIZE_MAX) { return StringResult::error(FudStatus::InvalidInput); } String output{}; + output.m_allocator = allocator; 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)); + auto dataResult{output.m_allocator->allocate(output.m_capacity)}; + if (dataResult.isError()) { + return StringResult::error(dataResult); + } + + data = static_cast<utf8*>(dataResult.takeOkay()); + 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(); @@ -72,36 +90,42 @@ StringResult String::makeFromCString(const char* cString) return StringResult::okay(std::move(output)); } -StringResult String::makeFromUtf8(const utf8* utf8String) +StringResult String::from(const String& rhs) { - // NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast) - return makeFromCString(reinterpret_cast<const char*>(utf8String)); - // NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast) -} + if (!rhs.valid()) { + return StringResult::error(FudStatus::InvalidInput); + } -String::String(const String& rhs) : m_length{rhs.m_length}, m_capacity{rhs.m_capacity} -{ - if (rhs.valid()) { - if (isLarge()) { - m_data = static_cast<utf8*>(fudAlloc(m_capacity)); - fudAssert(m_data != nullptr); + String output{}; + output.m_length = rhs.m_length; + output.m_capacity = rhs.m_capacity; + output.m_allocator = rhs.m_allocator; + + if (rhs.isLarge()) { + auto dataResult = output.m_allocator->allocate(output.m_capacity); + if (dataResult.isError()) { + return StringResult::error(dataResult.getError()); } - fudAssert(copyMem(data(), m_capacity, rhs.data(), m_length) == FudStatus::Success); - fudAssert(nullTerminate() == FudStatus::Success); + output.m_data = static_cast<utf8*>(dataResult.getOkay()); + fudAssert(output.m_data != nullptr); } + + auto copyResult = copyMem(output.data(), output.m_capacity, rhs.data(), output.m_length); + fudAssert(copyResult == FudStatus::Success); + auto nullTerminateStatus = output.nullTerminate(); + fudAssert(nullTerminateStatus == FudStatus::Success); + return StringResult::okay(std::move(output)); } -String::String(String&& rhs) noexcept : m_length{rhs.m_length}, m_capacity{rhs.m_capacity} +String::String(String&& rhs) noexcept : m_length{rhs.m_length}, m_capacity{rhs.m_capacity}, m_allocator{rhs.m_allocator} { - if (isLarge()) { - cleanup(); - } if (rhs.isLarge()) { m_data = rhs.m_data; rhs.m_data = nullptr; } else { m_buffer = rhs.m_buffer; - fudAssert(nullTerminate() == FudStatus::Success); + auto terminateStatus = nullTerminate(); + fudAssert(terminateStatus == FudStatus::Success); } } @@ -110,25 +134,37 @@ String::~String() cleanup(); } -String& String::operator=(const String& rhs) +FudStatus String::copy(const String& rhs) { if (this == &rhs) { - return *this; + return FudStatus::Success; + } + + if (!rhs.valid()) { + return FudStatus::InvalidInput; } cleanup(); m_length = rhs.m_length; m_capacity = rhs.m_capacity; - if (rhs.valid()) { - if (isLarge()) { - m_data = static_cast<utf8*>(fudAlloc(m_capacity)); - fudAssert(m_data != nullptr); + m_allocator = rhs.m_allocator; + + if (isLarge()) { + auto dataResult = m_allocator->allocate(m_capacity); + if (dataResult.isError()) { + return dataResult.getError(); } - fudAssert(copyMem(data(), m_capacity, rhs.data(), m_length) == FudStatus::Success); - fudAssert(nullTerminate() == FudStatus::Success); + m_data = static_cast<utf8*>(dataResult.getOkay()); + fudAssert(m_data != nullptr); } - return *this; + + auto copyResult = copyMem(data(), m_capacity, rhs.data(), m_length); + fudAssert(copyResult == FudStatus::Success); + auto nullTerminateStatus = nullTerminate(); + fudAssert(nullTerminateStatus == FudStatus::Success); + + return FudStatus::Success; } String& String::operator=(String&& rhs) noexcept @@ -137,6 +173,7 @@ String& String::operator=(String&& rhs) noexcept m_length = rhs.m_length; m_capacity = rhs.m_capacity; + m_allocator = rhs.m_allocator; if (rhs.isLarge()) { m_data = rhs.m_data; rhs.m_data = nullptr; @@ -149,8 +186,8 @@ String& String::operator=(String&& rhs) noexcept void String::cleanup() { - if (isLarge() && m_data != nullptr) { - fudFree(m_data); + if (isLarge() && m_data != nullptr && m_allocator != nullptr) { + m_allocator->deallocate(m_data, m_capacity); m_data = nullptr; } } @@ -209,7 +246,7 @@ bool String::nullTerminated() const bool String::valid() const { - return nullTerminated(); + return m_allocator != nullptr && nullTerminated(); } bool String::utf8Valid() const @@ -416,7 +453,11 @@ StringResult String::catenate(const char* rhs) const 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)); + auto ptrResult = m_allocator->allocate(output.m_capacity); + if (ptrResult.isError()) { + return StringResult::error(ptrResult.getError()); + } + destPtr = static_cast<utf8*>(ptrResult.getOkay()); if (destPtr == nullptr) { return StringResult::error(FudStatus::AllocFailure); } |