view dep/animone/src/util/win32.cc @ 347:a0aa8c8c4307

dep/anitomy: port to use UCS-4 rather than wide strings rationale: wide strings are not the same on every platform, and might not even be Unicode. (while they usually are, its possible that they are not) I was *going* to change StringToInt to use a string stream, but outputting to an integer doesn't seem to work at all with UCS-4, even though it ought to, so I just rolled my own that uses the arabic digits only.
author Paper <paper@paper.us.eu.org>
date Sun, 23 Jun 2024 10:32:09 -0400
parents 74e2365326c6
children
line wrap: on
line source

/*
 * util/win32.cc: utility functions only useful on windows
 */
#include "animone/util/win32.h"

#include <shlobj.h>  /* SHGetKnownFolderPath */
#include <subauth.h> /* UNICODE_STRING */
#include <windows.h>

namespace animone::internal::win32 {

std::string ToUtf8String(const std::wstring& string) {
	if (string.empty())
		return std::string();

	long size = ::WideCharToMultiByte(CP_UTF8, 0, string.c_str(), string.length(), nullptr, 0, nullptr, nullptr);
	std::string ret(size, '\0');
	::WideCharToMultiByte(CP_UTF8, 0, string.c_str(), string.length(), &ret.front(), ret.length(), nullptr, nullptr);
	return ret;
}

std::string ToUtf8String(const UNICODE_STRING& string) {
	const auto wctomb = [&string](LPSTR out, int size) -> int {
		return ::WideCharToMultiByte(CP_UTF8, 0, string.Buffer, string.Length, out, size, nullptr, nullptr);
	};

	if (string.Length <= 0)
		return std::string();

	long size = wctomb(nullptr, 0);
	std::string ret(size, '\0');
	wctomb(&ret.front(), ret.length());
	return ret;
}

std::wstring ToWstring(const std::string& string) {
	const auto mbtowc = [&string](LPWSTR out, int size) -> int {
		return ::MultiByteToWideChar(CP_UTF8, 0, string.c_str(), string.length(), out, size);
	};

	if (string.empty())
		return std::wstring();

	long size = mbtowc(nullptr, 0);
	std::wstring ret(size, L'\0');
	mbtowc(&ret.front(), ret.length());
	return ret;
}

} // namespace animone::internal::win32