AuroraRuntime/Source/Locale/LocaleConvertWide.cpp

109 lines
2.9 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: LocaleConvertWide.cpp
Date: 2022-9-15
File: Locale.cpp
Date: 2021-6-11
Author: Reece
***/
#define I_REALLY_NEED_WIDECHAR_PUBAPI
#include <Source/RuntimeInternal.hpp>
#include "Locale.hpp"
#if !defined(AU_NO_CPPLOCALE)
#include <locale>
#include <codecvt>
#endif
#include <wchar.h>
namespace Aurora::Locale
{
// Note: [0] out of touch boomers deprecated std::wstring_convert before going for a nappy. we do not have a replacement yet
// [1] the native win32 implementation appears to be more optimized than MSVC/stl
#if !defined(AU_NO_CPPLOCALE) && !(defined(AURORA_COMPILER_MSVC) && defined(AU_LANG_CPP_20))
static std::wstring_convert<std::codecvt_utf8<wchar_t>> gUtf8Conv;
#endif
AUKN_SYM AuString ConvertFromWChar(const wchar_t *in)
{
AU_DEBUG_MEMCRUNCH;
try
{
return ConvertFromWChar(in, wcslen(in));
}
catch (...)
{
SysPushErrorMem("ConvertFromWChar failed");
return {};
}
}
AUKN_SYM AuString ConvertFromWChar(const wchar_t *in, AuMach length)
{
AU_DEBUG_MEMCRUNCH;
try
{
#if defined(AU_HAS_MSFT_NATIONALLANGSUPPORT)
AuString ret;
auto chars = WideCharToMultiByte(CP_UTF8, 0, in, length, NULL, 0, NULL, NULL);
if (!chars)
{
return {};
}
ret.resize(chars);
WideCharToMultiByte(CP_UTF8, 0, in, length, ret.data(), ret.size(), NULL, NULL);
return ret;
#elif !defined(AU_NO_CPPLOCALE)
return AuString(gUtf8Conv.to_bytes(std::wstring(in, wcsnlen(in, length))));
#else
SysPushErrorUnimplemented("ConvertFromWChar");
return {};
#endif
}
catch (...)
{
SysPushErrorMem("ConvertFromWChar failed");
Debug::CheckErrors();
}
return {};
}
AUKN_SYM std::wstring ConvertFromUTF8(const AuROString &in)
{
AU_DEBUG_MEMCRUNCH;
try
{
#if defined(AU_HAS_MSFT_NATIONALLANGSUPPORT)
std::wstring ret;
auto chars = MultiByteToWideChar(CP_UTF8, 0, in.data(), in.length(), NULL, 0);
if (!chars)
{
return {};
}
ret.resize(chars);
MultiByteToWideChar(CP_UTF8, 0, in.data(), in.length(), ret.data(), ret.size());
return ret;
#elif !defined(AU_NO_CPPLOCALE)
return gUtf8Conv.from_bytes(in.data(), in.data() + in.size());
#else
SysPushErrorUnimplemented("ConvertFromUTF8");
return {};
#endif
}
catch (...)
{
SysPushErrorMem("ConvertFromUTF8 failed");
Debug::CheckErrors();
}
return {};
}
}