summaryrefslogtreecommitdiffstats
path: root/source/core/slang-string.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/core/slang-string.cpp')
-rw-r--r--source/core/slang-string.cpp1101
1 files changed, 566 insertions, 535 deletions
diff --git a/source/core/slang-string.cpp b/source/core/slang-string.cpp
index 182c6261e..b58d466fa 100644
--- a/source/core/slang-string.cpp
+++ b/source/core/slang-string.cpp
@@ -1,288 +1,292 @@
#include "slang-string.h"
-#include "slang-text-io.h"
#include "slang-char-util.h"
+#include "slang-text-io.h"
namespace Slang
{
- // HACK!
- // JS: Many of the inlined functions of CharUtil just access a global map. That referencing this global is *NOT* enough to
- // link correctly with CharUtil on linux for a shared library. The following call exists to try and force linkage of CharUtil
- // for anything that uses core
- static const auto s_charUtilLink = CharUtil::_ensureLink();
+// HACK!
+// JS: Many of the inlined functions of CharUtil just access a global map. That referencing this
+// global is *NOT* enough to link correctly with CharUtil on linux for a shared library. The
+// following call exists to try and force linkage of CharUtil for anything that uses core
+static const auto s_charUtilLink = CharUtil::_ensureLink();
- // StringRepresentation
+// StringRepresentation
- void StringRepresentation::setContents(const UnownedStringSlice& slice)
- {
- const auto sliceLength = slice.getLength();
- SLANG_ASSERT(sliceLength <= capacity);
+void StringRepresentation::setContents(const UnownedStringSlice& slice)
+{
+ const auto sliceLength = slice.getLength();
+ SLANG_ASSERT(sliceLength <= capacity);
- char* chars = getData();
+ char* chars = getData();
- // Use move (rather than memcpy), because the slice *could* be contained in the StringRepresentation
- ::memmove(chars, slice.begin(), sliceLength * sizeof(char));
- // Zero terminate.
- chars[sliceLength] = 0;
- // Set the length
- length = sliceLength;
- }
+ // Use move (rather than memcpy), because the slice *could* be contained in the
+ // StringRepresentation
+ ::memmove(chars, slice.begin(), sliceLength * sizeof(char));
+ // Zero terminate.
+ chars[sliceLength] = 0;
+ // Set the length
+ length = sliceLength;
+}
- /* static */StringRepresentation* StringRepresentation::create(const UnownedStringSlice& slice)
+/* static */ StringRepresentation* StringRepresentation::create(const UnownedStringSlice& slice)
+{
+ const auto sliceLength = slice.getLength();
+
+ if (sliceLength)
{
- const auto sliceLength = slice.getLength();
+ StringRepresentation* rep = StringRepresentation::createWithLength(sliceLength);
- if (sliceLength)
- {
- StringRepresentation* rep = StringRepresentation::createWithLength(sliceLength);
-
- char* chars = rep->getData();
- ::memcpy(chars, slice.begin(), sizeof(char) * sliceLength);
- chars[sliceLength] = 0;
+ char* chars = rep->getData();
+ ::memcpy(chars, slice.begin(), sizeof(char) * sliceLength);
+ chars[sliceLength] = 0;
- return rep;
- }
- else
- {
- return nullptr;
- }
+ return rep;
}
-
- /* static */StringRepresentation* StringRepresentation::createWithReference(const UnownedStringSlice& slice)
+ else
{
- const auto sliceLength = slice.getLength();
+ return nullptr;
+ }
+}
- if (sliceLength)
- {
- StringRepresentation* rep = StringRepresentation::createWithLength(sliceLength);
- rep->addReference();
+/* static */ StringRepresentation* StringRepresentation::createWithReference(
+ const UnownedStringSlice& slice)
+{
+ const auto sliceLength = slice.getLength();
- char* chars = rep->getData();
- ::memcpy(chars, slice.begin(), sizeof(char) * sliceLength);
- chars[sliceLength] = 0;
+ if (sliceLength)
+ {
+ StringRepresentation* rep = StringRepresentation::createWithLength(sliceLength);
+ rep->addReference();
- return rep;
- }
- else
- {
- return nullptr;
- }
+ char* chars = rep->getData();
+ ::memcpy(chars, slice.begin(), sizeof(char) * sliceLength);
+ chars[sliceLength] = 0;
+
+ return rep;
}
+ else
+ {
+ return nullptr;
+ }
+}
- // OSString
+// OSString
- OSString::OSString()
- : m_begin(nullptr)
- , m_end(nullptr)
- {}
+OSString::OSString()
+ : m_begin(nullptr), m_end(nullptr)
+{
+}
- OSString::OSString(wchar_t* begin, wchar_t* end)
- : m_begin(begin)
- , m_end(end)
- {}
+OSString::OSString(wchar_t* begin, wchar_t* end)
+ : m_begin(begin), m_end(end)
+{
+}
- void OSString::_releaseBuffer()
+void OSString::_releaseBuffer()
+{
+ if (m_begin)
{
- if (m_begin)
- {
- delete[] m_begin;
- }
+ delete[] m_begin;
}
+}
- void OSString::set(const wchar_t* begin, const wchar_t* end)
+void OSString::set(const wchar_t* begin, const wchar_t* end)
+{
+ if (m_begin)
{
- if (m_begin)
- {
- delete[] m_begin;
- m_begin = nullptr;
- m_end = nullptr;
- }
- const size_t len = end - begin;
- if (len > 0)
- {
- // TODO(JS): The allocation is only done this way to be compatible with the buffer being detached from an array
- // This is unfortunate, because it means that the allocation stores the size (and alignment fix), which is a shame because we know the size
- m_begin = new wchar_t[len + 1];
- memcpy(m_begin, begin, len * sizeof(wchar_t));
- // Zero terminate
- m_begin[len] = 0;
- m_end = m_begin + len;
- }
+ delete[] m_begin;
+ m_begin = nullptr;
+ m_end = nullptr;
}
-
- static const wchar_t kEmptyOSString[] = { 0 };
-
- wchar_t const* OSString::begin() const
+ const size_t len = end - begin;
+ if (len > 0)
{
- return m_begin ? m_begin : kEmptyOSString;
+ // TODO(JS): The allocation is only done this way to be compatible with the buffer being
+ // detached from an array This is unfortunate, because it means that the allocation stores
+ // the size (and alignment fix), which is a shame because we know the size
+ m_begin = new wchar_t[len + 1];
+ memcpy(m_begin, begin, len * sizeof(wchar_t));
+ // Zero terminate
+ m_begin[len] = 0;
+ m_end = m_begin + len;
}
+}
- wchar_t const* OSString::end() const
- {
- return m_end ? m_end : kEmptyOSString;
- }
+static const wchar_t kEmptyOSString[] = {0};
- // UnownedStringSlice
+wchar_t const* OSString::begin() const
+{
+ return m_begin ? m_begin : kEmptyOSString;
+}
- bool UnownedStringSlice::startsWith(UnownedStringSlice const& other) const
- {
- UInt thisSize = getLength();
- UInt otherSize = other.getLength();
+wchar_t const* OSString::end() const
+{
+ return m_end ? m_end : kEmptyOSString;
+}
- if (otherSize > thisSize)
- return false;
+// UnownedStringSlice
- return head(otherSize) == other;
- }
+bool UnownedStringSlice::startsWith(UnownedStringSlice const& other) const
+{
+ UInt thisSize = getLength();
+ UInt otherSize = other.getLength();
- bool UnownedStringSlice::startsWith(char const* str) const
- {
- return startsWith(UnownedTerminatedStringSlice(str));
- }
+ if (otherSize > thisSize)
+ return false;
- bool UnownedStringSlice::startsWithCaseInsensitive(UnownedStringSlice const& other) const
- {
- UInt thisSize = getLength();
- UInt otherSize = other.getLength();
+ return head(otherSize) == other;
+}
- if (otherSize > thisSize)
- return false;
+bool UnownedStringSlice::startsWith(char const* str) const
+{
+ return startsWith(UnownedTerminatedStringSlice(str));
+}
- return head(otherSize).caseInsensitiveEquals(other);
- }
+bool UnownedStringSlice::startsWithCaseInsensitive(UnownedStringSlice const& other) const
+{
+ UInt thisSize = getLength();
+ UInt otherSize = other.getLength();
+ if (otherSize > thisSize)
+ return false;
- bool UnownedStringSlice::endsWith(UnownedStringSlice const& other) const
- {
- UInt thisSize = getLength();
- UInt otherSize = other.getLength();
+ return head(otherSize).caseInsensitiveEquals(other);
+}
- if (otherSize > thisSize)
- return false;
- return UnownedStringSlice(
- end() - otherSize, end()) == other;
- }
+bool UnownedStringSlice::endsWith(UnownedStringSlice const& other) const
+{
+ UInt thisSize = getLength();
+ UInt otherSize = other.getLength();
- bool UnownedStringSlice::endsWithCaseInsensitive(UnownedStringSlice const& other) const
- {
- UInt thisSize = getLength();
- UInt otherSize = other.getLength();
+ if (otherSize > thisSize)
+ return false;
- if (otherSize > thisSize)
- return false;
+ return UnownedStringSlice(end() - otherSize, end()) == other;
+}
- return UnownedStringSlice(end() - otherSize, end()).caseInsensitiveEquals(other);
- }
+bool UnownedStringSlice::endsWithCaseInsensitive(UnownedStringSlice const& other) const
+{
+ UInt thisSize = getLength();
+ UInt otherSize = other.getLength();
- bool UnownedStringSlice::endsWith(char const* str) const
- {
- return endsWith(UnownedTerminatedStringSlice(str));
- }
+ if (otherSize > thisSize)
+ return false;
- bool UnownedStringSlice::endsWithCaseInsensitive(char const* str) const
- {
- return endsWithCaseInsensitive(UnownedTerminatedStringSlice(str));
- }
+ return UnownedStringSlice(end() - otherSize, end()).caseInsensitiveEquals(other);
+}
- UnownedStringSlice UnownedStringSlice::trim() const
- {
- const char* start = m_begin;
- const char* end = m_end;
+bool UnownedStringSlice::endsWith(char const* str) const
+{
+ return endsWith(UnownedTerminatedStringSlice(str));
+}
- while (start < end && CharUtil::isHorizontalWhitespace(*start)) start++;
- while (end > start && CharUtil::isHorizontalWhitespace(end[-1])) end--;
- return UnownedStringSlice(start, end);
- }
+bool UnownedStringSlice::endsWithCaseInsensitive(char const* str) const
+{
+ return endsWithCaseInsensitive(UnownedTerminatedStringSlice(str));
+}
- UnownedStringSlice UnownedStringSlice::trimStart() const
- {
- const char* start = m_begin;
+UnownedStringSlice UnownedStringSlice::trim() const
+{
+ const char* start = m_begin;
+ const char* end = m_end;
+
+ while (start < end && CharUtil::isHorizontalWhitespace(*start))
+ start++;
+ while (end > start && CharUtil::isHorizontalWhitespace(end[-1]))
+ end--;
+ return UnownedStringSlice(start, end);
+}
- while (start < m_end && CharUtil::isHorizontalWhitespace(*start)) start++;
- return UnownedStringSlice(start, m_end);
- }
+UnownedStringSlice UnownedStringSlice::trimStart() const
+{
+ const char* start = m_begin;
- UnownedStringSlice UnownedStringSlice::trim(char c) const
- {
- const char* start = m_begin;
- const char* end = m_end;
+ while (start < m_end && CharUtil::isHorizontalWhitespace(*start))
+ start++;
+ return UnownedStringSlice(start, m_end);
+}
- while (start < end && *start == c) start++;
- while (end > start && end[-1] == c) end--;
- return UnownedStringSlice(start, end);
- }
+UnownedStringSlice UnownedStringSlice::trim(char c) const
+{
+ const char* start = m_begin;
+ const char* end = m_end;
+
+ while (start < end && *start == c)
+ start++;
+ while (end > start && end[-1] == c)
+ end--;
+ return UnownedStringSlice(start, end);
+}
- // StringSlice
+// StringSlice
- StringSlice::StringSlice()
- : representation(0)
- , beginIndex(0)
- , endIndex(0)
- {}
+StringSlice::StringSlice()
+ : representation(0), beginIndex(0), endIndex(0)
+{
+}
- StringSlice::StringSlice(String const& str)
- : representation(str.m_buffer)
- , beginIndex(0)
- , endIndex(str.getLength())
- {}
+StringSlice::StringSlice(String const& str)
+ : representation(str.m_buffer), beginIndex(0), endIndex(str.getLength())
+{
+}
- StringSlice::StringSlice(String const& str, UInt beginIndex, UInt endIndex)
- : representation(str.m_buffer)
- , beginIndex(beginIndex)
- , endIndex(endIndex)
- {}
+StringSlice::StringSlice(String const& str, UInt beginIndex, UInt endIndex)
+ : representation(str.m_buffer), beginIndex(beginIndex), endIndex(endIndex)
+{
+}
- //
+//
- _EndLine EndLine;
+_EndLine EndLine;
- String operator+(const char * op1, const String & op2)
- {
- String result(op1);
- result.append(op2);
- return result;
- }
+String operator+(const char* op1, const String& op2)
+{
+ String result(op1);
+ result.append(op2);
+ return result;
+}
- String operator+(const String & op1, const char * op2)
- {
- String result(op1);
- result.append(op2);
- return result;
- }
+String operator+(const String& op1, const char* op2)
+{
+ String result(op1);
+ result.append(op2);
+ return result;
+}
- String operator+(const String & op1, const String & op2)
- {
- String result(op1);
- result.append(op2);
- return result;
- }
+String operator+(const String& op1, const String& op2)
+{
+ String result(op1);
+ result.append(op2);
+ return result;
+}
- int stringToInt(const String& str, int radix)
- {
- if (str.startsWith("0x"))
- return (int)strtoll(str.getBuffer(), NULL, 16);
- else
- return (int)strtoll(str.getBuffer(), NULL, radix);
- }
- unsigned int stringToUInt(const String& str, int radix)
- {
- if (str.startsWith("0x"))
- return (unsigned int)strtoull(str.getBuffer(), NULL, 16);
- else
- return (unsigned int)strtoull(str.getBuffer(), NULL, radix);
- }
- double stringToDouble(const String& str)
- {
- return (double)strtod(str.getBuffer(), NULL);
- }
- float stringToFloat(const String& str)
- {
- return strtof(str.getBuffer(), NULL);
- }
+int stringToInt(const String& str, int radix)
+{
+ if (str.startsWith("0x"))
+ return (int)strtoll(str.getBuffer(), NULL, 16);
+ else
+ return (int)strtoll(str.getBuffer(), NULL, radix);
+}
+unsigned int stringToUInt(const String& str, int radix)
+{
+ if (str.startsWith("0x"))
+ return (unsigned int)strtoull(str.getBuffer(), NULL, 16);
+ else
+ return (unsigned int)strtoull(str.getBuffer(), NULL, radix);
+}
+double stringToDouble(const String& str)
+{
+ return (double)strtod(str.getBuffer(), NULL);
+}
+float stringToFloat(const String& str)
+{
+ return strtof(str.getBuffer(), NULL);
+}
#if 0
String String::ReplaceAll(String src, String dst) const
@@ -300,446 +304,473 @@ namespace Slang
}
#endif
- String String::fromWString(const wchar_t* wstr)
- {
- List<char> buf;
+String String::fromWString(const wchar_t* wstr)
+{
+ List<char> buf;
#ifdef _WIN32
- Slang::CharEncoding::UTF16->decode((const Byte*)wstr, (int)(wcslen(wstr) * sizeof(wchar_t)), buf);
+ Slang::CharEncoding::UTF16->decode(
+ (const Byte*)wstr,
+ (int)(wcslen(wstr) * sizeof(wchar_t)),
+ buf);
#else
- Slang::CharEncoding::UTF32->decode((const Byte*)wstr, (int)(wcslen(wstr) * sizeof(wchar_t)), buf);
+ Slang::CharEncoding::UTF32->decode(
+ (const Byte*)wstr,
+ (int)(wcslen(wstr) * sizeof(wchar_t)),
+ buf);
#endif
- return String(buf.begin(), buf.end());
- }
+ return String(buf.begin(), buf.end());
+}
- String String::fromWString(const wchar_t* wstr, const wchar_t* wend)
- {
- List<char> buf;
+String String::fromWString(const wchar_t* wstr, const wchar_t* wend)
+{
+ List<char> buf;
#ifdef _WIN32
- Slang::CharEncoding::UTF16->decode((const Byte*)wstr, (int)((wend - wstr) * sizeof(wchar_t)), buf);
+ Slang::CharEncoding::UTF16->decode(
+ (const Byte*)wstr,
+ (int)((wend - wstr) * sizeof(wchar_t)),
+ buf);
#else
- Slang::CharEncoding::UTF32->decode((const Byte*)wstr, (int)((wend - wstr) * sizeof(wchar_t)), buf);
+ Slang::CharEncoding::UTF32->decode(
+ (const Byte*)wstr,
+ (int)((wend - wstr) * sizeof(wchar_t)),
+ buf);
#endif
- return String(buf.begin(), buf.end());
- }
+ return String(buf.begin(), buf.end());
+}
- String String::fromWChar(const wchar_t ch)
- {
- List<char> buf;
+String String::fromWChar(const wchar_t ch)
+{
+ List<char> buf;
#ifdef _WIN32
- Slang::CharEncoding::UTF16->decode((const Byte*)&ch, (int)(sizeof(wchar_t)), buf);
+ Slang::CharEncoding::UTF16->decode((const Byte*)&ch, (int)(sizeof(wchar_t)), buf);
#else
- Slang::CharEncoding::UTF32->decode((const Byte*)&ch, (int)(sizeof(wchar_t)), buf);
+ Slang::CharEncoding::UTF32->decode((const Byte*)&ch, (int)(sizeof(wchar_t)), buf);
#endif
- return String(buf.begin(), buf.end());
- }
+ return String(buf.begin(), buf.end());
+}
+
+/* static */ String String::fromUnicodePoint(Char32 codePoint)
+{
+ char buf[6];
+ int len = Slang::encodeUnicodePointToUTF8(codePoint, buf);
+ return String(buf, buf + len);
+}
- /* static */String String::fromUnicodePoint(Char32 codePoint)
+OSString String::toWString(Index* outLength) const
+{
+ if (!m_buffer)
{
- char buf[6];
- int len = Slang::encodeUnicodePointToUTF8(codePoint, buf);
- return String(buf, buf + len);
+ return OSString();
}
-
- OSString String::toWString(Index* outLength) const
+ else
{
- if (!m_buffer)
+ List<Byte> buf;
+ switch (sizeof(wchar_t))
{
- return OSString();
- }
- else
- {
- List<Byte> buf;
- switch(sizeof(wchar_t))
- {
- case 2:
- Slang::CharEncoding::UTF16->encode(getUnownedSlice(), buf);
- break;
+ case 2: Slang::CharEncoding::UTF16->encode(getUnownedSlice(), buf); break;
- case 4:
- Slang::CharEncoding::UTF32->encode(getUnownedSlice(), buf);
- break;
+ case 4: Slang::CharEncoding::UTF32->encode(getUnownedSlice(), buf); break;
- default:
- break;
- }
+ default: break;
+ }
- auto length = Index(buf.getCount() / sizeof(wchar_t));
- if (outLength)
- *outLength = length;
+ auto length = Index(buf.getCount() / sizeof(wchar_t));
+ if (outLength)
+ *outLength = length;
- for(size_t ii = 0; ii < sizeof(wchar_t); ++ii)
- buf.add(0);
+ for (size_t ii = 0; ii < sizeof(wchar_t); ++ii)
+ buf.add(0);
- wchar_t* beginData = (wchar_t*)buf.getBuffer();
- wchar_t* endData = beginData + length;
+ wchar_t* beginData = (wchar_t*)buf.getBuffer();
+ wchar_t* endData = beginData + length;
- OSString ret;
- ret.set(beginData, endData);
- return ret;
- }
+ OSString ret;
+ ret.set(beginData, endData);
+ return ret;
}
+}
+
+//
- //
+void String::ensureUniqueStorageWithCapacity(Index requiredCapacity)
+{
+ if (m_buffer && m_buffer->isUniquelyReferenced() && m_buffer->capacity >= requiredCapacity)
+ return;
- void String::ensureUniqueStorageWithCapacity(Index requiredCapacity)
+ Index newCapacity = m_buffer ? 2 * m_buffer->capacity : 16;
+ if (newCapacity < requiredCapacity)
{
- if (m_buffer && m_buffer->isUniquelyReferenced() && m_buffer->capacity >= requiredCapacity)
- return;
+ newCapacity = requiredCapacity;
+ }
- Index newCapacity = m_buffer ? 2 * m_buffer->capacity : 16;
- if (newCapacity < requiredCapacity)
- {
- newCapacity = requiredCapacity;
- }
+ Index length = getLength();
+ StringRepresentation* newRepresentation =
+ StringRepresentation::createWithCapacityAndLength(newCapacity, length);
- Index length = getLength();
- StringRepresentation* newRepresentation = StringRepresentation::createWithCapacityAndLength(newCapacity, length);
+ if (m_buffer)
+ {
+ memcpy(newRepresentation->getData(), m_buffer->getData(), length + 1);
+ }
- if (m_buffer)
- {
- memcpy(newRepresentation->getData(), m_buffer->getData(), length + 1);
- }
+ m_buffer = newRepresentation;
+}
- m_buffer = newRepresentation;
- }
+char* String::prepareForAppend(Index count)
+{
+ auto oldLength = getLength();
+ auto newLength = oldLength + count;
+ ensureUniqueStorageWithCapacity(newLength);
+ return getData() + oldLength;
+}
+void String::appendInPlace(const char* chars, Index count)
+{
+ SLANG_UNUSED(chars);
- char* String::prepareForAppend(Index count)
+ if (count > 0)
{
+ SLANG_ASSERT(m_buffer && m_buffer->isUniquelyReferenced());
+
auto oldLength = getLength();
auto newLength = oldLength + count;
- ensureUniqueStorageWithCapacity(newLength);
- return getData() + oldLength;
- }
- void String::appendInPlace(const char* chars, Index count)
- {
- SLANG_UNUSED(chars);
-
- if (count > 0)
- {
- SLANG_ASSERT(m_buffer && m_buffer->isUniquelyReferenced());
-
- auto oldLength = getLength();
- auto newLength = oldLength + count;
- char* dst = m_buffer->getData();
+ char* dst = m_buffer->getData();
- // Make sure the input buffer is the same one returned from prepareForAppend
- SLANG_ASSERT(chars == dst + oldLength);
- // It has to fit within the capacity
- SLANG_ASSERT(newLength <= m_buffer->capacity);
+ // Make sure the input buffer is the same one returned from prepareForAppend
+ SLANG_ASSERT(chars == dst + oldLength);
+ // It has to fit within the capacity
+ SLANG_ASSERT(newLength <= m_buffer->capacity);
- // We just need to modify the length
- m_buffer->length = newLength;
+ // We just need to modify the length
+ m_buffer->length = newLength;
- // And mark with a terminating 0
- dst[newLength] = 0;
- }
+ // And mark with a terminating 0
+ dst[newLength] = 0;
}
+}
- void String::reduceLength(Index newLength)
+void String::reduceLength(Index newLength)
+{
+ Index oldLength = getLength();
+ SLANG_ASSERT(newLength <= oldLength);
+ if (oldLength == newLength)
{
- Index oldLength = getLength();
- SLANG_ASSERT(newLength <= oldLength);
- if (oldLength == newLength)
- {
- return;
- }
+ return;
+ }
- // It must have a buffer, because only 0 length allows for nullptr
- // and being 0 sized is already covered
- SLANG_ASSERT(m_buffer);
+ // It must have a buffer, because only 0 length allows for nullptr
+ // and being 0 sized is already covered
+ SLANG_ASSERT(m_buffer);
- if (m_buffer->isUniquelyReferenced())
+ if (m_buffer->isUniquelyReferenced())
+ {
+ m_buffer->length = newLength;
+ m_buffer->getData()[newLength] = 0;
+ }
+ else
+ {
+ // If 0 length is wanted we can just free
+ if (newLength == 0)
{
- m_buffer->length = newLength;
- m_buffer->getData()[newLength] = 0;
+ m_buffer.setNull();
}
else
{
- // If 0 length is wanted we can just free
- if (newLength == 0)
- {
- m_buffer.setNull();
- }
- else
- {
- // We need to make a new copy, that we will shrink
+ // We need to make a new copy, that we will shrink
- // We'll just go with capacity enough for the new length
- const Index newCapacity = newLength;
- StringRepresentation* newRepresentation = StringRepresentation::createWithCapacityAndLength(newCapacity, newLength);
+ // We'll just go with capacity enough for the new length
+ const Index newCapacity = newLength;
+ StringRepresentation* newRepresentation =
+ StringRepresentation::createWithCapacityAndLength(newCapacity, newLength);
- // Copy
- char* dst = newRepresentation->getData();
- memcpy(dst, m_buffer->getData(), sizeof(char) * newLength);
- // Zero terminate
- dst[newLength] = 0;
+ // Copy
+ char* dst = newRepresentation->getData();
+ memcpy(dst, m_buffer->getData(), sizeof(char) * newLength);
+ // Zero terminate
+ dst[newLength] = 0;
- // Set the new rep
- m_buffer = newRepresentation;
- }
+ // Set the new rep
+ m_buffer = newRepresentation;
}
}
+}
- void String::append(char const* str, size_t len)
- {
- append(str, str + len);
- }
+void String::append(char const* str, size_t len)
+{
+ append(str, str + len);
+}
- void String::append(const char* textBegin, char const* textEnd)
- {
- auto oldLength = getLength();
- auto textLength = textEnd - textBegin;
- if (textLength <= 0)
- return;
+void String::append(const char* textBegin, char const* textEnd)
+{
+ auto oldLength = getLength();
+ auto textLength = textEnd - textBegin;
+ if (textLength <= 0)
+ return;
- auto newLength = oldLength + textLength;
+ auto newLength = oldLength + textLength;
- ensureUniqueStorageWithCapacity(newLength);
+ ensureUniqueStorageWithCapacity(newLength);
- memcpy(getData() + oldLength, textBegin, textLength);
- getData()[newLength] = 0;
- m_buffer->length = newLength;
- }
+ memcpy(getData() + oldLength, textBegin, textLength);
+ getData()[newLength] = 0;
+ m_buffer->length = newLength;
+}
- void String::append(char const* str)
+void String::append(char const* str)
+{
+ if (str)
{
- if (str)
- {
- append(str, str + strlen(str));
- }
+ append(str, str + strlen(str));
}
+}
- void String::appendRepeatedChar(char chr, Index count)
+void String::appendRepeatedChar(char chr, Index count)
+{
+ SLANG_ASSERT(count >= 0);
+ if (count > 0)
{
- SLANG_ASSERT(count >= 0);
- if (count > 0)
- {
- char* chars = prepareForAppend(count);
- // Set all space to repeated chr.
- ::memset(chars, chr, sizeof(char) * count);
- appendInPlace(chars, count);
- }
+ char* chars = prepareForAppend(count);
+ // Set all space to repeated chr.
+ ::memset(chars, chr, sizeof(char) * count);
+ appendInPlace(chars, count);
}
+}
- void String::appendChar(char c)
- {
- const auto oldLength = getLength();
- const auto newLength = oldLength + 1;
+void String::appendChar(char c)
+{
+ const auto oldLength = getLength();
+ const auto newLength = oldLength + 1;
- ensureUniqueStorageWithCapacity(newLength);
+ ensureUniqueStorageWithCapacity(newLength);
- // Since there must be space for at least one character, m_buffer cannot be nullptr
- SLANG_ASSERT(m_buffer);
- char* data = m_buffer->getData();
- data[oldLength] = c;
- data[newLength] = 0;
+ // Since there must be space for at least one character, m_buffer cannot be nullptr
+ SLANG_ASSERT(m_buffer);
+ char* data = m_buffer->getData();
+ data[oldLength] = c;
+ data[newLength] = 0;
- m_buffer->length = newLength;
- }
+ m_buffer->length = newLength;
+}
- void String::append(char chr)
+void String::append(char chr)
+{
+ appendChar(chr);
+}
+
+void String::append(String const& str)
+{
+ if (!m_buffer)
{
- appendChar(chr);
+ m_buffer = str.m_buffer;
+ return;
}
- void String::append(String const& str)
- {
- if (!m_buffer)
- {
- m_buffer = str.m_buffer;
- return;
- }
+ append(str.begin(), str.end());
+}
- append(str.begin(), str.end());
- }
+void String::append(StringSlice const& slice)
+{
+ append(slice.begin(), slice.end());
+}
- void String::append(StringSlice const& slice)
- {
- append(slice.begin(), slice.end());
- }
+void String::append(UnownedStringSlice const& slice)
+{
+ append(slice.begin(), slice.end());
+}
- void String::append(UnownedStringSlice const& slice)
+void String::append(int32_t value, int radix)
+{
+ enum
{
- append(slice.begin(), slice.end());
- }
+ kCount = 33
+ };
+ char* data = prepareForAppend(kCount);
+ const auto count = intToAscii(data, value, radix);
+ m_buffer->length += count;
+}
- void String::append(int32_t value, int radix)
+void String::append(uint32_t value, int radix)
+{
+ enum
{
- enum { kCount = 33 };
- char* data = prepareForAppend(kCount);
- const auto count = intToAscii(data, value, radix);
- m_buffer->length += count;
- }
+ kCount = 33
+ };
+ char* data = prepareForAppend(kCount);
+ const auto count = intToAscii(data, value, radix);
+ m_buffer->length += count;
+}
- void String::append(uint32_t value, int radix)
+void String::append(int64_t value, int radix)
+{
+ enum
{
- enum { kCount = 33 };
- char* data = prepareForAppend(kCount);
- const auto count = intToAscii(data, value, radix);
- m_buffer->length += count;
- }
+ kCount = 65
+ };
+ char* data = prepareForAppend(kCount);
+ auto count = intToAscii(data, value, radix);
+ m_buffer->length += count;
+}
- void String::append(int64_t value, int radix)
+void String::append(uint64_t value, int radix)
+{
+ enum
{
- enum { kCount = 65 };
- char* data = prepareForAppend(kCount);
- auto count = intToAscii(data, value, radix);
- m_buffer->length += count;
- }
+ kCount = 65
+ };
+ char* data = prepareForAppend(kCount);
+ auto count = intToAscii(data, value, radix);
+ m_buffer->length += count;
+}
- void String::append(uint64_t value, int radix)
+void String::append(float val, const char* format)
+{
+ enum
{
- enum { kCount = 65 };
- char* data = prepareForAppend(kCount);
- auto count = intToAscii(data, value, radix);
- m_buffer->length += count;
- }
+ kCount = 128
+ };
+ char* data = prepareForAppend(kCount);
+ sprintf_s(data, kCount, format, val);
+ m_buffer->length += strnlen_s(data, kCount);
+}
- void String::append(float val, const char* format)
+void String::append(double val, const char* format)
+{
+ enum
{
- enum { kCount = 128 };
- char* data = prepareForAppend(kCount);
- sprintf_s(data, kCount, format, val);
- m_buffer->length += strnlen_s(data, kCount);
- }
+ kCount = 128
+ };
+ char* data = prepareForAppend(kCount);
+ sprintf_s(data, kCount, format, val);
+ m_buffer->length += strnlen_s(data, kCount);
+}
+
+void String::append(StableHashCode32 value)
+{
+ const Index digits = 8;
+ // + null terminator
+ char* data = prepareForAppend(digits + 1);
+ auto count = intToAscii(data, value.hash, 16, digits);
+ m_buffer->length += count;
+}
- void String::append(double val, const char* format)
+void String::append(StableHashCode64 value)
+{
+ const Index digits = 16;
+ // + null terminator
+ char* data = prepareForAppend(digits + 1);
+ auto count = intToAscii(data, value.hash, 16, digits);
+ m_buffer->length += count;
+}
+
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! UnownedStringSlice !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+Index UnownedStringSlice::indexOf(char c) const
+{
+ const Index size = Index(m_end - m_begin);
+ for (Index i = 0; i < size; ++i)
{
- enum { kCount = 128 };
- char* data = prepareForAppend(kCount);
- sprintf_s(data, kCount, format, val);
- m_buffer->length += strnlen_s(data, kCount);
+ if (m_begin[i] == c)
+ {
+ return i;
+ }
}
+ return -1;
+}
- void String::append(StableHashCode32 value)
+Index UnownedStringSlice::indexOf(const UnownedStringSlice& in) const
+{
+ const Index len = getLength();
+ const Index inLen = in.getLength();
+ if (inLen > len)
{
- const Index digits = 8;
- // + null terminator
- char* data = prepareForAppend(digits + 1);
- auto count = intToAscii(data, value.hash, 16, digits);
- m_buffer->length += count;
+ return -1;
}
- void String::append(StableHashCode64 value)
+ const char* inChars = in.m_begin;
+ switch (inLen)
{
- const Index digits = 16;
- // + null terminator
- char* data = prepareForAppend(digits + 1);
- auto count = intToAscii(data, value.hash, 16, digits);
- m_buffer->length += count;
+ case 0: return 0;
+ case 1: return indexOf(inChars[0]);
+ default: break;
}
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! UnownedStringSlice !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ const char* chars = m_begin;
+ const char firstChar = inChars[0];
- Index UnownedStringSlice::indexOf(char c) const
+ for (Int i = 0; i <= len - inLen; ++i)
{
- const Index size = Index(m_end - m_begin);
- for (Index i = 0; i < size; ++i)
+ if (chars[i] == firstChar && in == UnownedStringSlice(chars + i, inLen))
{
- if (m_begin[i] == c)
- {
- return i;
- }
+ return i;
}
- return -1;
}
- Index UnownedStringSlice::indexOf(const UnownedStringSlice& in) const
- {
- const Index len = getLength();
- const Index inLen = in.getLength();
- if (inLen > len)
- {
- return -1;
- }
+ return -1;
+}
- const char* inChars = in.m_begin;
- switch (inLen)
- {
- case 0: return 0;
- case 1: return indexOf(inChars[0]);
- default: break;
- }
+UnownedStringSlice UnownedStringSlice::subString(Index idx, Index len) const
+{
+ const Index totalLen = getLength();
+ SLANG_ASSERT(idx >= 0 && len >= 0 && idx <= totalLen);
- const char* chars = m_begin;
- const char firstChar = inChars[0];
+ // If too large, we truncate
+ len = (idx + len > totalLen) ? (totalLen - idx) : len;
- for (Int i = 0; i <= len - inLen; ++i)
- {
- if (chars[i] == firstChar && in == UnownedStringSlice(chars + i, inLen))
- {
- return i;
- }
- }
+ // Return the substring
+ return UnownedStringSlice(m_begin + idx, m_begin + idx + len);
+}
- return -1;
- }
+bool UnownedStringSlice::operator==(ThisType const& other) const
+{
+ // Note that memcmp is undefined when passed in null ptrs, so if we want to handle
+ // we need to cover that case.
+ // Can only be nullptr if size is 0.
+ auto thisSize = getLength();
+ auto otherSize = other.getLength();
- UnownedStringSlice UnownedStringSlice::subString(Index idx, Index len) const
+ if (thisSize != otherSize)
{
- const Index totalLen = getLength();
- SLANG_ASSERT(idx >= 0 && len >= 0 && idx <= totalLen);
-
- // If too large, we truncate
- len = (idx + len > totalLen) ? (totalLen - idx) : len;
-
- // Return the substring
- return UnownedStringSlice(m_begin + idx, m_begin + idx + len);
+ return false;
}
- bool UnownedStringSlice::operator==(ThisType const& other) const
+ const char* const thisChars = begin();
+ const char* const otherChars = other.begin();
+ if (thisChars == otherChars || thisSize == 0)
{
- // Note that memcmp is undefined when passed in null ptrs, so if we want to handle
- // we need to cover that case.
- // Can only be nullptr if size is 0.
- auto thisSize = getLength();
- auto otherSize = other.getLength();
-
- if (thisSize != otherSize)
- {
- return false;
- }
-
- const char*const thisChars = begin();
- const char*const otherChars = other.begin();
- if (thisChars == otherChars || thisSize == 0)
- {
- return true;
- }
- SLANG_ASSERT(thisChars && otherChars);
- return memcmp(thisChars, otherChars, thisSize) == 0;
+ return true;
}
+ SLANG_ASSERT(thisChars && otherChars);
+ return memcmp(thisChars, otherChars, thisSize) == 0;
+}
- bool UnownedStringSlice::caseInsensitiveEquals(const ThisType& rhs) const
+bool UnownedStringSlice::caseInsensitiveEquals(const ThisType& rhs) const
+{
+ const auto length = getLength();
+ if (length != rhs.getLength())
{
- const auto length = getLength();
- if (length != rhs.getLength())
- {
- return false;
- }
+ return false;
+ }
- const char* a = m_begin;
- const char* b = rhs.m_begin;
+ const char* a = m_begin;
+ const char* b = rhs.m_begin;
- // Assuming this is a faster test
- if (memcmp(a, b, length) != 0)
+ // Assuming this is a faster test
+ if (memcmp(a, b, length) != 0)
+ {
+ // They aren't identical so compare character by character
+ for (Index i = 0; i < length; ++i)
{
- // They aren't identical so compare character by character
- for (Index i = 0; i < length; ++i)
+ if (CharUtil::toLower(a[i]) != CharUtil::toLower(b[i]))
{
- if (CharUtil::toLower(a[i]) != CharUtil::toLower(b[i]))
- {
- return false;
- }
+ return false;
}
}
-
- return true;
}
+
+ return true;
}
+} // namespace Slang
-std::ostream& operator<< (std::ostream& stream, const Slang::String& s)
+std::ostream& operator<<(std::ostream& stream, const Slang::String& s)
{
stream << s.getBuffer();
return stream;