Changeset 28903 in vbox for trunk/src/VBox/Runtime/r3
- Timestamp:
- Apr 29, 2010 2:58:12 PM (15 years ago)
- Location:
- trunk/src/VBox/Runtime/r3
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/init.cpp
r28800 r28903 234 234 { 235 235 /* 236 * Init C runtime locale before we do anything that may end up converting 237 * paths or we'll end up using the "C" locale for path conversion. 238 */ 239 setlocale(LC_CTYPE, ""); 240 241 /* 236 242 * The Process ID. 237 243 */ … … 309 315 * The remainder cannot easily be undone, so it has to go last. 310 316 */ 311 312 /* Init C runtime locale. */313 setlocale(LC_CTYPE, "");314 317 315 318 /* Fork and exit callbacks. */ -
trunk/src/VBox/Runtime/r3/posix/utf8-posix.cpp
r28800 r28903 30 30 *******************************************************************************/ 31 31 #include <iprt/string.h> 32 #include "internal/iprt.h" 33 32 34 #include <iprt/alloc.h> 33 35 #include <iprt/assert.h> … … 40 42 #include <wctype.h> 41 43 42 #ifdef RT_OS_SOLARIS 43 # include <langinfo.h> 44 #include <langinfo.h> 45 46 #include "internal/alignmentchecks.h" 47 #ifdef RT_WITH_ICONV_CACHE 48 # include "internal/thread.h" 49 # include "internal/string.h" 50 AssertCompile(sizeof(iconv_t) <= sizeof(void *)); 44 51 #endif 45 52 46 #include "internal/alignmentchecks.h" 47 48 49 /******************************************************************************* 50 * Internal Functions * 51 *******************************************************************************/ 52 static int rtstrConvert(const void *pvInput, size_t cbInput, const char *pszInputCS, void **ppvOutput, size_t cbOutput, const char *pszOutputCS, unsigned cFactor); 53 54 /** 55 * Gets the codeset of the current locale (LC_CTYPE). 56 * 57 * @returns Pointer to read-only string with the codeset name. 58 */ 59 const char *rtStrGetLocaleCodeset(void) 60 { 61 return nl_langinfo(CODESET); 62 } 63 64 65 #ifdef RT_WITH_ICONV_CACHE 66 67 /** 68 * Initializes the iconv handle cache associated with a thread. 69 * 70 * @param pThread The thread in question. 71 */ 72 void rtStrIconvCacheInit(PRTTHREADINT pThread) 73 { 74 for (size_t i = 0; i < RT_ELEMENTS(pThread->ahIconvs); i++) 75 pThread->ahIconvs[i] = (iconv_t)-1; 76 } 77 78 /** 79 * Destroys the iconv handle cache associated with a thread. 80 * 81 * @param pThread The thread in question. 82 */ 83 void rtStrIconvCacheDestroy(PRTTHREADINT pThread) 84 { 85 for (size_t i = 0; i < RT_ELEMENTS(pThread->ahIconvs); i++) 86 { 87 iconv_t hIconv = pThread->ahIconvs[i]; 88 pThread->ahIconvs[i] = NULL; 89 if (hIconv != (iconv_t)-1) 90 iconv_close(hIconv); 91 } 92 } 53 93 54 94 … … 66 106 * @param pszOutputCS Codeset of the input string. 67 107 * @param cFactor Input vs. output size factor. 68 */ 69 static int rtstrConvert(const void *pvInput, size_t cbInput, const char *pszInputCS, void **ppvOutput, size_t cbOutput, const char *pszOutputCS, unsigned cFactor) 108 * @param phIconv Pointer to the cache entry. 109 */ 110 static int rtstrConvertCached(const void *pvInput, size_t cbInput, const char *pszInputCS, 111 void **ppvOutput, size_t cbOutput, const char *pszOutputCS, 112 unsigned cFactor, iconv_t *phIconv) 113 { 114 /* 115 * Allocate buffer 116 */ 117 bool fUcs2Term; 118 void *pvOutput; 119 size_t cbOutput2; 120 if (!cbOutput) 121 { 122 cbOutput2 = cbInput * cFactor; 123 pvOutput = RTMemTmpAlloc(cbOutput2 + sizeof(RTUTF16)); 124 if (!pvOutput) 125 return VERR_NO_TMP_MEMORY; 126 fUcs2Term = true; 127 } 128 else 129 { 130 pvOutput = *ppvOutput; 131 fUcs2Term = !strcmp(pszOutputCS, "UCS-2") 132 || !strcmp(pszOutputCS, "UTF-16") 133 || !strcmp(pszOutputCS, "ucs-2") 134 || !strcmp(pszOutputCS, "utf-16"); 135 cbOutput2 = cbOutput - (fUcs2Term ? sizeof(RTUTF16) : 1); 136 if (cbOutput2 > cbOutput) 137 return VERR_BUFFER_OVERFLOW; 138 } 139 140 /* 141 * Use a loop here to retry with bigger buffers. 142 */ 143 for (unsigned cTries = 10; cTries > 0; cTries--) 144 { 145 /* 146 * Create conversion object if necessary. 147 */ 148 iconv_t hIconv = (iconv_t)*phIconv; 149 if (hIconv == (iconv_t)-1) 150 { 151 IPRT_ALIGNMENT_CHECKS_DISABLE(); /* glibc causes trouble */ 152 *phIconv = hIconv = iconv_open(pszOutputCS, pszInputCS); 153 IPRT_ALIGNMENT_CHECKS_ENABLE(); 154 } 155 if (hIconv != (iconv_t)-1) 156 { 157 /* 158 * Do the conversion. 159 */ 160 size_t cbInLeft = cbInput; 161 size_t cbOutLeft = cbOutput2; 162 const void *pvInputLeft = pvInput; 163 void *pvOutputLeft = pvOutput; 164 #if defined(RT_OS_LINUX) || (defined(RT_OS_DARWIN) && defined(_DARWIN_FEATURE_UNIX_CONFORMANCE)) /* there are different opinions about the constness of the input buffer. */ 165 if (iconv(hIconv, (char **)&pvInputLeft, &cbInLeft, (char **)&pvOutputLeft, &cbOutLeft) != (size_t)-1) 166 #else 167 if (iconv(hIconv, (const char **)&pvInputLeft, &cbInLeft, (char **)&pvOutputLeft, &cbOutLeft) != (size_t)-1) 168 #endif 169 { 170 if (!cbInLeft) 171 { 172 /* 173 * We're done, just add the terminator and return. 174 * (Two terminators to support UCS-2 output, too.) 175 */ 176 ((char *)pvOutputLeft)[0] = '\0'; 177 if (fUcs2Term) 178 ((char *)pvOutputLeft)[1] = '\0'; 179 *ppvOutput = pvOutput; 180 return VINF_SUCCESS; 181 } 182 errno = E2BIG; 183 } 184 185 /* 186 * If we failed because of output buffer space we'll 187 * increase the output buffer size and retry. 188 */ 189 if (errno == E2BIG) 190 { 191 if (!cbOutput) 192 { 193 RTMemTmpFree(pvOutput); 194 cbOutput2 *= 2; 195 pvOutput = RTMemTmpAlloc(cbOutput2 + sizeof(RTUTF16)); 196 if (!pvOutput) 197 return VERR_NO_TMP_MEMORY; 198 continue; 199 } 200 return VERR_BUFFER_OVERFLOW; 201 } 202 203 /* 204 * Close the handle on all other errors to make sure we won't carry 205 * any bad state with us. 206 */ 207 *phIconv = (iconv_t)-1; 208 iconv_close(hIconv); 209 } 210 break; 211 } 212 213 /* failure */ 214 if (!cbOutput) 215 RTMemTmpFree(pvOutput); 216 return VERR_NO_TRANSLATION; 217 } 218 219 #endif /* RT_WITH_ICONV_CACHE */ 220 221 /** 222 * Converts a string from one charset to another without using the handle cache. 223 * 224 * @returns IPRT status code. 225 * 226 * @param pvInput Pointer to intput string. 227 * @param cbInput Size (in bytes) of input string. Excludes any terminators. 228 * @param pszInputCS Codeset of the input string. 229 * @param ppvOutput Pointer to pointer to output buffer if cbOutput > 0. 230 * If cbOutput is 0 this is where the pointer to the allocated 231 * buffer is stored. 232 * @param cbOutput Size of the passed in buffer. 233 * @param pszOutputCS Codeset of the input string. 234 * @param cFactor Input vs. output size factor. 235 */ 236 static int rtStrConvertUncached(const void *pvInput, size_t cbInput, const char *pszInputCS, 237 void **ppvOutput, size_t cbOutput, const char *pszOutputCS, 238 unsigned cFactor) 70 239 { 71 240 /* … … 103 272 /* Solaris doesn't grok empty codeset strings, so help it find the current codeset. */ 104 273 if (!*pszInputCS) 105 pszInputCS = nl_langinfo(CODESET);274 pszInputCS = rtStrGetLocaleCodeset(); 106 275 if (!*pszOutputCS) 107 pszOutputCS = nl_langinfo(CODESET);276 pszOutputCS = rtStrGetLocaleCodeset(); 108 277 #endif 109 278 IPRT_ALIGNMENT_CHECKS_DISABLE(); /* glibc causes trouble */ … … 171 340 172 341 /** 342 * Wrapper that selects rtStrConvertCached or rtStrConvertUncached. 343 * 344 * @returns IPRT status code. 345 * 346 * @param pszInput Pointer to intput string. 347 * @param cchInput Size (in bytes) of input string. Excludes any 348 * terminators. 349 * @param pszInputCS Codeset of the input string. 350 * @param ppszOutput Pointer to pointer to output buffer if cbOutput > 0. 351 * If cbOutput is 0 this is where the pointer to the 352 * allocated buffer is stored. 353 * @param cbOutput Size of the passed in buffer. 354 * @param pszOutputCS Codeset of the input string. 355 * @param cFactor Input vs. output size factor. 356 * @param enmCacheIdx The iconv cache index. 357 */ 358 DECLINLINE(int) rtStrConvertWrapper(const char *pchInput, size_t cchInput, const char *pszInputCS, 359 char **ppszOutput, size_t cbOutput, const char *pszOutputCS, 360 unsigned cFactor, RTSTRICONV enmCacheIdx) 361 { 362 #ifdef RT_WITH_ICONV_CACHE 363 RTTHREAD hSelf = RTThreadSelf(); 364 if (hSelf != NIL_RTTHREAD) 365 { 366 PRTTHREADINT pThread = rtThreadGet(hSelf); 367 if ( pThread 368 && (pThread->fIntFlags & (RTTHREADINT_FLAGS_ALIEN | RTTHREADINT_FLAGS_MAIN)) != RTTHREADINT_FLAGS_ALIEN) 369 return rtstrConvertCached(pchInput, cchInput, pszInputCS, 370 (void **)ppszOutput, cbOutput, pszOutputCS, 371 cFactor, &pThread->ahIconvs[enmCacheIdx]); 372 } 373 #endif 374 return rtStrConvertUncached(pchInput, cchInput, pszInputCS, 375 (void **)ppszOutput, cbOutput, pszOutputCS, 376 cFactor); 377 } 378 379 380 /** 381 * Internal API for use by the path conversion code. 382 * 383 * @returns IPRT status code. 384 * 385 * @param pszInput Pointer to intput string. 386 * @param cchInput Size (in bytes) of input string. Excludes any 387 * terminators. 388 * @param pszInputCS Codeset of the input string. 389 * @param ppszOutput Pointer to pointer to output buffer if cbOutput > 0. 390 * If cbOutput is 0 this is where the pointer to the 391 * allocated buffer is stored. 392 * @param cbOutput Size of the passed in buffer. 393 * @param pszOutputCS Codeset of the input string. 394 * @param cFactor Input vs. output size factor. 395 * @param enmCacheIdx The iconv cache index. 396 */ 397 int rtStrConvert(const char *pchInput, size_t cchInput, const char *pszInputCS, 398 char **ppszOutput, size_t cbOutput, const char *pszOutputCS, 399 unsigned cFactor, RTSTRICONV enmCacheIdx) 400 { 401 Assert(enmCacheIdx >= 0 && enmCacheIdx < RTSTRICONV_END); 402 return rtStrConvertWrapper(pchInput, cchInput, pszInputCS, 403 ppszOutput, cbOutput, pszOutputCS, 404 cFactor, enmCacheIdx); 405 } 406 407 408 /** 173 409 * Allocates tmp buffer, translates pszString from UTF8 to current codepage. 174 410 * … … 196 432 return VERR_NO_TMP_MEMORY; 197 433 } 198 return rt strConvert(pszString, cch, "UTF-8", (void **)ppszString, 0, "", 1);434 return rtStrConvertWrapper(pszString, cch, "UTF-8", ppszString, 0, "", 1, RTSTRICONV_UTF8_TO_LOCALE); 199 435 } 200 436 … … 215 451 216 452 /* 217 * Attempt with UTF-8 length of 2x the native leng ht.453 * Attempt with UTF-8 length of 2x the native length. 218 454 */ 219 455 size_t cch = strlen(pszString); … … 226 462 return VERR_NO_TMP_MEMORY; 227 463 } 228 return rt strConvert(pszString, cch, "", (void **)ppszString, 0, "UTF-8", 2);229 } 230 464 return rtStrConvertWrapper(pszString, cch, "", ppszString, 0, "UTF-8", 2, RTSTRICONV_LOCALE_TO_UTF8); 465 } 466
Note:
See TracChangeset
for help on using the changeset viewer.