fixes/improvements to AzCore
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
@@ -35,11 +35,11 @@ namespace AZStd
|
||||
{
|
||||
if constexpr (Size == 2)
|
||||
{
|
||||
Utf8::Unchecked::utf16to8(first, last, AZStd::back_inserter(dest));
|
||||
Utf8::Unchecked::utf16to8(first, last, AZStd::back_inserter(dest), dest.max_size());
|
||||
}
|
||||
else if constexpr (Size == 4)
|
||||
{
|
||||
Utf8::Unchecked::utf32to8(first, last, AZStd::back_inserter(dest));
|
||||
Utf8::Unchecked::utf32to8(first, last, AZStd::back_inserter(dest), dest.max_size());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -54,11 +54,29 @@ namespace AZStd
|
||||
{
|
||||
if constexpr (Size == 2)
|
||||
{
|
||||
Utf8::Unchecked::utf16to8(first, last, AZStd::back_inserter(dest));
|
||||
Utf8::Unchecked::utf16to8(first, last, AZStd::back_inserter(dest), dest.max_size());
|
||||
}
|
||||
else if constexpr (Size == 4)
|
||||
{
|
||||
Utf8::Unchecked::utf32to8(first, last, AZStd::back_inserter(dest));
|
||||
Utf8::Unchecked::utf32to8(first, last, AZStd::back_inserter(dest), dest.max_size());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Workaround to defer static_assert evaluation until this function is invoked by using the template parameter
|
||||
using StringType = AZStd::basic_string<string::value_type, string::traits_type, Allocator1>;
|
||||
static_assert(!AZStd::is_same_v<StringType, StringType>, "only wchar_t types of size 2 or 4 can be converted to utf8");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void to_string(char* dest, size_t destSize, const wchar_t* first, const wchar_t* last)
|
||||
{
|
||||
if constexpr (Size == 2)
|
||||
{
|
||||
Utf8::Unchecked::utf16to8(first, last, dest, destSize);
|
||||
}
|
||||
else if constexpr (Size == 4)
|
||||
{
|
||||
Utf8::Unchecked::utf32to8(first, last, dest, destSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -73,11 +91,11 @@ namespace AZStd
|
||||
{
|
||||
if constexpr (Size == 2)
|
||||
{
|
||||
Utf8::Unchecked::utf8to16(first, last, AZStd::back_inserter(dest));
|
||||
Utf8::Unchecked::utf8to16(first, last, AZStd::back_inserter(dest), dest.max_size());
|
||||
}
|
||||
else if constexpr (Size == 4)
|
||||
{
|
||||
Utf8::Unchecked::utf8to32(first, last, AZStd::back_inserter(dest));
|
||||
Utf8::Unchecked::utf8to32(first, last, AZStd::back_inserter(dest), dest.max_size());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -92,11 +110,11 @@ namespace AZStd
|
||||
{
|
||||
if constexpr (Size == 2)
|
||||
{
|
||||
Utf8::Unchecked::utf8to16(first, last, AZStd::back_inserter(dest));
|
||||
Utf8::Unchecked::utf8to16(first, last, AZStd::back_inserter(dest), dest.max_size());
|
||||
}
|
||||
else if constexpr (Size == 4)
|
||||
{
|
||||
Utf8::Unchecked::utf8to32(first, last, AZStd::back_inserter(dest));
|
||||
Utf8::Unchecked::utf8to32(first, last, AZStd::back_inserter(dest), dest.max_size());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -326,6 +344,19 @@ namespace AZStd
|
||||
return to_string(dest, src.c_str(), src.length());
|
||||
}
|
||||
|
||||
inline void to_string(char* dest, size_t destSize, const wchar_t* str, size_t srcLen = 0)
|
||||
{
|
||||
if (srcLen == 0)
|
||||
{
|
||||
srcLen = wcslen(str) + 1;
|
||||
}
|
||||
|
||||
if (srcLen > 0)
|
||||
{
|
||||
Internal::WCharTPlatformConverter<>::to_string(dest, destSize, str, str + srcLen + 1); // copy null terminator
|
||||
}
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
int stoi(const AZStd::basic_string<wstring::value_type, wstring::traits_type, Allocator>& str, AZStd::size_t* idx = 0, int base = 10)
|
||||
{
|
||||
|
||||
@@ -92,33 +92,58 @@ namespace Utf8::Unchecked
|
||||
return temp;
|
||||
}
|
||||
|
||||
static Iterator to_utf8_sequence(AZ::u32 cp, Iterator result)
|
||||
static Iterator to_utf8_sequence(AZ::u32 cp, Iterator& result, size_t& resultMaxSize)
|
||||
{
|
||||
if (cp < 0x80)
|
||||
{
|
||||
// one octet
|
||||
resultMaxSize -= 1; // no need to check the calling function will exit the loop
|
||||
*(result++) = static_cast<AZ::u8>(cp);
|
||||
}
|
||||
else if (cp < 0x800)
|
||||
{
|
||||
// two octets
|
||||
*(result++) = static_cast<AZ::u8>((cp >> 6) | 0xc0);
|
||||
*(result++) = static_cast<AZ::u8>((cp & 0x3f) | 0x80);
|
||||
if (resultMaxSize >= 2)
|
||||
{
|
||||
*(result++) = static_cast<AZ::u8>((cp >> 6) | 0xc0);
|
||||
*(result++) = static_cast<AZ::u8>((cp & 0x3f) | 0x80);
|
||||
resultMaxSize -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
resultMaxSize = 0;
|
||||
}
|
||||
}
|
||||
else if (cp < 0x10000)
|
||||
{
|
||||
// three octets
|
||||
*(result++) = static_cast<AZ::u8>((cp >> 12) | 0xe0);
|
||||
*(result++) = static_cast<AZ::u8>(((cp >> 6) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<AZ::u8>((cp & 0x3f) | 0x80);
|
||||
if (resultMaxSize >= 3)
|
||||
{
|
||||
*(result++) = static_cast<AZ::u8>((cp >> 12) | 0xe0);
|
||||
*(result++) = static_cast<AZ::u8>(((cp >> 6) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<AZ::u8>((cp & 0x3f) | 0x80);
|
||||
resultMaxSize -= 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
resultMaxSize = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// four octets
|
||||
*(result++) = static_cast<AZ::u8>((cp >> 18) | 0xf0);
|
||||
*(result++) = static_cast<AZ::u8>(((cp >> 12) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<AZ::u8>(((cp >> 6) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<AZ::u8>((cp & 0x3f) | 0x80);
|
||||
if (resultMaxSize >= 4)
|
||||
{
|
||||
*(result++) = static_cast<AZ::u8>((cp >> 18) | 0xf0);
|
||||
*(result++) = static_cast<AZ::u8>(((cp >> 12) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<AZ::u8>(((cp >> 6) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<AZ::u8>((cp & 0x3f) | 0x80);
|
||||
resultMaxSize -= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
resultMaxSize = 0;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -155,9 +180,9 @@ namespace Utf8::Unchecked
|
||||
};
|
||||
|
||||
template <typename u16bit_iterator, typename Utf8Iterator>
|
||||
Utf8Iterator utf16to8(u16bit_iterator start, u16bit_iterator end, Utf8Iterator result)
|
||||
Utf8Iterator utf16to8(u16bit_iterator start, u16bit_iterator end, Utf8Iterator result, size_t resultMaxSize)
|
||||
{
|
||||
while (start != end)
|
||||
while (start != end && resultMaxSize > 0)
|
||||
{
|
||||
AZ::u32 cp = Utf8::Internal::mask16(*start++);
|
||||
// Take care of surrogate pairs first
|
||||
@@ -166,52 +191,62 @@ namespace Utf8::Unchecked
|
||||
AZ::u32 trail_surrogate = Utf8::Internal::mask16(*start++);
|
||||
cp = (cp << 10) + trail_surrogate + Internal::SURROGATE_OFFSET;
|
||||
}
|
||||
octet_iterator<Utf8Iterator>::to_utf8_sequence(cp, result);
|
||||
octet_iterator<Utf8Iterator>::to_utf8_sequence(cp, result, resultMaxSize);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename u16bit_iterator, typename Utf8Iterator>
|
||||
u16bit_iterator utf8to16(Utf8Iterator start, Utf8Iterator end, u16bit_iterator result)
|
||||
u16bit_iterator utf8to16(Utf8Iterator start, Utf8Iterator end, u16bit_iterator result, size_t resultMaxSize)
|
||||
{
|
||||
octet_iterator utf8Start(start);
|
||||
octet_iterator utf8Last(end);
|
||||
while (utf8Start != utf8Last)
|
||||
while (utf8Start != utf8Last && resultMaxSize > 0)
|
||||
{
|
||||
AZ::u32 cp = *utf8Start++;
|
||||
if (cp > 0xffff)
|
||||
{
|
||||
//make a surrogate pair
|
||||
*result++ = static_cast<AZ::u16>((cp >> 10) + Internal::LEAD_OFFSET);
|
||||
*result++ = static_cast<AZ::u16>((cp & 0x3ff) + Internal::TRAIL_SURROGATE_MIN);
|
||||
if (resultMaxSize >= 2)
|
||||
{
|
||||
*result++ = static_cast<AZ::u16>((cp >> 10) + Internal::LEAD_OFFSET);
|
||||
*result++ = static_cast<AZ::u16>((cp & 0x3ff) + Internal::TRAIL_SURROGATE_MIN);
|
||||
resultMaxSize -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
resultMaxSize = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*result++ = static_cast<AZ::u16>(cp);
|
||||
resultMaxSize -= 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Utf8Iterator, typename u32bit_iterator>
|
||||
Utf8Iterator utf32to8(u32bit_iterator start, u32bit_iterator end, Utf8Iterator result)
|
||||
Utf8Iterator utf32to8(u32bit_iterator start, u32bit_iterator end, Utf8Iterator result, size_t resultMaxSize)
|
||||
{
|
||||
while (start != end)
|
||||
while (start != end && resultMaxSize > 0)
|
||||
{
|
||||
octet_iterator<Utf8Iterator>::to_utf8_sequence(*start++, result);
|
||||
octet_iterator<Utf8Iterator>::to_utf8_sequence(*start++, result, resultMaxSize);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Utf8Iterator, typename u32bit_iterator>
|
||||
u32bit_iterator utf8to32(Utf8Iterator start, Utf8Iterator end, u32bit_iterator result)
|
||||
u32bit_iterator utf8to32(Utf8Iterator start, Utf8Iterator end, u32bit_iterator result, size_t resultMaxSize)
|
||||
{
|
||||
octet_iterator utf8Start(start);
|
||||
octet_iterator utf8Last(end);
|
||||
while (utf8Start != utf8Last)
|
||||
while (utf8Start != utf8Last && resultMaxSize > 0)
|
||||
{
|
||||
*result++ = *utf8Start++;
|
||||
--resultMaxSize;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzCore/PlatformIncl.h>
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -29,7 +30,9 @@ namespace AZ
|
||||
result.m_pathIncludesFilename = true;
|
||||
// Platform specific get exe path: http://stackoverflow.com/a/1024937
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulefilenamea
|
||||
const DWORD pathLen = GetModuleFileNameA(nullptr, exeStorageBuffer, static_cast<DWORD>(exeStorageSize));
|
||||
AZStd::wstring pathBuffer;
|
||||
pathBuffer.resize(exeStorageSize);
|
||||
const DWORD pathLen = GetModuleFileName(nullptr, pathBuffer.data(), static_cast<DWORD>(exeStorageSize));
|
||||
const DWORD errorCode = GetLastError();
|
||||
if (pathLen == exeStorageSize && errorCode == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
@@ -39,6 +42,10 @@ namespace AZ
|
||||
{
|
||||
result.m_pathStored = ExecutablePathResult::GeneralError;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZStd::to_string(exeStorageBuffer, exeStorageSize, pathBuffer.c_str());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -628,10 +628,6 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(AZ_COMPILER_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning( disable: 4428 ) // universal-character-name encountered in source
|
||||
#endif // AZ_COMPILER_MSVC
|
||||
TEST_F(String, Algorithms)
|
||||
{
|
||||
string str = string::format("%s %d", "BlaBla", 5);
|
||||
@@ -1114,11 +1110,6 @@ namespace UnitTest
|
||||
EXPECT_FALSE(other2.Valid());
|
||||
}
|
||||
|
||||
// StringAlgorithmTest-End
|
||||
#if defined(AZ_COMPILER_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif // AZ_COMPILER_MSVC
|
||||
|
||||
TEST_F(String, ConstString)
|
||||
{
|
||||
string_view cstr1;
|
||||
|
||||
Reference in New Issue
Block a user