summaryrefslogtreecommitdiff
path: root/source/fud_string.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/fud_string.cpp')
-rw-r--r--source/fud_string.cpp105
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);
}