diff options
Diffstat (limited to 'libs/distrho/extra/d_string.hpp')
-rw-r--r-- | libs/distrho/extra/d_string.hpp | 750 |
1 files changed, 0 insertions, 750 deletions
diff --git a/libs/distrho/extra/d_string.hpp b/libs/distrho/extra/d_string.hpp deleted file mode 100644 index 0420c42..0000000 --- a/libs/distrho/extra/d_string.hpp +++ /dev/null @@ -1,750 +0,0 @@ -/* - * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> - * - * Permission to use, copy, modify, and/or distribute this software for any purpose with - * or without fee is hereby granted, provided that the above copyright notice and this - * permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef DISTRHO_STRING_HPP_INCLUDED -#define DISTRHO_STRING_HPP_INCLUDED - -#include "d_leakdetector.hpp" - -START_NAMESPACE_DISTRHO - -// ----------------------------------------------------------------------- -// d_string class - -class d_string -{ -public: - // ------------------------------------------------------------------- - // constructors (no explicit conversions allowed) - - /* - * Empty string. - */ - explicit d_string() noexcept - { - _init(); - } - - /* - * Simple character. - */ - explicit d_string(const char c) noexcept - { - char ch[2]; - ch[0] = c; - ch[1] = '\0'; - - _init(); - _dup(ch); - } - - /* - * Simple char string. - */ - explicit d_string(char* const strBuf) noexcept - { - _init(); - _dup(strBuf); - } - - /* - * Simple const char string. - */ - explicit d_string(const char* const strBuf) noexcept - { - _init(); - _dup(strBuf); - } - - /* - * Integer. - */ - explicit d_string(const int value) noexcept - { - char strBuf[0xff+1]; - std::snprintf(strBuf, 0xff, "%d", value); - strBuf[0xff] = '\0'; - - _init(); - _dup(strBuf); - } - - /* - * Unsigned integer, possibly in hexadecimal. - */ - explicit d_string(const unsigned int value, const bool hexadecimal = false) noexcept - { - char strBuf[0xff+1]; - std::snprintf(strBuf, 0xff, hexadecimal ? "0x%x" : "%u", value); - strBuf[0xff] = '\0'; - - _init(); - _dup(strBuf); - } - - /* - * Long integer. - */ - explicit d_string(const long value) noexcept - { - char strBuf[0xff+1]; - std::snprintf(strBuf, 0xff, "%ld", value); - strBuf[0xff] = '\0'; - - _init(); - _dup(strBuf); - } - - /* - * Long unsigned integer, possibly hexadecimal. - */ - explicit d_string(const unsigned long value, const bool hexadecimal = false) noexcept - { - char strBuf[0xff+1]; - std::snprintf(strBuf, 0xff, hexadecimal ? "0x%lx" : "%lu", value); - strBuf[0xff] = '\0'; - - _init(); - _dup(strBuf); - } - - /* - * Long long integer. - */ - explicit d_string(const long long value) noexcept - { - char strBuf[0xff+1]; - std::snprintf(strBuf, 0xff, "%lld", value); - strBuf[0xff] = '\0'; - - _init(); - _dup(strBuf); - } - - /* - * Long long unsigned integer, possibly hexadecimal. - */ - explicit d_string(const unsigned long long value, const bool hexadecimal = false) noexcept - { - char strBuf[0xff+1]; - std::snprintf(strBuf, 0xff, hexadecimal ? "0x%llx" : "%llu", value); - strBuf[0xff] = '\0'; - - _init(); - _dup(strBuf); - } - - /* - * Single-precision floating point number. - */ - explicit d_string(const float value) noexcept - { - char strBuf[0xff+1]; - std::snprintf(strBuf, 0xff, "%f", value); - strBuf[0xff] = '\0'; - - _init(); - _dup(strBuf); - } - - /* - * Double-precision floating point number. - */ - explicit d_string(const double value) noexcept - { - char strBuf[0xff+1]; - std::snprintf(strBuf, 0xff, "%g", value); - strBuf[0xff] = '\0'; - - _init(); - _dup(strBuf); - } - - // ------------------------------------------------------------------- - // non-explicit constructor - - /* - * Create string from another string. - */ - d_string(const d_string& str) noexcept - { - _init(); - _dup(str.fBuffer); - } - - // ------------------------------------------------------------------- - // destructor - - /* - * Destructor. - */ - ~d_string() noexcept - { - DISTRHO_SAFE_ASSERT_RETURN(fBuffer != nullptr,); - - if (fBuffer == _null()) - return; - - std::free(fBuffer); - - fBuffer = nullptr; - fBufferLen = 0; - } - - // ------------------------------------------------------------------- - // public methods - - /* - * Get length of the string. - */ - size_t length() const noexcept - { - return fBufferLen; - } - - /* - * Check if the string is empty. - */ - bool isEmpty() const noexcept - { - return (fBufferLen == 0); - } - - /* - * Check if the string is not empty. - */ - bool isNotEmpty() const noexcept - { - return (fBufferLen != 0); - } - - /* - * Check if the string contains another string, optionally ignoring case. - */ - bool contains(const char* const strBuf, const bool ignoreCase = false) const noexcept - { - DISTRHO_SAFE_ASSERT_RETURN(strBuf != nullptr, false); - - if (ignoreCase) - { -#ifdef __USE_GNU - return (strcasestr(fBuffer, strBuf) != nullptr); -#else - d_string tmp1(fBuffer), tmp2(strBuf); - - // memory allocation failed or empty string(s) - if (tmp1.fBuffer == _null() || tmp2.fBuffer == _null()) - return false; - - tmp1.toLower(); - tmp2.toLower(); - return (std::strstr(tmp1, tmp2) != nullptr); -#endif - } - - return (std::strstr(fBuffer, strBuf) != nullptr); - } - - /* - * Check if character at 'pos' is a digit. - */ - bool isDigit(const size_t pos) const noexcept - { - DISTRHO_SAFE_ASSERT_RETURN(pos < fBufferLen, false); - - return (fBuffer[pos] >= '0' && fBuffer[pos] <= '9'); - } - - /* - * Check if the string starts with the character 'c'. - */ - bool startsWith(const char c) const noexcept - { - DISTRHO_SAFE_ASSERT_RETURN(c != '\0', false); - - return (fBufferLen > 0 && fBuffer[0] == c); - } - - /* - * Check if the string starts with the string 'prefix'. - */ - bool startsWith(const char* const prefix) const noexcept - { - DISTRHO_SAFE_ASSERT_RETURN(prefix != nullptr, false); - - const size_t prefixLen(std::strlen(prefix)); - - if (fBufferLen < prefixLen) - return false; - - return (std::strncmp(fBuffer, prefix, prefixLen) == 0); - } - - /* - * Check if the string ends with the character 'c'. - */ - bool endsWith(const char c) const noexcept - { - DISTRHO_SAFE_ASSERT_RETURN(c != '\0', false); - - return (fBufferLen > 0 && fBuffer[fBufferLen-1] == c); - } - - /* - * Check if the string ends with the string 'suffix'. - */ - bool endsWith(const char* const suffix) const noexcept - { - DISTRHO_SAFE_ASSERT_RETURN(suffix != nullptr, false); - - const size_t suffixLen(std::strlen(suffix)); - - if (fBufferLen < suffixLen) - return false; - - return (std::strncmp(fBuffer + (fBufferLen-suffixLen), suffix, suffixLen) == 0); - } - - /* - * Find the first occurrence of character 'c' in the string. - * Returns "length()" if the character is not found. - */ - size_t find(const char c, bool* const found = nullptr) const noexcept - { - if (fBufferLen == 0 || c == '\0') - { - if (found != nullptr) - *found = false; - return fBufferLen; - } - - for (size_t i=0; i < fBufferLen; ++i) - { - if (fBuffer[i] == c) - { - if (found != nullptr) - *found = true; - return i; - } - } - - if (found != nullptr) - *found = false; - return fBufferLen; - } - - /* - * Find the first occurrence of string 'strBuf' in the string. - * Returns "length()" if the string is not found. - */ - size_t find(const char* const strBuf, bool* const found = nullptr) const noexcept - { - if (fBufferLen == 0 || strBuf == nullptr || strBuf[0] == '\0') - { - if (found != nullptr) - *found = false; - return fBufferLen; - } - - if (char* const subStrBuf = std::strstr(fBuffer, strBuf)) - { - const ssize_t ret(subStrBuf - fBuffer); - - if (ret < 0) - { - // should never happen! - d_safe_assert("ret >= 0", __FILE__, __LINE__); - - if (found != nullptr) - *found = false; - return fBufferLen; - } - - if (found != nullptr) - *found = true; - return static_cast<size_t>(ret); - } - - if (found != nullptr) - *found = false; - return fBufferLen; - } - - /* - * Find the last occurrence of character 'c' in the string. - * Returns "length()" if the character is not found. - */ - size_t rfind(const char c, bool* const found = nullptr) const noexcept - { - if (fBufferLen == 0 || c == '\0') - { - if (found != nullptr) - *found = false; - return fBufferLen; - } - - for (size_t i=fBufferLen; i > 0; --i) - { - if (fBuffer[i-1] == c) - { - if (found != nullptr) - *found = true; - return i-1; - } - } - - if (found != nullptr) - *found = false; - return fBufferLen; - } - - /* - * Find the last occurrence of string 'strBuf' in the string. - * Returns "length()" if the string is not found. - */ - size_t rfind(const char* const strBuf, bool* const found = nullptr) const noexcept - { - if (found != nullptr) - *found = false; - - if (fBufferLen == 0 || strBuf == nullptr || strBuf[0] == '\0') - return fBufferLen; - - const size_t strBufLen(std::strlen(strBuf)); - - size_t ret = fBufferLen; - const char* tmpBuf = fBuffer; - - for (size_t i=0; i < fBufferLen; ++i) - { - if (std::strstr(tmpBuf+1, strBuf) == nullptr && std::strncmp(tmpBuf, strBuf, strBufLen) == 0) - { - if (found != nullptr) - *found = true; - break; - } - - --ret; - ++tmpBuf; - } - - return fBufferLen-ret; - } - - /* - * Clear the string. - */ - void clear() noexcept - { - truncate(0); - } - - /* - * Replace all occurrences of character 'before' with character 'after'. - */ - void replace(const char before, const char after) noexcept - { - DISTRHO_SAFE_ASSERT_RETURN(before != '\0' && after != '\0',); - - for (size_t i=0; i < fBufferLen; ++i) - { - if (fBuffer[i] == before) - fBuffer[i] = after; - } - } - - /* - * Truncate the string to size 'n'. - */ - void truncate(const size_t n) noexcept - { - if (n >= fBufferLen) - return; - - for (size_t i=n; i < fBufferLen; ++i) - fBuffer[i] = '\0'; - - fBufferLen = n; - } - - /* - * Convert all non-basic characters to '_'. - */ - void toBasic() noexcept - { - for (size_t i=0; i < fBufferLen; ++i) - { - if (fBuffer[i] >= '0' && fBuffer[i] <= '9') - continue; - if (fBuffer[i] >= 'A' && fBuffer[i] <= 'Z') - continue; - if (fBuffer[i] >= 'a' && fBuffer[i] <= 'z') - continue; - if (fBuffer[i] == '_') - continue; - - fBuffer[i] = '_'; - } - } - - /* - * Convert to all ascii characters to lowercase. - */ - void toLower() noexcept - { - static const char kCharDiff('a' - 'A'); - - for (size_t i=0; i < fBufferLen; ++i) - { - if (fBuffer[i] >= 'A' && fBuffer[i] <= 'Z') - fBuffer[i] = static_cast<char>(fBuffer[i] + kCharDiff); - } - } - - /* - * Convert to all ascii characters to uppercase. - */ - void toUpper() noexcept - { - static const char kCharDiff('a' - 'A'); - - for (size_t i=0; i < fBufferLen; ++i) - { - if (fBuffer[i] >= 'a' && fBuffer[i] <= 'z') - fBuffer[i] = static_cast<char>(fBuffer[i] - kCharDiff); - } - } - - /* - * Direct access to the string buffer (read-only). - */ - const char* buffer() const noexcept - { - return fBuffer; - } - - // ------------------------------------------------------------------- - // public operators - - operator const char*() const noexcept - { - return fBuffer; - } - - char operator[](const size_t pos) const noexcept - { - if (pos < fBufferLen) - return fBuffer[pos]; - - d_safe_assert("pos < fBufferLen", __FILE__, __LINE__); - - static char fallback; - fallback = '\0'; - return fallback; - } - - char& operator[](const size_t pos) noexcept - { - if (pos < fBufferLen) - return fBuffer[pos]; - - d_safe_assert("pos < fBufferLen", __FILE__, __LINE__); - - static char fallback; - fallback = '\0'; - return fallback; - } - - bool operator==(const char* const strBuf) const noexcept - { - return (strBuf != nullptr && std::strcmp(fBuffer, strBuf) == 0); - } - - bool operator==(const d_string& str) const noexcept - { - return operator==(str.fBuffer); - } - - bool operator!=(const char* const strBuf) const noexcept - { - return !operator==(strBuf); - } - - bool operator!=(const d_string& str) const noexcept - { - return !operator==(str.fBuffer); - } - - d_string& operator=(const char* const strBuf) noexcept - { - _dup(strBuf); - - return *this; - } - - d_string& operator=(const d_string& str) noexcept - { - _dup(str.fBuffer); - - return *this; - } - - d_string& operator+=(const char* const strBuf) noexcept - { - if (strBuf == nullptr) - return *this; - - const size_t newBufSize = fBufferLen + std::strlen(strBuf) + 1; - char newBuf[newBufSize]; - - std::strcpy(newBuf, fBuffer); - std::strcat(newBuf, strBuf); - - _dup(newBuf, newBufSize-1); - - return *this; - } - - d_string& operator+=(const d_string& str) noexcept - { - return operator+=(str.fBuffer); - } - - d_string operator+(const char* const strBuf) noexcept - { - const size_t newBufSize = fBufferLen + ((strBuf != nullptr) ? std::strlen(strBuf) : 0) + 1; - char newBuf[newBufSize]; - - std::strcpy(newBuf, fBuffer); - - if (strBuf != nullptr) - std::strcat(newBuf, strBuf); - - return d_string(newBuf); - } - - d_string operator+(const d_string& str) noexcept - { - return operator+(str.fBuffer); - } - - // ------------------------------------------------------------------- - -private: - char* fBuffer; // the actual string buffer - size_t fBufferLen; // string length - - /* - * Static null string. - * Prevents allocation for new and/or empty strings. - */ - static char* _null() noexcept - { - static char sNull = '\0'; - return &sNull; - } - - /* - * Shared init function. - * Called on all constructors. - */ - void _init() noexcept - { - fBuffer = _null(); - fBufferLen = 0; - } - - /* - * Helper function. - * Called whenever the string needs to be allocated. - * - * Notes: - * - Allocates string only if 'strBuf' is not null and new string contents are different - * - If 'strBuf' is null, 'size' must be 0 - */ - void _dup(const char* const strBuf, const size_t size = 0) noexcept - { - if (strBuf != nullptr) - { - // don't recreate string if contents match - if (std::strcmp(fBuffer, strBuf) == 0) - return; - - if (fBuffer != _null()) - std::free(fBuffer); - - fBufferLen = (size > 0) ? size : std::strlen(strBuf); - fBuffer = (char*)std::malloc(fBufferLen+1); - - if (fBuffer == nullptr) - return _init(); - - std::strcpy(fBuffer, strBuf); - - fBuffer[fBufferLen] = '\0'; - } - else - { - DISTRHO_SAFE_ASSERT(size == 0); - - // don't recreate null string - if (fBuffer == _null()) - return; - - DISTRHO_SAFE_ASSERT(fBuffer != nullptr); - std::free(fBuffer); - - _init(); - } - } - - DISTRHO_LEAK_DETECTOR(d_string) - DISTRHO_PREVENT_HEAP_ALLOCATION -}; - -// ----------------------------------------------------------------------- - -static inline -d_string operator+(const d_string& strBefore, const char* const strBufAfter) noexcept -{ - const char* const strBufBefore = strBefore.buffer(); - const size_t newBufSize = strBefore.length() + ((strBufAfter != nullptr) ? std::strlen(strBufAfter) : 0) + 1; - char newBuf[newBufSize]; - - std::strcpy(newBuf, strBufBefore); - std::strcat(newBuf, strBufAfter); - - return d_string(newBuf); -} - -static inline -d_string operator+(const char* const strBufBefore, const d_string& strAfter) noexcept -{ - const char* const strBufAfter = strAfter.buffer(); - const size_t newBufSize = ((strBufBefore != nullptr) ? std::strlen(strBufBefore) : 0) + strAfter.length() + 1; - char newBuf[newBufSize]; - - std::strcpy(newBuf, strBufBefore); - std::strcat(newBuf, strBufAfter); - - return d_string(newBuf); -} - -// ----------------------------------------------------------------------- - -END_NAMESPACE_DISTRHO - -#endif // DISTRHO_STRING_HPP_INCLUDED |