ft2-clone

Fasttracker 2 clone
Log | Files | Refs | README | LICENSE

ft2_unicode.c (6517B)


      1 // for finding memory leaks in debug mode with Visual Studio
      2 #if defined _DEBUG && defined _MSC_VER
      3 #include <crtdbg.h>
      4 #endif
      5 
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <stdint.h>
      9 #include <stdbool.h>
     10 #ifdef _WIN32
     11 #define WIN32_LEAN_AND_MEAN
     12 #include <windows.h>
     13 #else
     14 #include <iconv.h>
     15 #endif
     16 #include "ft2_unicode.h"
     17 
     18 #ifdef _WIN32
     19 
     20 // Windows routines
     21 char *cp850ToUtf8(char *src)
     22 {
     23 	int32_t retVal;
     24 
     25 	if (src == NULL)
     26 		return NULL;
     27 
     28 	int32_t srcLen = (int32_t)strlen(src);
     29 	if (srcLen <= 0)
     30 		return NULL;
     31 
     32 	int32_t reqSize = MultiByteToWideChar(850, 0, src, srcLen, 0, 0);
     33 	if (reqSize <= 0)
     34 		return NULL;
     35 
     36 	wchar_t *w = (wchar_t *)malloc((reqSize + 1) * sizeof (wchar_t));
     37 	if (w == NULL)
     38 		return NULL;
     39 
     40 	w[reqSize] = 0;
     41 
     42 	retVal = MultiByteToWideChar(850, 0, src, srcLen, w, reqSize);
     43 	if (!retVal)
     44 	{
     45 		free(w);
     46 		return NULL;
     47 	}
     48 
     49 	srcLen = (int32_t)wcslen(w);
     50 	if (srcLen <= 0)
     51 		return NULL;
     52 
     53 	reqSize = WideCharToMultiByte(CP_UTF8, 0, w, srcLen, 0, 0, 0, 0);
     54 	if (reqSize <= 0)
     55 	{
     56 		free(w);
     57 		return NULL;
     58 	}
     59 
     60 	char *x = (char *)malloc((reqSize + 1) * sizeof (char));
     61 	if (x == NULL)
     62 	{
     63 		free(w);
     64 		return NULL;
     65 	}
     66 
     67 	x[reqSize] = '\0';
     68 
     69 	retVal = WideCharToMultiByte(CP_UTF8, 0, w, srcLen, x, reqSize, 0, 0);
     70 	free(w);
     71 
     72 	if (!retVal)
     73 	{
     74 		free(x);
     75 		return NULL;
     76 	}
     77 
     78 	return x;
     79 }
     80 
     81 UNICHAR *cp850ToUnichar(char *src)
     82 {
     83 	if (src == NULL)
     84 		return NULL;
     85 
     86 	int32_t srcLen = (int32_t)strlen(src);
     87 	if (srcLen <= 0)
     88 		return NULL;
     89 
     90 	int32_t reqSize = MultiByteToWideChar(850, 0, src, srcLen, 0, 0);
     91 	if (reqSize <= 0)
     92 		return NULL;
     93 
     94 	UNICHAR *w = (wchar_t *)malloc((reqSize + 1) * sizeof (wchar_t));
     95 	if (w == NULL)
     96 		return NULL;
     97 
     98 	w[reqSize] = 0;
     99 
    100 	int32_t retVal = MultiByteToWideChar(850, 0, src, srcLen, w, reqSize);
    101 	if (!retVal)
    102 	{
    103 		free(w);
    104 		return NULL;
    105 	}
    106 
    107 	return w;
    108 }
    109 
    110 char *utf8ToCp850(char *src, bool removeIllegalChars)
    111 {
    112 	if (src == NULL)
    113 		return NULL;
    114 
    115 	int32_t srcLen = (int32_t)strlen(src);
    116 	if (srcLen <= 0)
    117 		return NULL;
    118 
    119 	int32_t reqSize = MultiByteToWideChar(CP_UTF8, 0, src, srcLen, 0, 0);
    120 	if (reqSize <= 0)
    121 		return NULL;
    122 
    123 	wchar_t *w = (wchar_t *)malloc((reqSize + 1) * sizeof (wchar_t));
    124 	if (w == NULL)
    125 		return NULL;
    126 
    127 	w[reqSize] = 0;
    128 
    129 	int32_t retVal = MultiByteToWideChar(CP_UTF8, 0, src, srcLen, w, reqSize);
    130 	if (!retVal)
    131 	{
    132 		free(w);
    133 		return NULL;
    134 	}
    135 
    136 	srcLen = (int32_t)wcslen(w);
    137 	if (srcLen <= 0)
    138 	{
    139 		free(w);
    140 		return NULL;
    141 	}
    142 
    143 	reqSize = WideCharToMultiByte(850, 0, w, srcLen, 0, 0, 0, 0);
    144 	if (reqSize <= 0)
    145 	{
    146 		free(w);
    147 		return NULL;
    148 	}
    149 
    150 	char *x = (char *)malloc((reqSize + 1) * sizeof (char));
    151 	if (x == NULL)
    152 	{
    153 		free(w);
    154 		return NULL;
    155 	}
    156 
    157 	x[reqSize] = '\0';
    158 
    159 	retVal = WideCharToMultiByte(850, 0, w, srcLen, x, reqSize, 0, 0);
    160 	free(w);
    161 
    162 	if (!retVal)
    163 	{
    164 		free(x);
    165 		return NULL;
    166 	}
    167 
    168 	if (removeIllegalChars)
    169 	{
    170 		// remove illegal characters (only allow certain nordic ones)
    171 		for (int32_t i = 0; i < reqSize; i++)
    172 		{
    173 			const int8_t ch = (const int8_t)x[i];
    174 			if (ch != '\0' && ch < 32 &&
    175 			    ch != -124 && ch != -108 && ch != -122 && ch != -114 && ch != -103 &&
    176 			    ch != -113 && ch != -101 && ch != -99 && ch != -111 && ch != -110)
    177 			{
    178 				x[i] = ' '; // character not allowed, turn it into space
    179 			}
    180 		}
    181 	}
    182 
    183 	return x;
    184 }
    185 
    186 char *unicharToCp850(UNICHAR *src, bool removeIllegalChars)
    187 {
    188 	if (src == NULL)
    189 		return NULL;
    190 
    191 	int32_t srcLen = (int32_t)UNICHAR_STRLEN(src);
    192 	if (srcLen <= 0)
    193 		return NULL;
    194 
    195 	int32_t reqSize = WideCharToMultiByte(850, 0, src, srcLen, 0, 0, 0, 0);
    196 	if (reqSize <= 0)
    197 		return NULL;
    198 
    199 	char *x = (char *)malloc((reqSize + 1) * sizeof (char));
    200 	if (x == NULL)
    201 		return NULL;
    202 
    203 	x[reqSize] = '\0';
    204 
    205 	int32_t retVal = WideCharToMultiByte(850, 0, src, srcLen, x, reqSize, 0, 0);
    206 	if (!retVal)
    207 	{
    208 		free(x);
    209 		return NULL;
    210 	}
    211 
    212 	if (removeIllegalChars)
    213 	{
    214 		// remove illegal characters (only allow certain nordic ones)
    215 		for (int32_t i = 0; i < reqSize; i++)
    216 		{
    217 			const int8_t ch = (const int8_t)x[i];
    218 			if (ch != '\0' && ch < 32 &&
    219 			    ch != -124 && ch != -108 && ch != -122 && ch != -114 && ch != -103 &&
    220 			    ch != -113 && ch != -101 && ch != -99 && ch != -111 && ch != -110)
    221 			{
    222 				x[i] = ' '; // character not allowed, turn it into space
    223 			}
    224 		}
    225 	}
    226 
    227 	return x;
    228 }
    229 
    230 #else
    231 
    232 // non-Windows routines
    233 char *cp850ToUtf8(char *src)
    234 {
    235 	if (src == NULL)
    236 		return NULL;
    237 
    238 	size_t srcLen = strlen(src);
    239 	if (srcLen <= 0)
    240 		return NULL;
    241 
    242 	iconv_t cd = iconv_open("UTF-8", "850");
    243 	if (cd == (iconv_t)-1)
    244 		return NULL;
    245 
    246 	size_t outLen = srcLen * 4; // should be sufficient
    247 
    248 	char *outBuf = (char *)calloc(outLen + 1, sizeof (char));
    249 	if (outBuf == NULL)
    250 		return NULL;
    251 
    252 	char *inPtr = src;
    253 	size_t inLen = srcLen;
    254 	char *outPtr = outBuf;
    255 
    256 #if defined(__NetBSD__) || defined(__sun) || defined(sun)
    257 	int32_t rc = iconv(cd, (const char **)&inPtr, &inLen, &outPtr, &outLen);
    258 #else
    259 	int32_t rc = iconv(cd, &inPtr, &inLen, &outPtr, &outLen);
    260 #endif
    261 	iconv(cd, NULL, NULL, &outPtr, &outLen); // flush
    262 	iconv_close(cd);
    263 
    264 	if (rc == -1)
    265 	{
    266 		free(outBuf);
    267 		return NULL;
    268 	}
    269 
    270 	outBuf[outLen] = '\0';
    271 
    272 	return outBuf;
    273 }
    274 
    275 char *utf8ToCp850(char *src, bool removeIllegalChars)
    276 {
    277 	if (src == NULL)
    278 		return NULL;
    279 
    280 	size_t srcLen = strlen(src);
    281 	if (srcLen <= 0)
    282 		return NULL;
    283 
    284 #ifdef __APPLE__
    285 	iconv_t cd = iconv_open("850//TRANSLIT//IGNORE", "UTF-8-MAC");
    286 #elif defined(__NetBSD__) || defined(__sun) || defined(sun)
    287 	iconv_t cd = iconv_open("850", "UTF-8");
    288 #else
    289 	iconv_t cd = iconv_open("850//TRANSLIT//IGNORE", "UTF-8");
    290 #endif
    291 	if (cd == (iconv_t)-1)
    292 		return NULL;
    293 
    294 	size_t outLen = srcLen * 4; // should be sufficient
    295 
    296 	char *outBuf = (char *)calloc(outLen + 1, sizeof (char));
    297 	if (outBuf == NULL)
    298 		return NULL;
    299 
    300 	char *inPtr = src;
    301 	size_t inLen = srcLen;
    302 	char *outPtr = outBuf;
    303 
    304 #if defined(__NetBSD__) || defined(__sun) || defined(sun)
    305 	int32_t rc = iconv(cd, (const char **)&inPtr, &inLen, &outPtr, &outLen);
    306 #else
    307 	int32_t rc = iconv(cd, &inPtr, &inLen, &outPtr, &outLen);
    308 #endif
    309 	iconv(cd, NULL, NULL, &outPtr, &outLen); // flush
    310 	iconv_close(cd);
    311 
    312 	if (rc == -1)
    313 	{
    314 		free(outBuf);
    315 		return NULL;
    316 	}
    317 
    318 	outBuf[outLen] = '\0';
    319 
    320 	if (removeIllegalChars)
    321 	{
    322 		// remove illegal characters (only allow certain nordic ones)
    323 		for (size_t i = 0; i < outLen; i++)
    324 		{
    325 			const int8_t ch = (const int8_t)outBuf[i];
    326 			if (ch != '\0' && ch < 32 &&
    327 			    ch != -124 && ch != -108 && ch != -122 && ch != -114 && ch != -103 &&
    328 			    ch != -113 && ch != -101 && ch != -99 && ch != -111 && ch != -110)
    329 			{
    330 				outBuf[i] = ' '; // character not allowed, turn it into space
    331 			}
    332 		}
    333 	}
    334 
    335 	return outBuf;
    336 }
    337 #endif