diff options
Diffstat (limited to 'client/asmjit/core/string.cpp')
| -rw-r--r-- | client/asmjit/core/string.cpp | 551 |
1 files changed, 0 insertions, 551 deletions
diff --git a/client/asmjit/core/string.cpp b/client/asmjit/core/string.cpp deleted file mode 100644 index e059884..0000000 --- a/client/asmjit/core/string.cpp +++ /dev/null @@ -1,551 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/string.h" -#include "../core/support.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::String - Globals] -// ============================================================================ - -static const char String_baseN[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -constexpr size_t kMinAllocSize = 64; -constexpr size_t kMaxAllocSize = SIZE_MAX - Globals::kGrowThreshold; - -// ============================================================================ -// [asmjit::String] -// ============================================================================ - -Error String::reset() noexcept { - if (_type == kTypeLarge) - ::free(_large.data); - - _resetInternal(); - return kErrorOk; -} - -Error String::clear() noexcept { - if (isLarge()) { - _large.size = 0; - _large.data[0] = '\0'; - } - else { - _raw.uptr[0] = 0; - } - - return kErrorOk; -} - -char* String::prepare(uint32_t op, size_t size) noexcept { - char* curData; - size_t curSize; - size_t curCapacity; - - if (isLarge()) { - curData = this->_large.data; - curSize = this->_large.size; - curCapacity = this->_large.capacity; - } - else { - curData = this->_small.data; - curSize = this->_small.type; - curCapacity = kSSOCapacity; - } - - if (op == kOpAssign) { - if (size > curCapacity) { - // Prevent arithmetic overflow. - if (ASMJIT_UNLIKELY(size >= kMaxAllocSize)) - return nullptr; - - size_t newCapacity = Support::alignUp<size_t>(size + 1, kMinAllocSize); - char* newData = static_cast<char*>(::malloc(newCapacity)); - - if (ASMJIT_UNLIKELY(!newData)) - return nullptr; - - if (_type == kTypeLarge) - ::free(curData); - - _large.type = kTypeLarge; - _large.size = size; - _large.capacity = newCapacity - 1; - _large.data = newData; - - newData[size] = '\0'; - return newData; - } - else { - _setSize(size); - curData[size] = '\0'; - return curData; - } - } - else { - // Prevent arithmetic overflow. - if (ASMJIT_UNLIKELY(size >= kMaxAllocSize - curSize)) - return nullptr; - - size_t newSize = size + curSize; - size_t newSizePlusOne = newSize + 1; - - if (newSizePlusOne > curCapacity) { - size_t newCapacity = Support::max<size_t>(curCapacity + 1, kMinAllocSize); - - if (newCapacity < newSizePlusOne && newCapacity < Globals::kGrowThreshold) - newCapacity = Support::alignUpPowerOf2(newCapacity); - - if (newCapacity < newSizePlusOne) - newCapacity = Support::alignUp(newSizePlusOne, Globals::kGrowThreshold); - - if (ASMJIT_UNLIKELY(newCapacity < newSizePlusOne)) - return nullptr; - - char* newData = static_cast<char*>(::malloc(newCapacity)); - if (ASMJIT_UNLIKELY(!newData)) - return nullptr; - - memcpy(newData, curData, curSize); - - if (_type == kTypeLarge) - ::free(curData); - - _large.type = kTypeLarge; - _large.size = newSize; - _large.capacity = newCapacity - 1; - _large.data = newData; - - newData[newSize] = '\0'; - return newData + curSize; - } - else { - _setSize(newSize); - curData[newSize] = '\0'; - return curData + curSize; - } - } -} - -Error String::assign(const char* data, size_t size) noexcept { - char* dst = nullptr; - - // Null terminated string without `size` specified. - if (size == SIZE_MAX) - size = data ? strlen(data) : size_t(0); - - if (isLarge()) { - if (size <= _large.capacity) { - dst = _large.data; - _large.size = size; - } - else { - size_t capacityPlusOne = Support::alignUp(size + 1, 32); - if (ASMJIT_UNLIKELY(capacityPlusOne < size)) - return DebugUtils::errored(kErrorOutOfMemory); - - dst = static_cast<char*>(::malloc(capacityPlusOne)); - if (ASMJIT_UNLIKELY(!dst)) - return DebugUtils::errored(kErrorOutOfMemory); - - if (!isExternal()) - ::free(_large.data); - - _large.type = kTypeLarge; - _large.data = dst; - _large.size = size; - _large.capacity = capacityPlusOne - 1; - } - } - else { - if (size <= kSSOCapacity) { - ASMJIT_ASSERT(size < 0xFFu); - - dst = _small.data; - _small.type = uint8_t(size); - } - else { - dst = static_cast<char*>(::malloc(size + 1)); - if (ASMJIT_UNLIKELY(!dst)) - return DebugUtils::errored(kErrorOutOfMemory); - - _large.type = kTypeLarge; - _large.data = dst; - _large.size = size; - _large.capacity = size; - } - } - - // Optionally copy data from `data` and null-terminate. - if (data && size) { - // NOTE: It's better to use `memmove()`. If, for any reason, somebody uses - // this function to substring the same string it would work as expected. - ::memmove(dst, data, size); - } - - dst[size] = '\0'; - return kErrorOk; -} - -// ============================================================================ -// [asmjit::String - Operations] -// ============================================================================ - -Error String::_opString(uint32_t op, const char* str, size_t size) noexcept { - if (size == SIZE_MAX) - size = str ? strlen(str) : size_t(0); - - if (!size) - return kErrorOk; - - char* p = prepare(op, size); - if (!p) - return DebugUtils::errored(kErrorOutOfMemory); - - memcpy(p, str, size); - return kErrorOk; -} - -Error String::_opChar(uint32_t op, char c) noexcept { - char* p = prepare(op, 1); - if (!p) - return DebugUtils::errored(kErrorOutOfMemory); - - *p = c; - return kErrorOk; -} - -Error String::_opChars(uint32_t op, char c, size_t n) noexcept { - if (!n) - return kErrorOk; - - char* p = prepare(op, n); - if (!p) - return DebugUtils::errored(kErrorOutOfMemory); - - memset(p, c, n); - return kErrorOk; -} - -Error String::padEnd(size_t n, char c) noexcept { - size_t size = this->size(); - return n > size ? appendChars(c, n - size) : kErrorOk; -} - -Error String::_opNumber(uint32_t op, uint64_t i, uint32_t base, size_t width, uint32_t flags) noexcept { - if (base < 2 || base > 36) - base = 10; - - char buf[128]; - char* p = buf + ASMJIT_ARRAY_SIZE(buf); - - uint64_t orig = i; - char sign = '\0'; - - // -------------------------------------------------------------------------- - // [Sign] - // -------------------------------------------------------------------------- - - if ((flags & kFormatSigned) != 0 && int64_t(i) < 0) { - i = uint64_t(-int64_t(i)); - sign = '-'; - } - else if ((flags & kFormatShowSign) != 0) { - sign = '+'; - } - else if ((flags & kFormatShowSpace) != 0) { - sign = ' '; - } - - // -------------------------------------------------------------------------- - // [Number] - // -------------------------------------------------------------------------- - - do { - uint64_t d = i / base; - uint64_t r = i % base; - - *--p = String_baseN[r]; - i = d; - } while (i); - - size_t numberSize = (size_t)(buf + ASMJIT_ARRAY_SIZE(buf) - p); - - // -------------------------------------------------------------------------- - // [Alternate Form] - // -------------------------------------------------------------------------- - - if ((flags & kFormatAlternate) != 0) { - if (base == 8) { - if (orig != 0) - *--p = '0'; - } - if (base == 16) { - *--p = 'x'; - *--p = '0'; - } - } - - // -------------------------------------------------------------------------- - // [Width] - // -------------------------------------------------------------------------- - - if (sign != 0) - *--p = sign; - - if (width > 256) - width = 256; - - if (width <= numberSize) - width = 0; - else - width -= numberSize; - - // -------------------------------------------------------------------------- - // Write] - // -------------------------------------------------------------------------- - - size_t prefixSize = (size_t)(buf + ASMJIT_ARRAY_SIZE(buf) - p) - numberSize; - char* data = prepare(op, prefixSize + width + numberSize); - - if (!data) - return DebugUtils::errored(kErrorOutOfMemory); - - memcpy(data, p, prefixSize); - data += prefixSize; - - memset(data, '0', width); - data += width; - - memcpy(data, p + prefixSize, numberSize); - return kErrorOk; -} - -Error String::_opHex(uint32_t op, const void* data, size_t size, char separator) noexcept { - char* dst; - const uint8_t* src = static_cast<const uint8_t*>(data); - - if (!size) - return kErrorOk; - - if (separator) { - if (ASMJIT_UNLIKELY(size >= SIZE_MAX / 3)) - return DebugUtils::errored(kErrorOutOfMemory); - - dst = prepare(op, size * 3 - 1); - if (ASMJIT_UNLIKELY(!dst)) - return DebugUtils::errored(kErrorOutOfMemory); - - size_t i = 0; - for (;;) { - dst[0] = String_baseN[(src[0] >> 4) & 0xF]; - dst[1] = String_baseN[(src[0] ) & 0xF]; - if (++i == size) - break; - // This makes sure that the separator is only put between two hexadecimal bytes. - dst[2] = separator; - dst += 3; - src++; - } - } - else { - if (ASMJIT_UNLIKELY(size >= SIZE_MAX / 2)) - return DebugUtils::errored(kErrorOutOfMemory); - - dst = prepare(op, size * 2); - if (ASMJIT_UNLIKELY(!dst)) - return DebugUtils::errored(kErrorOutOfMemory); - - for (size_t i = 0; i < size; i++, dst += 2, src++) { - dst[0] = String_baseN[(src[0] >> 4) & 0xF]; - dst[1] = String_baseN[(src[0] ) & 0xF]; - } - } - - return kErrorOk; -} - -Error String::_opFormat(uint32_t op, const char* fmt, ...) noexcept { - Error err; - va_list ap; - - va_start(ap, fmt); - err = _opVFormat(op, fmt, ap); - va_end(ap); - - return err; -} - -Error String::_opVFormat(uint32_t op, const char* fmt, va_list ap) noexcept { - size_t startAt = (op == kOpAssign) ? size_t(0) : size(); - size_t remainingCapacity = capacity() - startAt; - - char buf[1024]; - int fmtResult; - size_t outputSize; - - va_list apCopy; - va_copy(apCopy, ap); - - if (remainingCapacity >= 128) { - fmtResult = vsnprintf(data() + startAt, remainingCapacity, fmt, ap); - outputSize = size_t(fmtResult); - - if (ASMJIT_LIKELY(outputSize <= remainingCapacity)) { - _setSize(startAt + outputSize); - return kErrorOk; - } - } - else { - fmtResult = vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf), fmt, ap); - outputSize = size_t(fmtResult); - - if (ASMJIT_LIKELY(outputSize < ASMJIT_ARRAY_SIZE(buf))) - return _opString(op, buf, outputSize); - } - - if (ASMJIT_UNLIKELY(fmtResult < 0)) - return DebugUtils::errored(kErrorInvalidState); - - char* p = prepare(op, outputSize); - if (ASMJIT_UNLIKELY(!p)) - return DebugUtils::errored(kErrorOutOfMemory); - - fmtResult = vsnprintf(p, outputSize + 1, fmt, apCopy); - ASMJIT_ASSERT(size_t(fmtResult) == outputSize); - - return kErrorOk; -} - -Error String::truncate(size_t newSize) noexcept { - if (isLarge()) { - if (newSize < _large.size) { - _large.data[newSize] = '\0'; - _large.size = newSize; - } - } - else { - if (newSize < _type) { - _small.data[newSize] = '\0'; - _small.type = uint8_t(newSize); - } - } - - return kErrorOk; -} - -bool String::eq(const char* other, size_t size) const noexcept { - const char* aData = data(); - const char* bData = other; - - size_t aSize = this->size(); - size_t bSize = size; - - if (bSize == SIZE_MAX) { - size_t i; - for (i = 0; i < aSize; i++) - if (aData[i] != bData[i] || bData[i] == 0) - return false; - return bData[i] == 0; - } - else { - if (aSize != bSize) - return false; - return ::memcmp(aData, bData, aSize) == 0; - } -} - -// ============================================================================ -// [asmjit::Support - Unit] -// ============================================================================ - -#if defined(ASMJIT_TEST) -UNIT(core_string) { - String s; - - EXPECT(s.isLarge() == false); - EXPECT(s.isExternal() == false); - - EXPECT(s.assign('a') == kErrorOk); - EXPECT(s.size() == 1); - EXPECT(s.capacity() == String::kSSOCapacity); - EXPECT(s.data()[0] == 'a'); - EXPECT(s.data()[1] == '\0'); - EXPECT(s.eq("a") == true); - EXPECT(s.eq("a", 1) == true); - - EXPECT(s.assignChars('b', 4) == kErrorOk); - EXPECT(s.size() == 4); - EXPECT(s.capacity() == String::kSSOCapacity); - EXPECT(s.data()[0] == 'b'); - EXPECT(s.data()[1] == 'b'); - EXPECT(s.data()[2] == 'b'); - EXPECT(s.data()[3] == 'b'); - EXPECT(s.data()[4] == '\0'); - EXPECT(s.eq("bbbb") == true); - EXPECT(s.eq("bbbb", 4) == true); - - EXPECT(s.assign("abc") == kErrorOk); - EXPECT(s.size() == 3); - EXPECT(s.capacity() == String::kSSOCapacity); - EXPECT(s.data()[0] == 'a'); - EXPECT(s.data()[1] == 'b'); - EXPECT(s.data()[2] == 'c'); - EXPECT(s.data()[3] == '\0'); - EXPECT(s.eq("abc") == true); - EXPECT(s.eq("abc", 3) == true); - - const char* large = "Large string that will not fit into SSO buffer"; - EXPECT(s.assign(large) == kErrorOk); - EXPECT(s.isLarge() == true); - EXPECT(s.size() == strlen(large)); - EXPECT(s.capacity() > String::kSSOCapacity); - EXPECT(s.eq(large) == true); - EXPECT(s.eq(large, strlen(large)) == true); - - const char* additional = " (additional content)"; - EXPECT(s.isLarge() == true); - EXPECT(s.append(additional) == kErrorOk); - EXPECT(s.size() == strlen(large) + strlen(additional)); - - EXPECT(s.clear() == kErrorOk); - EXPECT(s.size() == 0); - EXPECT(s.empty() == true); - EXPECT(s.data()[0] == '\0'); - EXPECT(s.isLarge() == true); // Clear should never release the memory. - - EXPECT(s.appendUInt(1234) == kErrorOk); - EXPECT(s.eq("1234") == true); - - StringTmp<64> sTmp; - EXPECT(sTmp.isLarge()); - EXPECT(sTmp.isExternal()); - EXPECT(sTmp.appendChars(' ', 1000) == kErrorOk); - EXPECT(!sTmp.isExternal()); -} -#endif - -ASMJIT_END_NAMESPACE |