ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

wcs.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.