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