|
@@ -7,117 +7,10 @@
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
|
|
-#include <platform.h>
|
|
|
|
#include "StringHelpers.h"
|
|
#include "StringHelpers.h"
|
|
#include "Util.h"
|
|
#include "Util.h"
|
|
-#include "StringUtils.h" // From CryCommon
|
|
|
|
-#include "UnicodeFunctions.h"
|
|
|
|
-#include <cctype>
|
|
|
|
-#include <algorithm>
|
|
|
|
-
|
|
|
|
-#include <AzCore/PlatformIncl.h> // WideCharToMultibyte(), CP_UTF8, etc.
|
|
|
|
-#include <AzCore/Casting/numeric_cast.h>
|
|
|
|
-
|
|
|
|
-static inline char ToLower(const char c)
|
|
|
|
-{
|
|
|
|
- return tolower(c);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static inline wchar_t ToLower(const wchar_t c)
|
|
|
|
-{
|
|
|
|
- return towlower(c);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-static inline char ToUpper(const char c)
|
|
|
|
-{
|
|
|
|
- return toupper(c);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static inline wchar_t ToUpper(const wchar_t c)
|
|
|
|
-{
|
|
|
|
- return towupper(c);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-static inline int Vscprintf(const char* format, va_list argList)
|
|
|
|
-{
|
|
|
|
-#if defined(AZ_PLATFORM_WINDOWS)
|
|
|
|
- return _vscprintf(format, argList);
|
|
|
|
-#elif AZ_TRAIT_OS_PLATFORM_APPLE || defined(AZ_PLATFORM_LINUX)
|
|
|
|
- int retval;
|
|
|
|
- va_list argcopy;
|
|
|
|
- va_copy(argcopy, argList);
|
|
|
|
- retval = azvsnprintf(NULL, 0, format, argcopy);
|
|
|
|
- va_end(argcopy);
|
|
|
|
- return retval;
|
|
|
|
-#else
|
|
|
|
- #error Not supported!
|
|
|
|
-#endif
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static inline int Vscprintf(const wchar_t* format, va_list argList)
|
|
|
|
-{
|
|
|
|
-#if defined(AZ_PLATFORM_WINDOWS)
|
|
|
|
- return _vscwprintf(format, argList);
|
|
|
|
-#elif AZ_TRAIT_OS_PLATFORM_APPLE || defined(AZ_PLATFORM_LINUX)
|
|
|
|
- int retval;
|
|
|
|
- va_list argcopy;
|
|
|
|
- va_copy(argcopy, argList);
|
|
|
|
- retval = azvsnwprintf(NULL, 0, format, argcopy);
|
|
|
|
- va_end(argcopy);
|
|
|
|
- return retval;
|
|
|
|
-#else
|
|
|
|
- #error Not supported!
|
|
|
|
-#endif
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-static inline int Vsnprintf_s(char* str, size_t sizeInBytes, [[maybe_unused]] size_t count, const char* format, va_list argList)
|
|
|
|
-{
|
|
|
|
- return azvsnprintf(str, sizeInBytes, format, argList);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static inline int Vsnprintf_s(wchar_t* str, size_t sizeInBytes, [[maybe_unused]] size_t count, const wchar_t* format, va_list argList)
|
|
|
|
-{
|
|
|
|
- return azvsnwprintf(str, sizeInBytes, format, argList);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-int StringHelpers::Compare(const AZStd::string& str0, const AZStd::string& str1)
|
|
|
|
-{
|
|
|
|
- const size_t minLength = Util::getMin(str0.length(), str1.length());
|
|
|
|
- const int result = std::memcmp(str0.c_str(), str1.c_str(), minLength);
|
|
|
|
- if (result)
|
|
|
|
- {
|
|
|
|
- return result;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- return (str0.length() == str1.length())
|
|
|
|
- ? 0
|
|
|
|
- : ((str0.length() < str1.length()) ? -1 : +1);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-int StringHelpers::Compare(const wstring& str0, const wstring& str1)
|
|
|
|
-{
|
|
|
|
- const size_t minLength = Util::getMin(str0.length(), str1.length());
|
|
|
|
- for (size_t i = 0; i < minLength; ++i)
|
|
|
|
- {
|
|
|
|
- const wchar_t c0 = str0[i];
|
|
|
|
- const wchar_t c1 = str1[i];
|
|
|
|
- if (c0 != c1)
|
|
|
|
- {
|
|
|
|
- return (c0 < c1) ? -1 : 1;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return (str0.length() == str1.length())
|
|
|
|
- ? 0
|
|
|
|
- : ((str0.length() < str1.length()) ? -1 : +1);
|
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
+#include <AzCore/std/string/string.h>
|
|
|
|
|
|
int StringHelpers::CompareIgnoreCase(const AZStd::string& str0, const AZStd::string& str1)
|
|
int StringHelpers::CompareIgnoreCase(const AZStd::string& str0, const AZStd::string& str1)
|
|
{
|
|
{
|
|
@@ -135,7 +28,7 @@ int StringHelpers::CompareIgnoreCase(const AZStd::string& str0, const AZStd::str
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-int StringHelpers::CompareIgnoreCase(const wstring& str0, const wstring& str1)
|
|
|
|
|
|
+int StringHelpers::CompareIgnoreCase(const AZStd::wstring& str0, const AZStd::wstring& str1)
|
|
{
|
|
{
|
|
const size_t minLength = Util::getMin(str0.length(), str1.length());
|
|
const size_t minLength = Util::getMin(str0.length(), str1.length());
|
|
for (size_t i = 0; i < minLength; ++i)
|
|
for (size_t i = 0; i < minLength; ++i)
|
|
@@ -153,402 +46,6 @@ int StringHelpers::CompareIgnoreCase(const wstring& str0, const wstring& str1)
|
|
: ((str0.length() < str1.length()) ? -1 : +1);
|
|
: ((str0.length() < str1.length()) ? -1 : +1);
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-bool StringHelpers::Equals(const AZStd::string& str0, const AZStd::string& str1)
|
|
|
|
-{
|
|
|
|
- if (str0.length() != str1.length())
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- return std::memcmp(str0.c_str(), str1.c_str(), str1.length()) == 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-bool StringHelpers::Equals(const wstring& str0, const wstring& str1)
|
|
|
|
-{
|
|
|
|
- if (str0.length() != str1.length())
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- return std::memcmp(str0.c_str(), str1.c_str(), str1.length() * sizeof(wstring::value_type)) == 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-bool StringHelpers::EqualsIgnoreCase(const AZStd::string& str0, const AZStd::string& str1)
|
|
|
|
-{
|
|
|
|
- if (str0.length() != str1.length())
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- return azmemicmp(str0.c_str(), str1.c_str(), str1.length()) == 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-bool StringHelpers::EqualsIgnoreCase(const wstring& str0, const wstring& str1)
|
|
|
|
-{
|
|
|
|
- const size_t str1Length = str1.length();
|
|
|
|
- if (str0.length() != str1Length)
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- for (size_t i = 0; i < str1Length; ++i)
|
|
|
|
- {
|
|
|
|
- if (towlower(str0[i]) != towlower(str1[i]))
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return true;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-bool StringHelpers::StartsWith(const AZStd::string& str, const AZStd::string& pattern)
|
|
|
|
-{
|
|
|
|
- if (str.length() < pattern.length())
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- return std::memcmp(str.c_str(), pattern.c_str(), pattern.length()) == 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-bool StringHelpers::StartsWith(const wstring& str, const wstring& pattern)
|
|
|
|
-{
|
|
|
|
- if (str.length() < pattern.length())
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- return std::memcmp(str.c_str(), pattern.c_str(), pattern.length() * sizeof(wstring::value_type)) == 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-bool StringHelpers::StartsWithIgnoreCase(const AZStd::string& str, const AZStd::string& pattern)
|
|
|
|
-{
|
|
|
|
- if (str.length() < pattern.length())
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- return azmemicmp(str.c_str(), pattern.c_str(), pattern.length()) == 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-bool StringHelpers::StartsWithIgnoreCase(const wstring& str, const wstring& pattern)
|
|
|
|
-{
|
|
|
|
- const size_t patternLength = pattern.length();
|
|
|
|
- if (str.length() < patternLength)
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- for (size_t i = 0; i < patternLength; ++i)
|
|
|
|
- {
|
|
|
|
- if (towlower(str[i]) != towlower(pattern[i]))
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return true;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-bool StringHelpers::EndsWith(const AZStd::string& str, const AZStd::string& pattern)
|
|
|
|
-{
|
|
|
|
- if (str.length() < pattern.length())
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- return std::memcmp(str.c_str() + str.length() - pattern.length(), pattern.c_str(), pattern.length()) == 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-bool StringHelpers::EndsWith(const wstring& str, const wstring& pattern)
|
|
|
|
-{
|
|
|
|
- if (str.length() < pattern.length())
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- return std::memcmp(str.c_str() + str.length() - pattern.length(), pattern.c_str(), pattern.length() * sizeof(wstring::value_type)) == 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-bool StringHelpers::EndsWithIgnoreCase(const AZStd::string& str, const AZStd::string& pattern)
|
|
|
|
-{
|
|
|
|
- if (str.length() < pattern.length())
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- return azmemicmp(str.c_str() + str.length() - pattern.length(), pattern.c_str(), pattern.length()) == 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-bool StringHelpers::EndsWithIgnoreCase(const wstring& str, const wstring& pattern)
|
|
|
|
-{
|
|
|
|
- const size_t patternLength = pattern.length();
|
|
|
|
- if (str.length() < patternLength)
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- for (size_t i = str.length() - patternLength, j = 0; i < patternLength; ++i, ++j)
|
|
|
|
- {
|
|
|
|
- if (towlower(str[i]) != towlower(pattern[j]))
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return true;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-bool StringHelpers::Contains(const AZStd::string& str, const AZStd::string& pattern)
|
|
|
|
-{
|
|
|
|
- const size_t patternLength = pattern.length();
|
|
|
|
- if (str.length() < patternLength)
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- const size_t n = str.length() - patternLength + 1;
|
|
|
|
- for (size_t i = 0; i < n; ++i)
|
|
|
|
- {
|
|
|
|
- if (std::memcmp(str.c_str() + i, pattern.c_str(), patternLength) == 0)
|
|
|
|
- {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-bool StringHelpers::Contains(const wstring& str, const wstring& pattern)
|
|
|
|
-{
|
|
|
|
- const size_t patternLength = pattern.length();
|
|
|
|
- if (str.length() < patternLength)
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- const size_t n = str.length() - patternLength + 1;
|
|
|
|
- for (size_t i = 0; i < n; ++i)
|
|
|
|
- {
|
|
|
|
- if (std::memcmp(str.c_str() + i, pattern.c_str(), patternLength * sizeof(wstring::value_type)) == 0)
|
|
|
|
- {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-bool StringHelpers::ContainsIgnoreCase(const AZStd::string& str, const AZStd::string& pattern)
|
|
|
|
-{
|
|
|
|
- const size_t patternLength = pattern.length();
|
|
|
|
- if (str.length() < patternLength)
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- const size_t n = str.length() - patternLength + 1;
|
|
|
|
- for (size_t i = 0; i < n; ++i)
|
|
|
|
- {
|
|
|
|
- if (azmemicmp(str.c_str() + i, pattern.c_str(), patternLength) == 0)
|
|
|
|
- {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-bool StringHelpers::ContainsIgnoreCase(const wstring& str, const wstring& pattern)
|
|
|
|
-{
|
|
|
|
- const size_t patternLength = pattern.length();
|
|
|
|
- if (patternLength == 0)
|
|
|
|
- {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- if (str.length() < patternLength)
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- const wstring::value_type firstPatternLetter = towlower(pattern[0]);
|
|
|
|
- const size_t n = str.length() - patternLength + 1;
|
|
|
|
- for (size_t i = 0; i < n; ++i)
|
|
|
|
- {
|
|
|
|
- bool match = true;
|
|
|
|
- for (size_t j = 0; j < patternLength; ++j)
|
|
|
|
- {
|
|
|
|
- if (towlower(str[i + j]) != towlower(pattern[j]))
|
|
|
|
- {
|
|
|
|
- match = false;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (match)
|
|
|
|
- {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-string StringHelpers::TrimLeft(const AZStd::string& s)
|
|
|
|
-{
|
|
|
|
- const size_t first = s.find_first_not_of(" \r\t");
|
|
|
|
- return (first == s.npos) ? string() : s.substr(first);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-wstring StringHelpers::TrimLeft(const wstring& s)
|
|
|
|
-{
|
|
|
|
- const size_t first = s.find_first_not_of(L" \r\t");
|
|
|
|
- return (first == s.npos) ? wstring() : s.substr(first);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-string StringHelpers::TrimRight(const AZStd::string& s)
|
|
|
|
-{
|
|
|
|
- const size_t last = s.find_last_not_of(" \r\t");
|
|
|
|
- return (last == s.npos) ? s : s.substr(0, last + 1);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-wstring StringHelpers::TrimRight(const wstring& s)
|
|
|
|
-{
|
|
|
|
- const size_t last = s.find_last_not_of(L" \r\t");
|
|
|
|
- return (last == s.npos) ? s : s.substr(0, last + 1);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-string StringHelpers::Trim(const AZStd::string& s)
|
|
|
|
-{
|
|
|
|
- return TrimLeft(TrimRight(s));
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-wstring StringHelpers::Trim(const wstring& s)
|
|
|
|
-{
|
|
|
|
- return TrimLeft(TrimRight(s));
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-template <class TS>
|
|
|
|
-static inline TS RemoveDuplicateSpaces_Tpl(const TS& s)
|
|
|
|
-{
|
|
|
|
- TS res;
|
|
|
|
- bool spaceFound = false;
|
|
|
|
-
|
|
|
|
- for (size_t i = 0, n = s.length(); i < n; ++i)
|
|
|
|
- {
|
|
|
|
- if ((s[i] == ' ') || (s[i] == '\r') || (s[i] == '\t'))
|
|
|
|
- {
|
|
|
|
- spaceFound = true;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- if (spaceFound)
|
|
|
|
- {
|
|
|
|
- res += ' ';
|
|
|
|
- spaceFound = false;
|
|
|
|
- }
|
|
|
|
- res += s[i];
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (spaceFound)
|
|
|
|
- {
|
|
|
|
- res += ' ';
|
|
|
|
- }
|
|
|
|
- return res;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-string StringHelpers::RemoveDuplicateSpaces(const AZStd::string& s)
|
|
|
|
-{
|
|
|
|
- return RemoveDuplicateSpaces_Tpl(s);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-wstring StringHelpers::RemoveDuplicateSpaces(const wstring& s)
|
|
|
|
-{
|
|
|
|
- return RemoveDuplicateSpaces_Tpl(s);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-template <class TS>
|
|
|
|
-static inline TS MakeLowerCase_Tpl(const TS& s)
|
|
|
|
-{
|
|
|
|
- TS copy;
|
|
|
|
- copy.reserve(s.length());
|
|
|
|
- for (typename TS::const_iterator it = s.begin(), end = s.end(); it != end; ++it)
|
|
|
|
- {
|
|
|
|
- copy.append(1, ToLower(*it));
|
|
|
|
- }
|
|
|
|
- return copy;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-string StringHelpers::MakeLowerCase(const AZStd::string& s)
|
|
|
|
-{
|
|
|
|
- return MakeLowerCase_Tpl(s);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-wstring StringHelpers::MakeLowerCase(const wstring& s)
|
|
|
|
-{
|
|
|
|
- return MakeLowerCase_Tpl(s);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-template <class TS>
|
|
|
|
-static inline TS MakeUpperCase_Tpl(const TS& s)
|
|
|
|
-{
|
|
|
|
- TS copy;
|
|
|
|
- copy.reserve(s.length());
|
|
|
|
- for (typename TS::const_iterator it = s.begin(), end = s.end(); it != end; ++it)
|
|
|
|
- {
|
|
|
|
- copy.append(1, ToUpper(*it));
|
|
|
|
- }
|
|
|
|
- return copy;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-string StringHelpers::MakeUpperCase(const AZStd::string& s)
|
|
|
|
-{
|
|
|
|
- return MakeUpperCase_Tpl(s);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-wstring StringHelpers::MakeUpperCase(const wstring& s)
|
|
|
|
-{
|
|
|
|
- return MakeUpperCase_Tpl(s);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-template <class TS>
|
|
|
|
-static inline TS Replace_Tpl(const TS& s, const typename TS::value_type oldChar, const typename TS::value_type newChar)
|
|
|
|
-{
|
|
|
|
- TS copy;
|
|
|
|
- copy.reserve(s.length());
|
|
|
|
- for (typename TS::const_iterator it = s.begin(), end = s.end(); it != end; ++it)
|
|
|
|
- {
|
|
|
|
- const typename TS::value_type c = (*it);
|
|
|
|
- copy.append(1, ((c == oldChar) ? newChar : c));
|
|
|
|
- }
|
|
|
|
- return copy;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-string StringHelpers::Replace(const AZStd::string& s, char oldChar, char newChar)
|
|
|
|
-{
|
|
|
|
- return Replace_Tpl(s, oldChar, newChar);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-wstring StringHelpers::Replace(const wstring& s, wchar_t oldChar, wchar_t newChar)
|
|
|
|
-{
|
|
|
|
- return Replace_Tpl(s, oldChar, newChar);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-void StringHelpers::ConvertStringByRef(string& out, const AZStd::string& in)
|
|
|
|
-{
|
|
|
|
- out = in;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void StringHelpers::ConvertStringByRef(wstring& out, const AZStd::string& in)
|
|
|
|
-{
|
|
|
|
- Unicode::Convert(out, in);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void StringHelpers::ConvertStringByRef(string& out, const wstring& in)
|
|
|
|
-{
|
|
|
|
- Unicode::Convert(out, in);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void StringHelpers::ConvertStringByRef(wstring& out, const wstring& in)
|
|
|
|
-{
|
|
|
|
- out = in;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
template <class TS>
|
|
template <class TS>
|
|
static inline void Split_Tpl(const TS& str, const TS& separator, bool bReturnEmptyPartsToo, std::vector<TS>& outParts)
|
|
static inline void Split_Tpl(const TS& str, const TS& separator, bool bReturnEmptyPartsToo, std::vector<TS>& outParts)
|
|
{
|
|
{
|
|
@@ -588,348 +85,12 @@ static inline void Split_Tpl(const TS& str, const TS& separator, bool bReturnEmp
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-template <class TS>
|
|
|
|
-static inline void SplitByAnyOf_Tpl(const TS& str, const TS& separators, bool bReturnEmptyPartsToo, std::vector<TS>& outParts)
|
|
|
|
-{
|
|
|
|
- if (str.empty())
|
|
|
|
- {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (separators.empty())
|
|
|
|
- {
|
|
|
|
- for (size_t i = 0; i < str.length(); ++i)
|
|
|
|
- {
|
|
|
|
- outParts.push_back(str.substr(i, 1));
|
|
|
|
- }
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- size_t partStart = 0;
|
|
|
|
-
|
|
|
|
- for (;; )
|
|
|
|
- {
|
|
|
|
- const size_t pos = str.find_first_of(separators, partStart);
|
|
|
|
- if (pos == TS::npos)
|
|
|
|
- {
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- if (bReturnEmptyPartsToo || (pos > partStart))
|
|
|
|
- {
|
|
|
|
- outParts.push_back(str.substr(partStart, pos - partStart));
|
|
|
|
- }
|
|
|
|
- partStart = pos + 1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (bReturnEmptyPartsToo || (partStart < str.length()))
|
|
|
|
- {
|
|
|
|
- outParts.push_back(str.substr(partStart, str.length() - partStart));
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-void StringHelpers::Split(const AZStd::string& str, const AZStd::string& separator, bool bReturnEmptyPartsToo, std::vector<string>& outParts)
|
|
|
|
|
|
+void StringHelpers::Split(const AZStd::string& str, const AZStd::string& separator, bool bReturnEmptyPartsToo, std::vector<AZStd::string>& outParts)
|
|
{
|
|
{
|
|
Split_Tpl(str, separator, bReturnEmptyPartsToo, outParts);
|
|
Split_Tpl(str, separator, bReturnEmptyPartsToo, outParts);
|
|
}
|
|
}
|
|
|
|
|
|
-void StringHelpers::Split(const wstring& str, const wstring& separator, bool bReturnEmptyPartsToo, std::vector<wstring>& outParts)
|
|
|
|
|
|
+void StringHelpers::Split(const AZStd::wstring& str, const AZStd::wstring& separator, bool bReturnEmptyPartsToo, std::vector<AZStd::wstring>& outParts)
|
|
{
|
|
{
|
|
Split_Tpl(str, separator, bReturnEmptyPartsToo, outParts);
|
|
Split_Tpl(str, separator, bReturnEmptyPartsToo, outParts);
|
|
}
|
|
}
|
|
-
|
|
|
|
-
|
|
|
|
-void StringHelpers::SplitByAnyOf(const AZStd::string& str, const AZStd::string& separators, bool bReturnEmptyPartsToo, std::vector<string>& outParts)
|
|
|
|
-{
|
|
|
|
- SplitByAnyOf_Tpl(str, separators, bReturnEmptyPartsToo, outParts);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void StringHelpers::SplitByAnyOf(const wstring& str, const wstring& separators, bool bReturnEmptyPartsToo, std::vector<wstring>& outParts)
|
|
|
|
-{
|
|
|
|
- SplitByAnyOf_Tpl(str, separators, bReturnEmptyPartsToo, outParts);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-template <class TS>
|
|
|
|
-static inline TS FormatVA_Tpl(const typename TS::value_type* const format, va_list parg)
|
|
|
|
-{
|
|
|
|
- if ((format == 0) || (format[0] == 0))
|
|
|
|
- {
|
|
|
|
- return TS();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- std::vector<typename TS::value_type> bf;
|
|
|
|
- size_t capacity = 0;
|
|
|
|
-
|
|
|
|
- size_t wantedCapacity = Vscprintf(format, parg);
|
|
|
|
- wantedCapacity += 2; // '+ 2' to prevent uncertainty when Vsnprintf_s() returns 'size - 1'
|
|
|
|
-
|
|
|
|
- for (;; )
|
|
|
|
- {
|
|
|
|
- if (wantedCapacity > capacity)
|
|
|
|
- {
|
|
|
|
- capacity = wantedCapacity;
|
|
|
|
- bf.resize(capacity + 1);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- const int countWritten = Vsnprintf_s(&bf[0], capacity + 1, _TRUNCATE, format, parg);
|
|
|
|
-
|
|
|
|
- if ((countWritten >= 0) && (capacity > (size_t)countWritten + 1))
|
|
|
|
- {
|
|
|
|
- bf[countWritten] = 0;
|
|
|
|
- return TS(&bf[0]);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- wantedCapacity = capacity * 2;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-string StringHelpers::FormatVA(const char* const format, va_list parg)
|
|
|
|
-{
|
|
|
|
- return FormatVA_Tpl<string>(format, parg);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-wstring StringHelpers::FormatVA(const wchar_t* const format, va_list parg)
|
|
|
|
-{
|
|
|
|
- return FormatVA_Tpl<wstring>(format, parg);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-//////////////////////////////////////////////////////////////////////////
|
|
|
|
-
|
|
|
|
-template <class TC>
|
|
|
|
-static inline void SafeCopy_Tpl(TC* const pDstBuffer, const size_t dstBufferSizeInBytes, const TC* const pSrc)
|
|
|
|
-{
|
|
|
|
- if (dstBufferSizeInBytes >= sizeof(TC))
|
|
|
|
- {
|
|
|
|
- const size_t n = dstBufferSizeInBytes / sizeof(TC) - 1;
|
|
|
|
- size_t i;
|
|
|
|
- for (i = 0; i < n && pSrc[i]; ++i)
|
|
|
|
- {
|
|
|
|
- pDstBuffer[i] = pSrc[i];
|
|
|
|
- }
|
|
|
|
- pDstBuffer[i] = 0;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-template <class TC>
|
|
|
|
-static inline void SafeCopyPadZeros_Tpl(TC* const pDstBuffer, const size_t dstBufferSizeInBytes, const TC* const pSrc)
|
|
|
|
-{
|
|
|
|
- if (dstBufferSizeInBytes > 0)
|
|
|
|
- {
|
|
|
|
- const size_t n = (dstBufferSizeInBytes < sizeof(TC)) ? 0 : dstBufferSizeInBytes / sizeof(TC) - 1;
|
|
|
|
- size_t i;
|
|
|
|
- for (i = 0; i < n && pSrc[i]; ++i)
|
|
|
|
- {
|
|
|
|
- pDstBuffer[i] = pSrc[i];
|
|
|
|
- }
|
|
|
|
- memset(&pDstBuffer[i], 0, dstBufferSizeInBytes - i * sizeof(TC));
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-void StringHelpers::SafeCopy(char* const pDstBuffer, const size_t dstBufferSizeInBytes, const char* const pSrc)
|
|
|
|
-{
|
|
|
|
- SafeCopy_Tpl<char>(pDstBuffer, dstBufferSizeInBytes, pSrc);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void StringHelpers::SafeCopy(wchar_t* const pDstBuffer, const size_t dstBufferSizeInBytes, const wchar_t* const pSrc)
|
|
|
|
-{
|
|
|
|
- SafeCopy_Tpl<wchar_t>(pDstBuffer, dstBufferSizeInBytes, pSrc);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-void StringHelpers::SafeCopyPadZeros(char* const pDstBuffer, const size_t dstBufferSizeInBytes, const char* const pSrc)
|
|
|
|
-{
|
|
|
|
- SafeCopyPadZeros_Tpl<char>(pDstBuffer, dstBufferSizeInBytes, pSrc);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void StringHelpers::SafeCopyPadZeros(wchar_t* const pDstBuffer, const size_t dstBufferSizeInBytes, const wchar_t* const pSrc)
|
|
|
|
-{
|
|
|
|
- SafeCopyPadZeros_Tpl<wchar_t>(pDstBuffer, dstBufferSizeInBytes, pSrc);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-//////////////////////////////////////////////////////////////////////////
|
|
|
|
-
|
|
|
|
-bool StringHelpers::Utf16ContainsAsciiOnly(const wchar_t* wstr)
|
|
|
|
-{
|
|
|
|
- while (*wstr)
|
|
|
|
- {
|
|
|
|
- if (*wstr > 127 || *wstr < 0)
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- ++wstr;
|
|
|
|
- }
|
|
|
|
- return true;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-string StringHelpers::ConvertAsciiUtf16ToAscii(const wchar_t* wstr)
|
|
|
|
-{
|
|
|
|
- const size_t len = wcslen(wstr);
|
|
|
|
-
|
|
|
|
- string result;
|
|
|
|
- result.reserve(len);
|
|
|
|
-
|
|
|
|
- for (size_t i = 0; i < len; ++i)
|
|
|
|
- {
|
|
|
|
- result.push_back(wstr[i] & 0x7F);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return result;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-wstring StringHelpers::ConvertAsciiToUtf16(const char* str)
|
|
|
|
-{
|
|
|
|
- const size_t len = strlen(str);
|
|
|
|
-
|
|
|
|
- wstring result;
|
|
|
|
- result.reserve(len);
|
|
|
|
-
|
|
|
|
- for (size_t i = 0; i < len; ++i)
|
|
|
|
- {
|
|
|
|
- result.push_back(str[i] & 0x7F);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return result;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-#if defined(AZ_PLATFORM_WINDOWS)
|
|
|
|
-static string ConvertUtf16ToMultibyte(const wchar_t* wstr, uint codePage, char badChar)
|
|
|
|
-{
|
|
|
|
- if (wstr[0] == 0)
|
|
|
|
- {
|
|
|
|
- return string();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- const int len = aznumeric_caster(wcslen(wstr));
|
|
|
|
-
|
|
|
|
- // Request needed buffer size, in bytes
|
|
|
|
- int neededByteCount = WideCharToMultiByte(
|
|
|
|
- codePage,
|
|
|
|
- 0,
|
|
|
|
- wstr,
|
|
|
|
- len,
|
|
|
|
- 0,
|
|
|
|
- 0,
|
|
|
|
- ((badChar && codePage != CP_UTF8) ? &badChar : NULL),
|
|
|
|
- NULL);
|
|
|
|
- if (neededByteCount <= 0)
|
|
|
|
- {
|
|
|
|
- return string();
|
|
|
|
- }
|
|
|
|
- ++neededByteCount; // extra space for terminating zero
|
|
|
|
-
|
|
|
|
- std::vector<char> buffer(neededByteCount);
|
|
|
|
-
|
|
|
|
- const int byteCount = WideCharToMultiByte(
|
|
|
|
- codePage,
|
|
|
|
- 0,
|
|
|
|
- wstr,
|
|
|
|
- len,
|
|
|
|
- &buffer[0], // output buffer
|
|
|
|
- neededByteCount - 1, // size of the output buffer in bytes
|
|
|
|
- ((badChar && codePage != CP_UTF8) ? &badChar : NULL),
|
|
|
|
- NULL);
|
|
|
|
- if (byteCount != neededByteCount - 1)
|
|
|
|
- {
|
|
|
|
- return string();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- buffer[byteCount] = 0;
|
|
|
|
-
|
|
|
|
- return string(&buffer[0]);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-static wstring ConvertMultibyteToUtf16(const char* str, uint codePage)
|
|
|
|
-{
|
|
|
|
- if (str[0] == 0)
|
|
|
|
- {
|
|
|
|
- return wstring();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- const int len = aznumeric_caster(strlen(str));
|
|
|
|
-
|
|
|
|
- // Request needed buffer size, in characters
|
|
|
|
- int neededCharCount = MultiByteToWideChar(
|
|
|
|
- codePage,
|
|
|
|
- 0,
|
|
|
|
- str,
|
|
|
|
- len,
|
|
|
|
- 0,
|
|
|
|
- 0);
|
|
|
|
- if (neededCharCount <= 0)
|
|
|
|
- {
|
|
|
|
- return wstring();
|
|
|
|
- }
|
|
|
|
- ++neededCharCount; // extra space for terminating zero
|
|
|
|
-
|
|
|
|
- std::vector<wchar_t> wbuffer(neededCharCount);
|
|
|
|
-
|
|
|
|
- const int charCount = MultiByteToWideChar(
|
|
|
|
- codePage,
|
|
|
|
- 0,
|
|
|
|
- str,
|
|
|
|
- len,
|
|
|
|
- &wbuffer[0], // output buffer
|
|
|
|
- neededCharCount - 1); // size of the output buffer in characters
|
|
|
|
- if (charCount != neededCharCount - 1)
|
|
|
|
- {
|
|
|
|
- return wstring();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- wbuffer[charCount] = 0;
|
|
|
|
-
|
|
|
|
- return wstring(&wbuffer[0]);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-wstring StringHelpers::ConvertUtf8ToUtf16(const char* str)
|
|
|
|
-{
|
|
|
|
- return ConvertMultibyteToUtf16(str, CP_UTF8);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-string StringHelpers::ConvertUtf16ToUtf8(const wchar_t* wstr)
|
|
|
|
-{
|
|
|
|
- return ConvertUtf16ToMultibyte(wstr, CP_UTF8, 0);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-wstring StringHelpers::ConvertAnsiToUtf16(const char* str)
|
|
|
|
-{
|
|
|
|
- return ConvertMultibyteToUtf16(str, CP_ACP);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-string StringHelpers::ConvertUtf16ToAnsi(const wchar_t* wstr, char badChar)
|
|
|
|
-{
|
|
|
|
- return ConvertUtf16ToMultibyte(wstr, CP_ACP, badChar);
|
|
|
|
-}
|
|
|
|
-#endif //AZ_PLATFORM_WINDOWS
|
|
|
|
-
|
|
|
|
-string StringHelpers::ConvertAnsiToAscii(const char* str, char badChar)
|
|
|
|
-{
|
|
|
|
- const size_t len = strlen(str);
|
|
|
|
-
|
|
|
|
- string result;
|
|
|
|
- result.reserve(len);
|
|
|
|
-
|
|
|
|
- for (size_t i = 0; i < len; ++i)
|
|
|
|
- {
|
|
|
|
- char c = str[i];
|
|
|
|
- if (c < 0 || c > 127)
|
|
|
|
- {
|
|
|
|
- c = badChar;
|
|
|
|
- }
|
|
|
|
- result.push_back(c);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return result;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// eof
|
|
|