mirror of https://github.com/OpenRCT2/OpenRCT2.git
Make OpenRCT2 use iconv on Linux
This makes possible to run the game with non-english locales on Linux Fixes #2300, fixes #2268, fixes #2267
This commit is contained in:
parent
317c2f7c7d
commit
7ba9ea2574
|
@ -20,6 +20,9 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <iconv.h>
|
||||
#include <errno.h>
|
||||
#endif // _WIN32
|
||||
#include "../addresses.h"
|
||||
#include "../config.h"
|
||||
|
@ -835,38 +838,80 @@ utf8 *win1252_to_utf8_alloc(const char *src)
|
|||
return (utf8*)realloc(result, actualSpace);
|
||||
}
|
||||
|
||||
int win1252_to_utf8(utf8string dst, const char *src, int maxBufferLength)
|
||||
int win1252_to_utf8(utf8string dst, const char *src, size_t maxBufferLength)
|
||||
{
|
||||
size_t srcLength = strlen(src);
|
||||
|
||||
#ifdef _WIN32
|
||||
utf16 stackBuffer[256];
|
||||
utf16 *heapBuffer = NULL;
|
||||
utf16 *intermediateBuffer = stackBuffer;
|
||||
int bufferCount = countof(stackBuffer);
|
||||
|
||||
size_t bufferCount = countof(stackBuffer);
|
||||
if (maxBufferLength > bufferCount) {
|
||||
int srcLength = strlen(src);
|
||||
if (srcLength > bufferCount) {
|
||||
bufferCount = srcLength + 4;
|
||||
heapBuffer = malloc(bufferCount * sizeof(utf16));
|
||||
intermediateBuffer = heapBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
MultiByteToWideChar(CP_ACP, 0, src, -1, intermediateBuffer, bufferCount);
|
||||
int result = WideCharToMultiByte(CP_UTF8, 0, intermediateBuffer, -1, dst, maxBufferLength, NULL, NULL);
|
||||
#else
|
||||
//STUB();
|
||||
// we cannot walk past maxBufferLength, but in case we have still space left
|
||||
// we need one byte for null terminator
|
||||
int result = strnlen(src, maxBufferLength) + 1;
|
||||
result = min(result, maxBufferLength);
|
||||
safe_strncpy(dst, src, maxBufferLength);
|
||||
dst[maxBufferLength - 1] = '\0';
|
||||
#endif // _WIN32
|
||||
|
||||
if (heapBuffer != NULL) {
|
||||
free(heapBuffer);
|
||||
}
|
||||
#else
|
||||
//log_warning("converting %s of size %d", src, srcLength);
|
||||
char *buffer_conv = strndup(src, srcLength);
|
||||
char *buffer_orig = buffer_conv;
|
||||
const char *to_charset = "UTF8";
|
||||
const char *from_charset = "CP1252";
|
||||
iconv_t cd = iconv_open(to_charset, from_charset);
|
||||
if ((iconv_t)-1 == cd)
|
||||
{
|
||||
int error = errno;
|
||||
switch (error)
|
||||
{
|
||||
case EINVAL:
|
||||
log_error("Unsupported conversion from %s to %s, errno = %d", from_charset, to_charset, error);
|
||||
break;
|
||||
default:
|
||||
log_error("Unknown error while initializing iconv, errno = %d", error);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
size_t obl = maxBufferLength;
|
||||
char *outBuf = dst;
|
||||
size_t conversion_result = iconv(cd, &buffer_conv, &srcLength, &outBuf, &obl);
|
||||
if (conversion_result == (size_t)-1)
|
||||
{
|
||||
int error = errno;
|
||||
switch (error)
|
||||
{
|
||||
case EILSEQ:
|
||||
log_error("Encountered invalid sequence");
|
||||
break;
|
||||
case EINVAL:
|
||||
log_error("Encountered incomplete sequence");
|
||||
break;
|
||||
case E2BIG:
|
||||
log_error("Ran out of space");
|
||||
break;
|
||||
default:
|
||||
log_error("Unknown error encountered, errno = %d", error);
|
||||
}
|
||||
}
|
||||
int close_result = iconv_close(cd);
|
||||
if (close_result == -1)
|
||||
{
|
||||
log_error("Failed to close iconv, errno = %d", errno);
|
||||
}
|
||||
size_t byte_diff = maxBufferLength - obl + 1;
|
||||
dst[byte_diff - 1] = '\0';
|
||||
//log_warning("converted %s of size %d, %d", dst, byte_diff, strlen(dst));
|
||||
int result = byte_diff;
|
||||
free(buffer_orig);
|
||||
#endif // _WIN32
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ void user_string_free(rct_string_id id);
|
|||
bool is_user_string_id(rct_string_id stringId);
|
||||
|
||||
utf8 *win1252_to_utf8_alloc(const char *src);
|
||||
int win1252_to_utf8(utf8string dst, const char *src, int maxBufferLength);
|
||||
int win1252_to_utf8(utf8string dst, const char *src, size_t maxBufferLength);
|
||||
|
||||
int rct2_to_utf8(utf8 *dst, const char *src);
|
||||
int utf8_to_rct2(char *dst, const utf8 *src);
|
||||
|
|
Loading…
Reference in New Issue