Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

OS_String.cpp

Go to the documentation of this file.
00001 #include "ace_pch.h"
00002 //=============================================================================
00003 /**
00004  *  @file   OS_String.cpp
00005  *
00006  *  $Id: OS_String.cpp,v 1.1.1.3.2.1 2003/03/13 19:44:21 chad Exp $
00007  *
00008  *  @brief  Contains definitions for class ACE_OS_String.
00009  */
00010 //=============================================================================
00011 
00012 #include "ace/OS_String.h"
00013 #include "ace/OS_Memory.h"
00014 
00015 ACE_RCSID (ace, OS_String, "$Id: OS_String.cpp,v 1.1.1.3.2.1 2003/03/13 19:44:21 chad Exp $")
00016 
00017 #if !defined (ACE_HAS_INLINED_OSCALLS)
00018 # include "ace/OS_String.inl"
00019 #endif /* ACE_HAS_INLINED_OS_CALLS */
00020 
00021 #if defined (ACE_LACKS_WCSDUP_PROTOTYPE)
00022 extern "C" wchar_t *wcsdup __P ((__const wchar_t *__s));
00023 #endif /* ACE_LACKS_WCSDUP_PROTOTYPE */
00024 
00025 const char *
00026 ACE_OS_String::strnstr (const char *s1, const char *s2, size_t len2)
00027 {
00028   // Substring length
00029   size_t len1 = ACE_OS_String::strlen (s1);
00030 
00031   // Check if the substring is longer than the string being searched.
00032   if (len2 > len1)
00033     return 0;
00034 
00035   // Go upto <len>
00036   size_t len = len1 - len2;
00037 
00038   for (size_t i = 0; i <= len; i++)
00039     {
00040       if (ACE_OS_String::memcmp (s1 + i, s2, len2) == 0)
00041         // Found a match!  Return the index.
00042         return s1 + i;
00043     }
00044 
00045   return 0;
00046 }
00047 
00048 const ACE_WCHAR_T *
00049 ACE_OS_String::strnstr (const ACE_WCHAR_T *s1, const ACE_WCHAR_T *s2, size_t len2)
00050 {
00051   // Substring length
00052   size_t len1 = ACE_OS_String::strlen (s1);
00053 
00054   // Check if the substring is longer than the string being searched.
00055   if (len2 > len1)
00056     return 0;
00057 
00058   // Go upto <len>
00059   size_t len = len1 - len2;
00060 
00061   for (size_t i = 0; i <= len; i++)
00062     {
00063       if (ACE_OS_String::memcmp (s1 + i, s2, len2 * sizeof (ACE_WCHAR_T)) == 0)
00064         // Found a match!  Return the index.
00065         return s1 + i;
00066     }
00067 
00068   return 0;
00069 }
00070 
00071 char *
00072 ACE_OS_String::strdup (const char *s)
00073 {
00074 #if defined (ACE_HAS_STRDUP_EMULATION)
00075   char *t = (char *) ACE_OS_Memory::malloc (ACE_OS_String::strlen (s) + 1);
00076   if (t == 0)
00077     return 0;
00078 
00079   return ACE_OS_String::strcpy (t, s);
00080 #else
00081   return ::strdup (s);
00082 #endif /* ACE_HAS_STRDUP_EMULATION */
00083 }
00084 
00085 #if defined (ACE_HAS_WCHAR)
00086 wchar_t *
00087 ACE_OS_String::strdup (const wchar_t *s)
00088 {
00089 #   if defined (ACE_LACKS_WCSDUP)
00090   wchar_t *buffer =
00091     (wchar_t *) ACE_OS_Memory::malloc ((ACE_OS_String::strlen (s) + 1)
00092                                        * sizeof (wchar_t));
00093   if (buffer == 0)
00094     return 0;
00095 
00096   return ACE_OS_String::strcpy (buffer, s);
00097 #   elif defined (ACE_WCSDUP_EQUIVALENT)
00098   return ACE_WCSDUP_EQUIVALENT (s);
00099 #   else /* ACE_LACKS_WCSDUP */
00100 #     if defined (__MINGW32__)
00101   return ::wcsdup (ACE_const_cast(wchar_t*, s));
00102 #     else /* __MINGW32__ */
00103   return ::wcsdup (s);
00104 #     endif /* __MINGW32__ */
00105 #   endif /* ACE_LACKS_WCSDUP */
00106 }
00107 #endif /* ACE_HAS_WCHAR */
00108 
00109 #if defined (ACE_LACKS_STRERROR)
00110 /**
00111  * Just returns "Unknown Error" all the time.
00112  */
00113 char *
00114 ACE_OS_String::strerror_emulation (int errnum)
00115 {
00116   return "Unknown Error";
00117 }
00118 #endif /* ACE_LACKS_STRERROR */
00119 
00120 #if defined (ACE_LACKS_STRCHR)
00121 char *
00122 ACE_OS_String::strchr_emulation (char *s, int c)
00123 {
00124   for (;;++s)
00125     {
00126       if (*s == c)
00127         return s;
00128       if (*s == 0)
00129         return 0;
00130     }
00131 }
00132 
00133 const char *
00134 ACE_OS_String::strchr_emulation (const char *s, int c)
00135 {
00136   for (;;++s)
00137     {
00138       if (*s == c)
00139         return s;
00140       if (*s == 0)
00141         return 0;
00142     }
00143 }
00144 #endif /* ACE_LACKS_STRCHR */
00145 
00146 const char *
00147 ACE_OS_String::strnchr (const char *s, int c, size_t len)
00148 {
00149   for (size_t i = 0; i < len; i++)
00150     if (s[i] == c)
00151       return s + i;
00152 
00153   return 0;
00154 }
00155 
00156 const ACE_WCHAR_T *
00157 ACE_OS_String::strnchr (const ACE_WCHAR_T *s, ACE_WINT_T c, size_t len)
00158 {
00159   for (size_t i = 0; i < len; i++)
00160     if (s[i] == ACE_static_cast(ACE_WCHAR_T, c))
00161       return s + i;
00162 
00163   return 0;
00164 }
00165 
00166 #if defined (ACE_LACKS_STRRCHR)
00167 char *
00168 ACE_OS_String::strrchr_emulation (char *s, int c)
00169 {
00170   char *p = s + ACE_OS_String::strlen (s);
00171 
00172   while (*p != c)
00173     if (p == s)
00174       return 0;
00175     else
00176       p--;
00177 
00178   return p;
00179 }
00180 
00181 const char *
00182 ACE_OS_String::strrchr_emulation (const char *s, int c)
00183 {
00184   const char *p = s + ACE_OS_String::strlen (s);
00185 
00186   while (*p != c)
00187     if (p == s)
00188       return 0;
00189     else
00190       p--;
00191 
00192   return p;
00193 }
00194 #endif /* ACE_LACKS_STRRCHR */
00195 
00196 #if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSRCHR)
00197 const wchar_t *
00198 ACE_OS_String::wcsrchr_emulation (const wchar_t *s, wint_t c)
00199 {
00200   const wchar_t *p = s + ACE_OS_String::strlen (s);
00201 
00202   while (*p != ACE_static_cast (wchar_t, c))
00203     if (p == s)
00204       return 0;
00205     else
00206       p--;
00207 
00208   return p;
00209 }
00210 
00211 wchar_t *
00212 ACE_OS_String::wcsrchr_emulation (wchar_t *s, wint_t c)
00213 {
00214   wchar_t *p = s + ACE_OS_String::strlen (s);
00215 
00216   while (*p != ACE_static_cast(wchar_t, c))
00217     if (p == s)
00218       return 0;
00219     else
00220       p--;
00221 
00222   return p;
00223 }
00224 #endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSRCHR */
00225 
00226 char *
00227 ACE_OS_String::strecpy (char *s, const char *t)
00228 {
00229   register char *dscan = s;
00230   register const char *sscan = t;
00231 
00232   while ((*dscan++ = *sscan++) != '\0')
00233     continue;
00234 
00235   return dscan;
00236 }
00237 
00238 #if defined (ACE_HAS_WCHAR)
00239 wchar_t *
00240 ACE_OS_String::strecpy (wchar_t *s, const wchar_t *t)
00241 {
00242   register wchar_t *dscan = s;
00243   register const wchar_t *sscan = t;
00244 
00245   while ((*dscan++ = *sscan++) != ACE_TEXT_WIDE ('\0'))
00246     continue;
00247 
00248   return dscan;
00249 }
00250 #endif /* ACE_HAS_WCHAR */
00251 
00252 #if defined (ACE_LACKS_STRCSPN)
00253 size_t
00254 ACE_OS_String::strcspn_emulation (const char *s, const char *reject)
00255 {
00256   const char *scan;
00257   const char *rej_scan;
00258   int count = 0;
00259 
00260   for (scan = s; *scan; scan++)
00261     {
00262 
00263       for (rej_scan = reject; *rej_scan; rej_scan++)
00264         if (*scan == *rej_scan)
00265           return count;
00266 
00267       count++;
00268     }
00269 
00270   return count;
00271 }
00272 #endif /* ACE_LACKS_STRCSPN */
00273 
00274 #if defined (ACE_LACKS_STRCASECMP)
00275 int
00276 ACE_OS_String::strcasecmp_emulation (const char *s, const char *t)
00277 {
00278   const char *scan1 = s;
00279   const char *scan2 = t;
00280 
00281   while (*scan1 != 0
00282          && ACE_OS_String::to_lower (*scan1)
00283             == ACE_OS_String::to_lower (*scan2))
00284     {
00285       ++scan1;
00286       ++scan2;
00287     }
00288 
00289   // The following case analysis is necessary so that characters which
00290   // look negative collate low against normal characters but high
00291   // against the end-of-string NUL.
00292 
00293   if (*scan1 == '\0' && *scan2 == '\0')
00294     return 0;
00295   else if (*scan1 == '\0')
00296     return -1;
00297   else if (*scan2 == '\0')
00298     return 1;
00299   else
00300     return ACE_OS_String::to_lower (*scan1) - ACE_OS_String::to_lower (*scan2);
00301 }
00302 #endif /* ACE_LACKS_STRCASECMP */
00303 
00304 #if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSICMP)
00305 int
00306 ACE_OS_String::wcsicmp_emulation (const wchar_t *s, const wchar_t *t)
00307 {
00308   const wchar_t *scan1 = s;
00309   const wchar_t *scan2 = t;
00310 
00311   while (*scan1 != 0
00312          && ACE_OS_String::to_lower (*scan1)
00313             == ACE_OS_String::to_lower (*scan2))
00314     {
00315       ++scan1;
00316       ++scan2;
00317     }
00318 
00319   // The following case analysis is necessary so that characters which
00320   // look negative collate low against normal characters but high
00321   // against the end-of-string NUL.
00322 
00323   if (*scan1 == '\0' && *scan2 == '\0')
00324     return 0;
00325   else if (*scan1 == '\0')
00326     return -1;
00327   else if (*scan2 == '\0')
00328     return 1;
00329   else
00330     return ACE_OS_String::to_lower (*scan1) - ACE_OS_String::to_lower (*scan2);
00331 }
00332 #endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSICMP */
00333 
00334 #if defined (ACE_LACKS_STRCASECMP)
00335 int
00336 ACE_OS_String::strncasecmp_emulation (const char *s,
00337                                       const char *t,
00338                                       size_t len)
00339 {
00340   const char *scan1 = s;
00341   const char *scan2 = t;
00342   size_t count = 0;
00343 
00344   while (count++ < len
00345          && *scan1 != 0
00346          && ACE_OS_String::to_lower (*scan1)
00347             == ACE_OS_String::to_lower (*scan2))
00348     {
00349       ++scan1;
00350       ++scan2;
00351     }
00352 
00353   if (count > len)
00354     return 0;
00355 
00356   // The following case analysis is necessary so that characters which
00357   // look negative collate low against normal characters but high
00358   // against the end-of-string NUL.
00359 
00360   if (*scan1 == '\0' && *scan2 == '\0')
00361     return 0;
00362   else if (*scan1 == '\0')
00363     return -1;
00364   else if (*scan2 == '\0')
00365     return 1;
00366   else
00367     return ACE_OS_String::to_lower (*scan1) - ACE_OS_String::to_lower (*scan2);
00368 }
00369 #endif /* ACE_LACKS_STRCASECMP */
00370 
00371 #if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSNICMP)
00372 int
00373 ACE_OS_String::wcsnicmp_emulation (const wchar_t *s,
00374                                    const wchar_t *t,
00375                                    size_t len)
00376 {
00377   const wchar_t *scan1 = s;
00378   const wchar_t *scan2 = t;
00379   size_t count = 0;
00380 
00381   while (count++ < len
00382          && *scan1 != 0
00383          && ACE_OS_String::to_lower (*scan1)
00384             == ACE_OS_String::to_lower (*scan2))
00385     {
00386       ++scan1;
00387       ++scan2;
00388     }
00389 
00390   if (count > len)
00391     return 0;
00392 
00393   // The following case analysis is necessary so that characters which
00394   // look negative collate low against normal characters but high
00395   // against the end-of-string NUL.
00396 
00397   if (*scan1 == '\0' && *scan2 == '\0')
00398     return 0;
00399   else if (*scan1 == '\0')
00400     return -1;
00401   else if (*scan2 == '\0')
00402     return 1;
00403   else
00404     return ACE_OS_String::to_lower (*scan1) - ACE_OS_String::to_lower (*scan2);
00405 }
00406 #endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSNICMP */
00407 
00408 #if !defined (ACE_HAS_REENTRANT_FUNCTIONS)
00409 char *
00410 ACE_OS_String::strtok_r_emulation (char *s, const char *tokens, char **lasts)
00411 {
00412   if (s == 0)
00413     s = *lasts;
00414   else
00415     *lasts = s;
00416   if (*s == 0)                  // We have reached the end
00417     return 0;
00418   size_t l_org = ACE_OS_String::strlen (s);
00419   s = ::strtok (s, tokens);
00420   if (s == 0)
00421     return 0;
00422   size_t l_sub = ACE_OS_String::strlen (s);
00423   if (s + l_sub < *lasts + l_org)
00424     *lasts = s + l_sub + 1;
00425   else
00426     *lasts = s + l_sub;
00427   return s ;
00428 }
00429 #endif /* !ACE_HAS_REENTRANT_FUNCTIONS */
00430 
00431 # if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSTOK)
00432 wchar_t*
00433 ACE_OS_String::strtok_r_emulation (ACE_WCHAR_T *s, const ACE_WCHAR_T *tokens, ACE_WCHAR_T **lasts)
00434 {
00435   if (s == 0)
00436     s = *lasts;
00437   else
00438     *lasts = s;
00439   if (*s == 0)                  // We have reached the end
00440     return 0;
00441   int l_org = ACE_OS_String::strlen (s);
00442   s = ACE_OS_String::strtok (s, tokens);
00443   if (s == 0)
00444     return 0;
00445   int l_sub = ACE_OS_String::strlen (s);
00446   if (s + l_sub < *lasts + l_org)
00447     *lasts = s + l_sub + 1;
00448   else
00449     *lasts = s + l_sub;
00450   return s ;
00451 }
00452 # endif  /* ACE_HAS_WCHAR && ACE_LACKS_WCSTOK */
00453 
00454 #if !defined (ACE_HAS_MEMCHR)
00455 const void *
00456 ACE_OS_String::memchr_emulation (const void *s, int c, size_t len)
00457 {
00458   const unsigned char *t = (const unsigned char *) s;
00459   const unsigned char *e = (const unsigned char *) s + len;
00460 
00461   while (t < e)
00462     if (((int) *t) == c)
00463       return t;
00464     else
00465       t++;
00466 
00467   return 0;
00468 }
00469 #endif /*ACE_HAS_MEMCHR*/
00470 
00471 #if !defined (ACE_HAS_ITOA)
00472 char *
00473 ACE_OS_String::itoa_emulation (int value, char *string, int radix)
00474 {
00475   char *e = string;
00476   char *b = string;
00477 
00478   // Short circuit if 0
00479 
00480   if (value == 0)
00481     {
00482       string[0] = '0';
00483       string[1] = 0;
00484       return string;
00485     }
00486 
00487   // If negative and base 10, print a - and then do the
00488   // number.
00489 
00490   if (value < 0 && radix == 10)
00491     {
00492       string[0] = '-';
00493       ++b;
00494       ++e; // Don't overwrite the negative sign.
00495       value = -value; // Drop negative sign so character selection is correct.
00496     }
00497 
00498   // Convert to base <radix>, but in reverse order
00499 
00500   while (value != 0)
00501     {
00502       int mod = value % radix;
00503       value = value / radix;
00504 
00505       *e++ = (mod < 10) ? '0' + mod : 'a' + mod - 10;
00506     }
00507 
00508   *e-- = 0;
00509 
00510   // Now reverse the string to get the correct result
00511 
00512   while (e > b)
00513     {
00514       char temp = *e;
00515       *e = *b;
00516       *b = temp;
00517       ++b;
00518       --e;
00519     }
00520 
00521   return string;
00522 }
00523 #endif /* !ACE_HAS_ITOA */
00524 
00525 #if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_ITOW)
00526 wchar_t *
00527 ACE_OS_String::itow_emulation (int value, wchar_t *string, int radix)
00528 {
00529   wchar_t *e = string;
00530   wchar_t *b = string;
00531 
00532   // Short circuit if 0
00533 
00534   if (value == 0)
00535     {
00536       string[0] = '0';
00537       string[1] = 0;
00538       return string;
00539     }
00540 
00541   // If negative and base 10, print a - and then do the
00542   // number.
00543 
00544   if (value < 0 && radix == 10)
00545     {
00546       string[0] = '-';
00547       b++;
00548     }
00549 
00550   // Convert to base <radix>, but in reverse order
00551 
00552   while (value != 0)
00553     {
00554       int mod = value % radix;
00555       value = value / radix;
00556 
00557       *e++ = (mod < 10) ? '0' + mod : 'a' + mod - 10;
00558     }
00559 
00560   *e-- = 0;
00561 
00562   // Now reverse the string to get the correct result
00563 
00564   while (e > b)
00565   {
00566     wchar_t temp = *e;
00567     *e = *b;
00568     *b = temp;
00569     ++b;
00570     --e;
00571   }
00572 
00573   return string;
00574 }
00575 #endif /* ACE_HAS_WCHAR && ACE_LACKS_ITOW */
00576 
00577 #if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSCSPN)
00578 size_t
00579 ACE_OS_String::wcscspn_emulation (const wchar_t *s, const wchar_t *reject)
00580 {
00581   const wchar_t *scan;
00582   const wchar_t *rej_scan;
00583   int count = 0;
00584 
00585   for (scan = s; *scan; scan++)
00586     {
00587 
00588       for (rej_scan = reject; *rej_scan; rej_scan++)
00589         if (*scan == *rej_scan)
00590           return count;
00591 
00592       count++;
00593     }
00594 
00595   return count;
00596 }
00597 #endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSCSPN */
00598 
00599 // The following wcs*_emulation methods were created based on BSD code:
00600 /*-
00601  * Copyright (c) 1991, 1993
00602  *      The Regents of the University of California.  All rights reserved.
00603  *
00604  * This code is derived from software contributed to Berkeley by
00605  * James W. Williams of NASA Goddard Space Flight Center.
00606  *
00607  * Redistribution and use in source and binary forms, with or without
00608  * modification, are permitted provided that the following conditions
00609  * are met:
00610  * 1. Redistributions of source code must retain the above copyright
00611  *    notice, this list of conditions and the following disclaimer.
00612  * 2. Redistributions in binary form must reproduce the above copyright
00613  *    notice, this list of conditions and the following disclaimer in the
00614  *    documentation and/or other materials provided with the distribution.
00615  * 3. All advertising materials mentioning features or use of this software
00616  *    must display the following acknowledgement:
00617  *      This product includes software developed by the University of
00618  *      California, Berkeley and its contributors.
00619  * 4. Neither the name of the University nor the names of its contributors
00620  *    may be used to endorse or promote products derived from this software
00621  *    without specific prior written permission.
00622  *
00623  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00624  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00625  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00626  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00627  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00628  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00629  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00630  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00631  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00632  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00633  * SUCH DAMAGE.
00634  */
00635 
00636 
00637 
00638 
00639 #if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSCAT)
00640 wchar_t *
00641 ACE_OS_String::wcscat_emulation (wchar_t *destination,
00642                                  const wchar_t *source)
00643 {
00644   wchar_t *save = destination;
00645 
00646   for (; *destination; ++destination);
00647   while ((*destination++ = *source++));
00648   return save;
00649 }
00650 #endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSCAT */
00651 
00652 #if defined (ACE_LACKS_STRSPN)
00653 size_t
00654 ACE_OS_String::strspn_emulation (const char *string,
00655                                  const char *charset)
00656 {
00657   const char *p = string;
00658   const char *spanp;
00659   wchar_t c, sc;
00660 
00661   // Skip any characters in charset, excluding the terminating \0.
00662 cont:
00663   c = *p++;
00664   for (spanp = charset; (sc = *spanp++) != 0;)
00665     if (sc == c)
00666       goto cont;
00667   return (p - 1 - string);
00668 }
00669 #endif /* ACE_LACKS_STRSPN */
00670 
00671 #if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSSPN)
00672 size_t
00673 ACE_OS_String::wcsspn_emulation (const wchar_t *string,
00674                                  const wchar_t *charset)
00675 {
00676   const wchar_t *p = string;
00677   const wchar_t *spanp;
00678   wchar_t c, sc;
00679 
00680   // Skip any characters in charset, excluding the terminating \0.
00681 cont:
00682   c = *p++;
00683   for (spanp = charset; (sc = *spanp++) != 0;)
00684     if (sc == c)
00685       goto cont;
00686   return (p - 1 - string);
00687 }
00688 #endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSSPN */
00689 
00690 #if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSSTR)
00691 wchar_t *
00692 ACE_OS_String::wcsstr_emulation (const wchar_t *string,
00693                                  const wchar_t *charset)
00694 {
00695   wchar_t c, sc;
00696   size_t len;
00697 
00698   if ((c = *charset++) != 0)
00699     {
00700       len = strlen(charset);
00701       do
00702         {
00703           do
00704             {
00705               if ((sc = *string++) == 0)
00706                 return 0;
00707             } while (sc != c);
00708         } while (strncmp(string, charset, len) != 0);
00709       string--;
00710     }
00711 
00712   return ACE_const_cast (wchar_t *, string);
00713 }
00714 #endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSSTR */
00715 
00716 #if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSLEN)
00717 size_t
00718 ACE_OS_String::wcslen_emulation (const ACE_WCHAR_T *string)
00719 {
00720   const ACE_WCHAR_T *s;
00721 
00722   for (s = string; *s; ++s)
00723     continue;
00724 
00725   return s - string;
00726 }
00727 #endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSLEN */
00728 
00729 #if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSNCPY)
00730 ACE_WCHAR_T *
00731 ACE_OS_String::wcsncpy_emulation (ACE_WCHAR_T *destination,
00732                                   const ACE_WCHAR_T *source,
00733                                   size_t len)
00734 {
00735   if (len != 0)
00736     {
00737       ACE_WCHAR_T *d = destination;
00738       const ACE_WCHAR_T *s = source;
00739 
00740       do
00741         {
00742           if ((*d++ = *s++) == 0)
00743             {
00744               // NUL pad the remaining n-1 bytes
00745               while (--len != 0)
00746                 *d++ = 0;
00747               break;
00748             }
00749         } while (--len != 0);
00750     }
00751 
00752   return destination;
00753 }
00754 #endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSNCPY */
00755 
00756 #if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSCMP)
00757 int
00758 ACE_OS_String::wcscmp_emulation (const ACE_WCHAR_T *string1,
00759                                  const ACE_WCHAR_T *string2)
00760 {
00761   while (*string1 == *string2++)
00762     if (*string1++ == 0)
00763       return (0);
00764   return (*string1 - *--string2);
00765 }
00766 #endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSCMP */
00767 
00768 #if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSCPY)
00769 wchar_t *
00770 ACE_OS_String::wcscpy_emulation (wchar_t *destination,
00771                                  const wchar_t *source)
00772 {
00773   wchar_t *save = destination;
00774 
00775   for (; (*destination = *source); ++source, ++destination);
00776   return save;
00777 }
00778 #endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSCPY */
00779 
00780 #if defined (ACE_LACKS_STRPBRK)
00781 char *
00782 ACE_OS_String::strpbrk_emulation (const char *string,
00783                                   const char *charset)
00784 {
00785   const char *scanp;
00786   int c, sc;
00787 
00788   while ((c = *string++) != 0)
00789     {
00790       for (scanp = charset; (sc = *scanp++) != 0;)
00791         if (sc == c)
00792           return ACE_const_cast (char *, string - 1);
00793     }
00794 
00795   return 0;
00796 }
00797 #endif /* ACE_LACKS_STRPBRK */
00798 
00799 #if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSPBRK)
00800 wchar_t *
00801 ACE_OS_String::wcspbrk_emulation (const wchar_t *string,
00802                                   const wchar_t *charset)
00803 {
00804   const wchar_t *scanp;
00805   int c, sc;
00806 
00807   while ((c = *string++) != 0)
00808     {
00809       for (scanp = charset; (sc = *scanp++) != 0;)
00810         if (sc == c)
00811           return ACE_const_cast (wchar_t *, string - 1);
00812     }
00813 
00814   return 0;
00815 }
00816 #endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSPBRK */
00817 
00818 #if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSNCAT)
00819 ACE_WCHAR_T *
00820 ACE_OS_String::wcsncat_emulation (ACE_WCHAR_T *destination,
00821                                   const ACE_WCHAR_T *source,
00822                                   size_t count)
00823 {
00824   if (count != 0)
00825     {
00826       ACE_WCHAR_T *d = destination;
00827       const ACE_WCHAR_T *s = source;
00828 
00829       while (*d != 0)
00830         d++;
00831 
00832       do
00833         {
00834           if ((*d = *s++) == 0)
00835             break;
00836 
00837           d++;
00838         } while (--count != 0);
00839 
00840       *d = 0;
00841     }
00842 
00843   return destination;
00844 }
00845 #endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSCAT */
00846 
00847 #if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSCHR)
00848 wchar_t *
00849 ACE_OS_String::wcschr_emulation (const wchar_t *string, wint_t c)
00850 {
00851   for (;*string ; ++string)
00852     if (*string == ACE_static_cast (wchar_t, c))
00853       return ACE_const_cast (wchar_t *, string);
00854 
00855   return 0;
00856 }
00857 #endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSCHR */
00858 
00859 #if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSNCMP)
00860 int
00861 ACE_OS_String::wcsncmp_emulation (const ACE_WCHAR_T *s1,
00862                                   const ACE_WCHAR_T *s2,
00863                                   size_t len)
00864 {
00865   if (len == 0)
00866     return 0;
00867 
00868   do
00869     {
00870       if (*s1 != *s2++)
00871         return (*s1 - *--s2);
00872       if (*s1++ == 0)
00873         break;
00874     } while (--len != 0);
00875 
00876   return 0;
00877 }
00878 #endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSNCMP */
00879 
00880 #if defined (ACE_LACKS_STRTOL)
00881 long
00882 ACE_OS_String::strtol_emulation (const char *nptr, char **endptr, int base)
00883 {
00884   register const char *s = nptr;
00885   register unsigned long acc;
00886   register int c;
00887   register unsigned long cutoff;
00888   register int neg = 0, any, cutlim;
00889 
00890   /*
00891    * Skip white space and pick up leading +/- sign if any.
00892    * If base is 0, allow 0x for hex and 0 for octal, else
00893    * assume decimal; if base is already 16, allow 0x.
00894    */
00895   do {
00896     c = *s++;
00897   } while (isspace(c));
00898   if (c == '-') {
00899     neg = 1;
00900     c = *s++;
00901   } else if (c == '+')
00902     c = *s++;
00903   if ((base == 0 || base == 16) &&
00904     c == '0' && (*s == 'x' || *s == 'X')) {
00905     c = s[1];
00906     s += 2;
00907     base = 16;
00908   }
00909   if (base == 0)
00910     base = c == '0' ? 8 : 10;
00911 
00912   /*
00913    * Compute the cutoff value between legal numbers and illegal
00914    * numbers.  That is the largest legal value, divided by the
00915    * base.  An input number that is greater than this value, if
00916    * followed by a legal input character, is too big.  One that
00917    * is equal to this value may be valid or not; the limit
00918    * between valid and invalid numbers is then based on the last
00919    * digit.  For instance, if the range for longs is
00920    * [-2147483648..2147483647] and the input base is 10,
00921    * cutoff will be set to 214748364 and cutlim to either
00922    * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
00923    * a value > 214748364, or equal but the next digit is > 7 (or 8),
00924    * the number is too big, and we will return a range error.
00925    *
00926    * Set any if any `digits' consumed; make it negative to indicate
00927    * overflow.
00928    */
00929   cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
00930   cutlim = cutoff % (unsigned long)base;
00931   cutoff /= (unsigned long)base;
00932   for (acc = 0, any = 0;; c = *s++) {
00933     if (isdigit(c))
00934       c -= '0';
00935     else if (isalpha(c))
00936       c -= isupper(c) ? 'A' - 10 : 'a' - 10;
00937     else
00938       break;
00939     if (c >= base)
00940       break;
00941     if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
00942       any = -1;
00943     else {
00944       any = 1;
00945       acc *= base;
00946       acc += c;
00947     }
00948   }
00949   if (any < 0) {
00950     acc = neg ? LONG_MIN : LONG_MAX;
00951     errno = ERANGE;
00952   } else if (neg)
00953     acc = -acc;
00954   if (endptr != 0)
00955     *endptr = any ? (char *)s - 1 : (char *)nptr;
00956   return (acc);
00957 }
00958 #endif /* ACE_LACKS_STRTOL */
00959 
00960 #if defined (ACE_LACKS_STRTOUL)
00961 unsigned long
00962 ACE_OS_String::strtoul_emulation (const char *nptr,
00963                                   char **endptr,
00964                                   register int base)
00965 {
00966   register const char *s = nptr;
00967   register unsigned long acc;
00968   register int c;
00969   register unsigned long cutoff;
00970   register int neg = 0, any, cutlim;
00971 
00972   /*
00973    * See strtol for comments as to the logic used.
00974    */
00975   do
00976     c = *s++;
00977   while (isspace(c));
00978   if (c == '-')
00979     {
00980       neg = 1;
00981       c = *s++;
00982     }
00983   else if (c == '+')
00984     c = *s++;
00985   if ((base == 0 || base == 16) &&
00986       c == '0' && (*s == 'x' || *s == 'X'))
00987     {
00988       c = s[1];
00989       s += 2;
00990       base = 16;
00991     }
00992   if (base == 0)
00993     base = c == '0' ? 8 : 10;
00994   cutoff = (unsigned long) ULONG_MAX / (unsigned long) base;
00995   cutlim = (unsigned long) ULONG_MAX % (unsigned long) base;
00996 
00997   for (acc = 0, any = 0;; c = *s++)
00998     {
00999       if (isdigit(c))
01000         c -= '0';
01001       else if (isalpha(c))
01002         c -= isupper(c) ? 'A' - 10 : 'a' - 10;
01003       else
01004         break;
01005       if (c >= base)
01006         break;
01007       if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
01008         any = -1;
01009       else
01010         {
01011           any = 1;
01012           acc *= base;
01013           acc += c;
01014         }
01015     }
01016   if (any < 0)
01017     {
01018       acc = ULONG_MAX;
01019       errno = ERANGE;
01020     } else if (neg)
01021     acc = -acc;
01022   if (endptr != 0)
01023     *endptr = any ? (char *) s - 1 : (char *) nptr;
01024   return (acc);
01025 }
01026 #endif /* ACE_LACKS_STRTOUL */
01027 
01028 char *
01029 ACE_OS_String::strsncpy (char *dst, const char *src, size_t maxlen)
01030 {
01031   register char *rdst = dst;
01032   register const char *rsrc = src;
01033   register size_t rmaxlen = maxlen;
01034 
01035   if (rmaxlen > 0)
01036     {
01037       if (rdst!=rsrc)
01038         {
01039           *rdst = '\0';
01040           if (rsrc != 0)
01041             strncat (rdst, rsrc, --rmaxlen);
01042         }
01043       else
01044         {
01045           rdst += (rmaxlen - 1);
01046           *rdst = '\0';
01047         }
01048     }
01049   return dst;
01050 }
01051 
01052 ACE_WCHAR_T *
01053 ACE_OS_String::strsncpy (ACE_WCHAR_T *dst, const ACE_WCHAR_T *src, size_t maxlen)
01054 {
01055   register ACE_WCHAR_T *rdst = dst;
01056   register const ACE_WCHAR_T *rsrc = src;
01057   register size_t rmaxlen = maxlen;
01058 
01059     if (rmaxlen > 0)
01060     {
01061       if (rdst!=rsrc)
01062         {
01063           *rdst = ACE_TEXT_WIDE ('\0');
01064           if (rsrc != 0)
01065             strncat (rdst, rsrc, --rmaxlen);
01066         }
01067       else
01068         {
01069           rdst += (rmaxlen - 1);
01070           *rdst = ACE_TEXT_WIDE ('\0');
01071         }
01072     }
01073   return dst;
01074 }

Generated on Mon Jun 16 11:20:45 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002