Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenwcs.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS CRT library 00003 * LICENSE: LGPL - See COPYING in the top level directory 00004 * FILE: lib/sdk/crt/string/wcs.c 00005 * PURPOSE: wcs* CRT functions 00006 * PROGRAMMERS: Wine team 00007 * Ported to ReactOS by Aleksey Bragin (aleksey@reactos.org) 00008 */ 00009 00010 /* 00011 * msvcrt.dll wide-char functions 00012 * 00013 * Copyright 1999 Alexandre Julliard 00014 * Copyright 2000 Jon Griffiths 00015 * 00016 * This library is free software; you can redistribute it and/or 00017 * modify it under the terms of the GNU Lesser General Public 00018 * License as published by the Free Software Foundation; either 00019 * version 2.1 of the License, or (at your option) any later version. 00020 * 00021 * This library is distributed in the hope that it will be useful, 00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00024 * Lesser General Public License for more details. 00025 * 00026 * You should have received a copy of the GNU Lesser General Public 00027 * License along with this library; if not, write to the Free Software 00028 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00029 */ 00030 #include <precomp.h> 00031 #include <assert.h> 00032 00033 #ifndef _LIBCNT_ 00034 #include <internal/wine/msvcrt.h> 00035 #endif 00036 00037 #include "wine/unicode.h" 00038 #undef sprintf 00039 #undef wsprintf 00040 #undef snprintf 00041 #undef vsnprintf 00042 #undef vprintf 00043 #undef vwprintf 00044 00045 #ifdef _MSC_VER 00046 #pragma function(_wcsset) 00047 #endif 00048 00049 #ifndef _LIBCNT_ 00050 /********************************************************************* 00051 * _wcsdup (MSVCRT.@) 00052 */ 00053 wchar_t* CDECL _wcsdup( const wchar_t* str ) 00054 { 00055 wchar_t* ret = NULL; 00056 if (str) 00057 { 00058 size_t size = (strlenW(str) + 1) * sizeof(wchar_t); 00059 ret = malloc( size ); 00060 if (ret) memcpy( ret, str, size ); 00061 } 00062 return ret; 00063 } 00064 /********************************************************************* 00065 * _wcsicoll (MSVCRT.@) 00066 */ 00067 INT CDECL _wcsicoll( const wchar_t* str1, const wchar_t* str2 ) 00068 { 00069 /* FIXME: handle collates */ 00070 return strcmpiW( str1, str2 ); 00071 } 00072 #endif 00073 00074 /********************************************************************* 00075 * _wcsnset (MSVCRT.@) 00076 */ 00077 wchar_t* CDECL _wcsnset( wchar_t* str, wchar_t c, size_t n ) 00078 { 00079 wchar_t* ret = str; 00080 while ((n-- > 0) && *str) *str++ = c; 00081 return ret; 00082 } 00083 00084 /********************************************************************* 00085 * _wcsrev (MSVCRT.@) 00086 */ 00087 wchar_t* CDECL _wcsrev( wchar_t* str ) 00088 { 00089 wchar_t* ret = str; 00090 wchar_t* end = str + strlenW(str) - 1; 00091 while (end > str) 00092 { 00093 wchar_t t = *end; 00094 *end-- = *str; 00095 *str++ = t; 00096 } 00097 return ret; 00098 } 00099 00100 #ifndef _LIBCNT_ 00101 /********************************************************************* 00102 * _wcsset (MSVCRT.@) 00103 */ 00104 wchar_t* CDECL _wcsset( wchar_t* str, wchar_t c ) 00105 { 00106 wchar_t* ret = str; 00107 while (*str) *str++ = c; 00108 return ret; 00109 } 00110 00111 /****************************************************************** 00112 * _wcsupr_s (MSVCRT.@) 00113 * 00114 */ 00115 INT CDECL _wcsupr_s( wchar_t* str, size_t n ) 00116 { 00117 wchar_t* ptr = str; 00118 00119 if (!str || !n) 00120 { 00121 if (str) *str = '\0'; 00122 _set_errno(EINVAL); 00123 return EINVAL; 00124 } 00125 00126 while (n--) 00127 { 00128 if (!*ptr) return 0; 00129 *ptr = toupperW(*ptr); 00130 ptr++; 00131 } 00132 00133 /* MSDN claims that the function should return and set errno to 00134 * ERANGE, which doesn't seem to be true based on the tests. */ 00135 *str = '\0'; 00136 _set_errno(EINVAL); 00137 return EINVAL; 00138 } 00139 00140 /********************************************************************* 00141 * wcstod (MSVCRT.@) 00142 */ 00143 double CDECL wcstod(const wchar_t* lpszStr, wchar_t** end) 00144 { 00145 const wchar_t* str = lpszStr; 00146 int negative = 0; 00147 double ret = 0, divisor = 10.0; 00148 00149 TRACE("(%s,%p) semi-stub\n", debugstr_w(lpszStr), end); 00150 00151 /* FIXME: 00152 * - Should set errno on failure 00153 * - Should fail on overflow 00154 * - Need to check which input formats are allowed 00155 */ 00156 while (isspaceW(*str)) 00157 str++; 00158 00159 if (*str == '-') 00160 { 00161 negative = 1; 00162 str++; 00163 } 00164 00165 while (isdigitW(*str)) 00166 { 00167 ret = ret * 10.0 + (*str - '0'); 00168 str++; 00169 } 00170 if (*str == '.') 00171 str++; 00172 while (isdigitW(*str)) 00173 { 00174 ret = ret + (*str - '0') / divisor; 00175 divisor *= 10; 00176 str++; 00177 } 00178 00179 if (*str == 'E' || *str == 'e' || *str == 'D' || *str == 'd') 00180 { 00181 int negativeExponent = 0; 00182 int exponent = 0; 00183 if (*(++str) == '-') 00184 { 00185 negativeExponent = 1; 00186 str++; 00187 } 00188 while (isdigitW(*str)) 00189 { 00190 exponent = exponent * 10 + (*str - '0'); 00191 str++; 00192 } 00193 if (exponent != 0) 00194 { 00195 if (negativeExponent) 00196 ret = ret / pow(10.0, exponent); 00197 else 00198 ret = ret * pow(10.0, exponent); 00199 } 00200 } 00201 00202 if (negative) 00203 ret = -ret; 00204 00205 if (end) 00206 *end = (wchar_t*)str; 00207 00208 TRACE("returning %g\n", ret); 00209 return ret; 00210 } 00211 #endif 00212 00213 /********************************************************************* 00214 * wcscoll (MSVCRT.@) 00215 */ 00216 int CDECL wcscoll( const wchar_t* str1, const wchar_t* str2 ) 00217 { 00218 /* FIXME: handle collates */ 00219 return strcmpW( str1, str2 ); 00220 } 00221 00222 /********************************************************************* 00223 * wcspbrk (MSVCRT.@) 00224 */ 00225 wchar_t* CDECL wcspbrk( const wchar_t* str, const wchar_t* accept ) 00226 { 00227 const wchar_t* p; 00228 while (*str) 00229 { 00230 for (p = accept; *p; p++) if (*p == *str) return (wchar_t*)str; 00231 str++; 00232 } 00233 return NULL; 00234 } 00235 00236 #ifndef _LIBCNT_ 00237 00238 /********************************************************************* 00239 * wctomb (MSVCRT.@) 00240 */ 00241 INT CDECL wctomb(char *mbchar, wchar_t wchar) 00242 { 00243 BOOL bUsedDefaultChar; 00244 char chMultiByte[MB_LEN_MAX]; 00245 int nBytes; 00246 00247 /* At least one parameter needs to be given, the length of a null character cannot be queried (verified by tests under WinXP SP2) */ 00248 if(!mbchar && !wchar) 00249 return 0; 00250 00251 /* Use WideCharToMultiByte for doing the conversion using the codepage currently set with setlocale() */ 00252 nBytes = WideCharToMultiByte(MSVCRT___lc_codepage, 0, &wchar, 1, chMultiByte, MB_LEN_MAX, NULL, &bUsedDefaultChar); 00253 00254 /* Only copy the character if an 'mbchar' pointer was given. 00255 00256 The "C" locale is emulated with codepage 1252 here. This codepage has a default character "?", but the "C" locale doesn't have one. 00257 Therefore don't copy the character in this case. */ 00258 if(mbchar && !(MSVCRT_current_lc_all[0] == 'C' && !MSVCRT_current_lc_all[1] && bUsedDefaultChar)) 00259 memcpy(mbchar, chMultiByte, nBytes); 00260 00261 /* If the default character was used, set errno to EILSEQ and return -1. */ 00262 if(bUsedDefaultChar) 00263 { 00264 _set_errno(EILSEQ); 00265 return -1; 00266 } 00267 00268 /* Otherwise return the number of bytes this character occupies. */ 00269 return nBytes; 00270 } 00271 00272 size_t CDECL wcstombs(char *mbstr, const wchar_t *wcstr, size_t count) 00273 { 00274 BOOL bUsedDefaultChar; 00275 char* p = mbstr; 00276 int nResult; 00277 00278 /* Does the caller query for output buffer size? */ 00279 if(!mbstr) 00280 { 00281 int nLength; 00282 00283 /* If we currently use the "C" locale, the length of the input string is returned (verified by tests under WinXP SP2) */ 00284 if(MSVCRT_current_lc_all[0] == 'C' && !MSVCRT_current_lc_all[1]) 00285 return wcslen(wcstr); 00286 00287 /* Otherwise check the length each character needs and build a final return value out of this */ 00288 count = wcslen(wcstr); 00289 nLength = 0; 00290 00291 while((int)(--count) >= 0 && *wcstr) 00292 { 00293 /* Get the length of this character */ 00294 nResult = wctomb(NULL, *wcstr++); 00295 00296 /* If this character is not convertible in the current locale, the end result will be -1 */ 00297 if(nResult == -1) 00298 return -1; 00299 00300 nLength += nResult; 00301 } 00302 00303 /* Return the final length */ 00304 return nLength; 00305 } 00306 00307 /* Convert the string then */ 00308 bUsedDefaultChar = FALSE; 00309 00310 for(;;) 00311 { 00312 char chMultiByte[MB_LEN_MAX]; 00313 UINT uLength; 00314 00315 /* Are we at the terminating null character? */ 00316 if(!*wcstr) 00317 { 00318 /* Set the null character, but don't increment the pointer as the returned length never includes the terminating null character */ 00319 *p = 0; 00320 break; 00321 } 00322 00323 /* Convert this character into the temporary chMultiByte variable */ 00324 ZeroMemory(chMultiByte, MB_LEN_MAX); 00325 nResult = wctomb(chMultiByte, *wcstr++); 00326 00327 /* Check if this was an invalid character */ 00328 if(nResult == -1) 00329 bUsedDefaultChar = TRUE; 00330 00331 /* If we got no character, stop the conversion process here */ 00332 if(!chMultiByte[0]) 00333 break; 00334 00335 /* Determine whether this is a double-byte or a single-byte character */ 00336 if(chMultiByte[1]) 00337 uLength = 2; 00338 else 00339 uLength = 1; 00340 00341 /* Decrease 'count' by the character length and check if the buffer can still hold the full character */ 00342 count -= uLength; 00343 00344 if((int)count < 0) 00345 break; 00346 00347 /* It can, so copy it and move the pointer forward */ 00348 memcpy(p, chMultiByte, uLength); 00349 p += uLength; 00350 } 00351 00352 if(bUsedDefaultChar) 00353 return -1; 00354 00355 /* Return the length in bytes of the copied characters (without the terminating null character) */ 00356 return p - mbstr; 00357 } 00358 #endif 00359 00360 /********************************************************************* 00361 * wcscpy_s (MSVCRT.@) 00362 */ 00363 INT CDECL wcscpy_s( wchar_t* wcDest, size_t numElement, const wchar_t *wcSrc) 00364 { 00365 size_t size = 0; 00366 00367 if(!wcDest || !numElement) 00368 return EINVAL; 00369 00370 wcDest[0] = 0; 00371 00372 if(!wcSrc) 00373 { 00374 return EINVAL; 00375 } 00376 00377 size = strlenW(wcSrc) + 1; 00378 00379 if(size > numElement) 00380 { 00381 return ERANGE; 00382 } 00383 00384 memcpy( wcDest, wcSrc, size*sizeof(WCHAR) ); 00385 00386 return 0; 00387 } 00388 00389 /****************************************************************** 00390 * wcsncpy_s (MSVCRT.@) 00391 */ 00392 INT CDECL wcsncpy_s( wchar_t* wcDest, size_t numElement, const wchar_t *wcSrc, 00393 size_t count ) 00394 { 00395 size_t size = 0; 00396 00397 if (!wcDest || !numElement) 00398 return EINVAL; 00399 00400 wcDest[0] = 0; 00401 00402 if (!wcSrc) 00403 { 00404 return EINVAL; 00405 } 00406 00407 size = min(strlenW(wcSrc), count); 00408 00409 if (size >= numElement) 00410 { 00411 return ERANGE; 00412 } 00413 00414 memcpy( wcDest, wcSrc, size*sizeof(WCHAR) ); 00415 wcDest[size] = '\0'; 00416 00417 return 0; 00418 } 00419 00420 /****************************************************************** 00421 * wcscat_s (MSVCRT.@) 00422 * 00423 */ 00424 INT CDECL wcscat_s(wchar_t* dst, size_t elem, const wchar_t* src) 00425 { 00426 wchar_t* ptr = dst; 00427 00428 if (!dst || elem == 0) return EINVAL; 00429 if (!src) 00430 { 00431 dst[0] = '\0'; 00432 return EINVAL; 00433 } 00434 00435 /* seek to end of dst string (or elem if no end of string is found */ 00436 while (ptr < dst + elem && *ptr != '\0') ptr++; 00437 while (ptr < dst + elem) 00438 { 00439 if ((*ptr++ = *src++) == '\0') return 0; 00440 } 00441 /* not enough space */ 00442 dst[0] = '\0'; 00443 return ERANGE; 00444 } 00445 00446 /********************************************************************* 00447 * wcsncat_s (MSVCRT.@) 00448 * 00449 */ 00450 INT CDECL wcsncat_s(wchar_t *dst, size_t elem, 00451 const wchar_t *src, size_t count) 00452 { 00453 size_t srclen; 00454 wchar_t dststart; 00455 INT ret = 0; 00456 00457 if (!MSVCRT_CHECK_PMT(dst != NULL) || !MSVCRT_CHECK_PMT(elem > 0)) 00458 { 00459 #ifndef _LIBCNT_ 00460 _set_errno(EINVAL); 00461 #endif 00462 return EINVAL; 00463 } 00464 if (!MSVCRT_CHECK_PMT(src != NULL || count == 0)) 00465 return EINVAL; 00466 if (count == 0) 00467 return 0; 00468 00469 for (dststart = 0; dststart < elem; dststart++) 00470 { 00471 if (dst[dststart] == '\0') 00472 break; 00473 } 00474 if (dststart == elem) 00475 { 00476 MSVCRT_INVALID_PMT("dst[elem] is not NULL terminated\n"); 00477 return EINVAL; 00478 } 00479 00480 if (count == _TRUNCATE) 00481 { 00482 srclen = strlenW(src); 00483 if (srclen >= (elem - dststart)) 00484 { 00485 srclen = elem - dststart - 1; 00486 ret = STRUNCATE; 00487 } 00488 } 00489 else 00490 srclen = min(strlenW(src), count); 00491 if (srclen < (elem - dststart)) 00492 { 00493 memcpy(&dst[dststart], src, srclen*sizeof(wchar_t)); 00494 dst[dststart+srclen] = '\0'; 00495 return ret; 00496 } 00497 MSVCRT_INVALID_PMT("dst[elem] is too small"); 00498 dst[0] = '\0'; 00499 return ERANGE; 00500 } 00501 Generated on Sun May 27 2012 04:36:46 for ReactOS by
1.7.6.1
|