00001
00002
00003 #include "ace/Lib_Find.h"
00004 #include "ace/Log_Msg.h"
00005 #include "ace/OS_NS_string.h"
00006 #include "ace/OS_NS_errno.h"
00007 #include "ace/OS_NS_stdio.h"
00008 #include "ace/OS_NS_unistd.h"
00009 #include "ace/OS_NS_stdlib.h"
00010 #include "ace/OS_Memory.h"
00011 #include "ace/OS_NS_fcntl.h"
00012
00013 #if defined (ACE_WIN32)
00014 # include "ace/OS_NS_strings.h"
00015 #endif
00016
00017 #if defined (ACE_OPENVMS)
00018 #include "ace/RB_Tree.h"
00019 #include "ace/Thread_Mutex.h"
00020 #include "ace/Singleton.h"
00021
00022 #include "descrip.h"
00023 #include "chfdef.h"
00024 #include "stsdef.h"
00025 #include "libdef.h"
00026
00027 extern "C" int LIB$FIND_IMAGE_SYMBOL(...);
00028
00029 class ACE_LD_Symbol_Registry
00030 {
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 public:
00053
00054 typedef ACE_RB_Tree<const ACE_TCHAR*,
00055 void*,
00056 ACE_Less_Than<const ACE_TCHAR*>,
00057 ACE_Thread_Mutex>
00058 TREE;
00059
00060 void register_symbol (const ACE_TCHAR* symname, void* symaddr);
00061
00062 void* find_symbol (const ACE_TCHAR* symname);
00063
00064 ACE_LD_Symbol_Registry () {}
00065 private:
00066
00067 TREE symbol_registry_;
00068 };
00069
00070 void
00071 ACE_LD_Symbol_Registry::register_symbol (const ACE_TCHAR* symname,
00072 void* symaddr)
00073 {
00074 int result = symbol_registry_.bind (symname, symaddr);
00075 if (result == 1)
00076 {
00077 ACE_DEBUG((LM_INFO, ACE_LIB_TEXT ("ACE_LD_Symbol_Registry:")
00078 ACE_LIB_TEXT (" duplicate symbol %s registered\n"),
00079 ACE_TEXT_ALWAYS_CHAR (symname)));
00080 }
00081 else if (result == -1)
00082 {
00083 ACE_ERROR((LM_ERROR, ACE_LIB_TEXT ("ACE_LD_Symbol_Registry:")
00084 ACE_LIB_TEXT (" failed to register symbol %s\n"),
00085 ACE_TEXT_ALWAYS_CHAR (symname)));
00086 }
00087
00088
00089 }
00090
00091 void*
00092 ACE_LD_Symbol_Registry::find_symbol (const ACE_TCHAR* symname)
00093 {
00094 void* symaddr = 0;
00095 int result = symbol_registry_.find (symname, symaddr);
00096
00097
00098
00099 return (result == 0 ? symaddr : 0);
00100 }
00101
00102
00103 ACE_SINGLETON_DECLARE (ACE_Singleton,
00104 ACE_LD_Symbol_Registry,
00105 ACE_Thread_Mutex)
00106
00107 typedef ACE_Singleton<ACE_LD_Symbol_Registry, ACE_Thread_Mutex>
00108 ACE_LD_SYMBOL_REGISTRY;
00109
00110 #if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION)
00111 template ACE_Singleton<ACE_LD_Symbol_Registry, ACE_Thread_Mutex> *
00112 ACE_Singleton<ACE_LD_Symbol_Registry, ACE_Thread_Mutex>::singleton_;
00113 #endif
00114 #endif
00115
00116 ACE_RCSID(ace, Lib_Find, "Lib_Find.cpp,v 1.33 2006/06/24 14:13:39 shuston Exp")
00117
00118 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00119
00120 int
00121 ACE::ldfind (const ACE_TCHAR* filename,
00122 ACE_TCHAR pathname[],
00123 size_t maxpathnamelen)
00124 {
00125 ACE_TRACE ("ACE::ldfind");
00126 #if defined (ACE_OPENVMS)
00127 if (strlen(filename) >= maxpathnamelen)
00128 {
00129 errno = ENOMEM;
00130 return -1;
00131 }
00132
00133 dsc$descriptor nameDsc;
00134 nameDsc.dsc$b_class = DSC$K_CLASS_S;
00135 nameDsc.dsc$b_dtype = DSC$K_DTYPE_T;
00136 nameDsc.dsc$w_length = strlen(filename);
00137 nameDsc.dsc$a_pointer = (char*)filename;
00138
00139 char symbol[] = "NULL";
00140 dsc$descriptor symbolDsc;
00141 symbolDsc.dsc$b_class = DSC$K_CLASS_S;
00142 symbolDsc.dsc$b_dtype = DSC$K_DTYPE_T;
00143 symbolDsc.dsc$w_length = strlen(symbol);
00144 symbolDsc.dsc$a_pointer = symbol;
00145
00146 int symbolValue;
00147 int result;
00148 try
00149 {
00150 result = LIB$FIND_IMAGE_SYMBOL(&nameDsc, &symbolDsc, &symbolValue, 0, 0);
00151 }
00152 catch (chf$signal_array& sig)
00153 {
00154 result = sig.chf$l_sig_name;
00155 }
00156
00157 int severity = result & STS$M_SEVERITY;
00158 int conditionId = result & STS$M_COND_ID;
00159 if (severity == STS$K_SUCCESS || severity == STS$K_WARNING || severity == STS$K_INFO ||
00160 (severity == STS$K_ERROR && conditionId == (LIB$_KEYNOTFOU & STS$M_COND_ID)))
00161 {
00162 strcpy(pathname, filename);
00163 return 0;
00164 }
00165
00166 if (strlen(filename) + strlen(ACE_DLL_PREFIX) >= maxpathnamelen)
00167 {
00168 errno = ENOMEM;
00169 return -1;
00170 }
00171
00172
00173 strcpy(pathname, ACE_DLL_PREFIX);
00174 strcat(pathname, filename);
00175 nameDsc.dsc$w_length = strlen(pathname);
00176 nameDsc.dsc$a_pointer = pathname;
00177 try
00178 {
00179 result = LIB$FIND_IMAGE_SYMBOL(&nameDsc, &symbolDsc, &symbolValue, 0, 0);
00180 }
00181 catch (chf$signal_array& sig)
00182 {
00183 result = sig.chf$l_sig_name;
00184 }
00185
00186 severity = result & STS$M_SEVERITY;
00187 conditionId = result & STS$M_COND_ID;
00188 if (severity == STS$K_SUCCESS || severity == STS$K_WARNING || severity == STS$K_INFO ||
00189 (severity == STS$K_ERROR && conditionId == (LIB$_KEYNOTFOU & STS$M_COND_ID)))
00190 {
00191 return 0;
00192 }
00193 errno = ENOENT;
00194 return -1;
00195 #endif
00196
00197 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) && \
00198 !defined (ACE_HAS_PHARLAP)
00199 ACE_TCHAR expanded_filename[MAXPATHLEN];
00200 if (ACE_TEXT_ExpandEnvironmentStrings (filename,
00201 expanded_filename,
00202 sizeof expanded_filename
00203 / sizeof (ACE_TCHAR)))
00204 filename = expanded_filename;
00205 #endif
00206
00207 ACE_TCHAR tempcopy[MAXPATHLEN + 1];
00208 ACE_TCHAR searchpathname[MAXPATHLEN + 1];
00209 #if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00210 ACE_TCHAR decorator[] = ACE_LD_DECORATOR_STR;
00211 ACE_TCHAR searchfilename[MAXPATHLEN + sizeof(decorator) / sizeof (ACE_TCHAR)];
00212 #else
00213 ACE_TCHAR searchfilename[MAXPATHLEN + 1];
00214 #endif
00215
00216
00217 if (ACE_OS::strlen (filename) + 1
00218 > (sizeof tempcopy / sizeof (ACE_TCHAR)))
00219 {
00220 errno = ENOMEM;
00221 return -1;
00222 }
00223 else
00224 ACE_OS::strcpy (tempcopy, filename);
00225
00226
00227 ACE_TCHAR *separator_ptr;
00228
00229 #if (ACE_DIRECTORY_SEPARATOR_CHAR != '/')
00230
00231
00232 ACE::strrepl (tempcopy, ACE_DIRECTORY_SEPARATOR_CHAR, '/');
00233 #endif
00234
00235
00236 separator_ptr = ACE_OS::strrchr (tempcopy, '/');
00237
00238
00239 if (separator_ptr == 0)
00240 {
00241 searchpathname[0] = '\0';
00242 ACE_OS::strcpy (searchfilename, tempcopy);
00243 }
00244 else
00245 {
00246 ACE_OS::strcpy (searchfilename, separator_ptr + 1);
00247 separator_ptr[1] = '\0';
00248 ACE_OS::strcpy (searchpathname, tempcopy);
00249 }
00250
00251 int got_suffix = 0;
00252
00253
00254
00255 ACE_TCHAR *s = ACE_OS::strrchr (searchfilename, '.');
00256
00257 const ACE_TCHAR *dll_suffix = ACE_DLL_SUFFIX;
00258
00259 if (s != 0)
00260 {
00261
00262 got_suffix = 1;
00263
00264
00265
00266 #if defined (ACE_WIN32)
00267
00268
00269 if (ACE_OS::strcasecmp (s, dll_suffix) != 0)
00270 #else
00271 if (ACE_OS::strcmp (s, dll_suffix) != 0)
00272 #endif
00273 {
00274 ACE_ERROR ((LM_WARNING,
00275 ACE_LIB_TEXT ("Warning: improper suffix for a ")
00276 ACE_LIB_TEXT ("shared library on this platform: %s\n"),
00277 s));
00278 }
00279 }
00280
00281
00282 if (ACE_OS::strlen (searchfilename)
00283 + ACE_OS::strlen (ACE_DLL_PREFIX)
00284 + got_suffix ? 0 : ACE_OS::strlen (dll_suffix) >= (sizeof searchfilename /
00285 sizeof (ACE_TCHAR)))
00286 {
00287 errno = ENOMEM;
00288 return -1;
00289 }
00290
00291 #if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00292 size_t len_searchfilename = ACE_OS::strlen (searchfilename);
00293 if (! got_suffix)
00294 ACE_OS::strcpy (searchfilename + len_searchfilename,
00295 decorator);
00296
00297 for (int tag = 1; tag >= 0; tag --)
00298 {
00299 if (tag == 0)
00300 searchfilename [len_searchfilename] = 0;
00301
00302 #endif
00303
00304 if (ACE_OS::strlen (searchpathname) > 0)
00305 {
00306 if (ACE_OS::strlen (searchfilename)
00307 + ACE_OS::strlen (searchpathname) >= maxpathnamelen)
00308 {
00309 errno = ENOMEM;
00310 return -1;
00311 }
00312 else
00313 {
00314 #if (ACE_DIRECTORY_SEPARATOR_CHAR != '/')
00315
00316 ACE::strrepl (searchpathname,
00317 '/',
00318 ACE_DIRECTORY_SEPARATOR_CHAR);
00319 #endif
00320
00321
00322 ACE_OS::sprintf (pathname,
00323 ACE_LIB_TEXT ("%s%s%s"),
00324 searchpathname,
00325 searchfilename,
00326 got_suffix ? ACE_LIB_TEXT ("") : dll_suffix);
00327 if (ACE_OS::access (pathname, F_OK) == 0)
00328 return 0;
00329
00330
00331 ACE_OS::sprintf (pathname,
00332 ACE_LIB_TEXT ("%s%s%s%s"),
00333 searchpathname,
00334 ACE_DLL_PREFIX,
00335 searchfilename,
00336 got_suffix ? ACE_LIB_TEXT ("") : dll_suffix);
00337 if (ACE_OS::access (pathname, F_OK) == 0)
00338 return 0;
00339 }
00340 }
00341
00342
00343
00344 else
00345 {
00346 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
00347 ACE_TCHAR *file_component = 0;
00348 DWORD pathlen =
00349 ACE_TEXT_SearchPath (0,
00350 searchfilename,
00351 dll_suffix,
00352 static_cast<DWORD> (maxpathnamelen),
00353 pathname,
00354 &file_component);
00355 if (pathlen >= maxpathnamelen)
00356 {
00357 errno = ENOMEM;
00358 return -1;
00359 }
00360 else if (pathlen > 0)
00361 return 0;
00362
00363
00364
00365 ACE_OS::strcpy (searchfilename, ACE_DLL_PREFIX);
00366 ACE_OS::strcat (searchfilename, tempcopy);
00367 pathlen =
00368 ACE_TEXT_SearchPath (0,
00369 searchfilename,
00370 dll_suffix,
00371 static_cast<DWORD> (maxpathnamelen),
00372 pathname,
00373 &file_component);
00374 if (pathlen >= maxpathnamelen)
00375 {
00376 errno = ENOMEM;
00377 return -1;
00378 }
00379 else if (pathlen > 0)
00380 return 0;
00381 #else
00382 ACE_TCHAR *ld_path;
00383 # if defined ACE_DEFAULT_LD_SEARCH_PATH
00384 ld_path = ACE_DEFAULT_LD_SEARCH_PATH;
00385 # else
00386 # if defined (ACE_WIN32) || !defined (ACE_USES_WCHAR)
00387 ld_path = ACE_OS::getenv (ACE_LD_SEARCH_PATH);
00388 # else
00389
00390
00391 ACE_Ascii_To_Wide wide_ldpath
00392 (ACE_OS::getenv (ACE_TEXT_ALWAYS_CHAR (ACE_LD_SEARCH_PATH)));
00393 ld_path = wide_ldpath.wchar_rep ();
00394 # endif
00395 # endif
00396
00397 #if defined (ACE_HAS_WINCE)
00398 ACE_TCHAR *ld_path_temp = 0;
00399 if (ld_path != 0)
00400 {
00401 ld_path_temp = (ACE_TCHAR *)
00402 ACE_OS::malloc ((ACE_OS::strlen (ld_path) + 2)
00403 * sizeof (ACE_TCHAR));
00404 if (ld_path_temp != 0)
00405 {
00406 ACE_OS::strcpy (ld_path_temp,
00407 ACE_LD_SEARCH_PATH_SEPARATOR_STR);
00408
00409 ACE_OS::strcat (ld_path_temp, ld_path);
00410 ld_path = ld_path_temp;
00411 }
00412 else
00413 {
00414 ACE_OS::free ((void *) ld_path_temp);
00415 ld_path = ld_path_temp = 0;
00416 }
00417 }
00418 #endif
00419
00420 if (ld_path != 0
00421 && (ld_path = ACE_OS::strdup (ld_path)) != 0)
00422 {
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 ACE_TCHAR *nextholder = 0;
00439 const ACE_TCHAR *path_entry =
00440 ACE::strsplit_r (ld_path,
00441 ACE_LD_SEARCH_PATH_SEPARATOR_STR,
00442 nextholder);
00443 int result = 0;
00444
00445 for (;;)
00446 {
00447
00448 if (path_entry == 0)
00449 {
00450 errno = ENOENT;
00451 result = -1;
00452 break;
00453 }
00454 else if (ACE_OS::strlen (path_entry)
00455 + 1
00456 + ACE_OS::strlen (searchfilename)
00457 >= maxpathnamelen)
00458 {
00459 errno = ENOMEM;
00460 result = -1;
00461 break;
00462 }
00463
00464
00465
00466
00467 else if (path_entry[0] == '\0')
00468 path_entry = ACE_LIB_TEXT (".");
00469
00470
00471
00472 ACE_OS::sprintf (pathname,
00473 ACE_LIB_TEXT ("%s%c%s%s"),
00474 path_entry,
00475 ACE_DIRECTORY_SEPARATOR_CHAR,
00476 searchfilename,
00477 got_suffix ? ACE_LIB_TEXT ("") : dll_suffix);
00478 if (ACE_OS::access (pathname, F_OK) == 0)
00479 break;
00480
00481
00482
00483 ACE_OS::sprintf (pathname,
00484 ACE_LIB_TEXT ("%s%c%s%s%s"),
00485 path_entry,
00486 ACE_DIRECTORY_SEPARATOR_CHAR,
00487 ACE_DLL_PREFIX,
00488 searchfilename,
00489 got_suffix ? ACE_LIB_TEXT ("") : dll_suffix);
00490 if (ACE_OS::access (pathname, F_OK) == 0)
00491 break;
00492
00493
00494 path_entry =
00495 ACE::strsplit_r (0,
00496 ACE_LD_SEARCH_PATH_SEPARATOR_STR,
00497 nextholder);
00498 }
00499
00500 #if defined (ACE_HAS_WINCE)
00501 if (ld_path_temp != 0)
00502 ACE_OS::free (ld_path_temp);
00503 #endif
00504 ACE_OS::free ((void *) ld_path);
00505 #if defined (ACE_HAS_WINCE) && defined (ACE_LD_DECORATOR_STR) && \
00506 !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00507 if (result == 0 || tag == 0)
00508 #endif
00509 return result;
00510 }
00511 #endif
00512 }
00513 #if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00514 }
00515 #endif
00516
00517 errno = ENOENT;
00518 return -1;
00519 }
00520
00521 FILE *
00522 ACE::ldopen (const ACE_TCHAR *filename,
00523 const ACE_TCHAR *type)
00524 {
00525 ACE_TRACE ("ACE::ldopen");
00526
00527 ACE_TCHAR buf[MAXPATHLEN + 1];
00528 if (ACE::ldfind (filename,
00529 buf,
00530 sizeof (buf) /sizeof (ACE_TCHAR)) == -1)
00531 return 0;
00532 else
00533 return ACE_OS::fopen (buf, type);
00534 }
00535
00536 ACE_TCHAR *
00537 ACE::ldname (const ACE_TCHAR *entry_point)
00538 {
00539 ACE_TRACE ("ACE::ldname");
00540
00541 #if defined(ACE_NEEDS_DL_UNDERSCORE)
00542 size_t size =
00543 1
00544 + ACE_OS::strlen (entry_point)
00545 + 1;
00546
00547 ACE_TCHAR *new_name;
00548 ACE_NEW_RETURN (new_name,
00549 ACE_TCHAR[size],
00550 0);
00551
00552 ACE_OS::strcpy (new_name, ACE_LIB_TEXT ("_"));
00553 ACE_OS::strcat (new_name, entry_point);
00554
00555 return new_name;
00556 #else
00557 size_t size =
00558 ACE_OS::strlen (entry_point)
00559 + 1;
00560
00561 ACE_TCHAR *new_name;
00562 ACE_NEW_RETURN (new_name,
00563 ACE_TCHAR[size],
00564 0);
00565
00566 ACE_OS::strcpy (new_name, entry_point);
00567 return new_name;
00568 #endif
00569 }
00570
00571 #if defined (ACE_OPENVMS)
00572 void
00573 ACE::ldregister (const ACE_TCHAR *entry_point,
00574 void* entry_addr)
00575 {
00576 ACE_LD_SYMBOL_REGISTRY::instance ()->register_symbol (entry_point,
00577 entry_addr);
00578 }
00579
00580 void *
00581 ACE::ldsymbol (ACE_SHLIB_HANDLE sh, const ACE_TCHAR *entry_point)
00582 {
00583 void* symaddr = ACE_OS::dlsym (sh, entry_point);
00584
00585 if (symaddr == 0)
00586 symaddr = ACE_LD_SYMBOL_REGISTRY::instance ()->find_symbol (entry_point);
00587
00588 return symaddr;
00589 }
00590 #endif
00591
00592 int
00593 ACE::get_temp_dir (ACE_TCHAR *buffer, size_t buffer_len)
00594 {
00595 int result;
00596 #if defined (ACE_WIN32)
00597 result = ACE_TEXT_GetTempPath (static_cast<DWORD> (buffer_len),
00598 buffer);
00599
00600
00601 if (result == 0 && ::GetLastError () != ERROR_SUCCESS
00602 || result > static_cast<int> (buffer_len))
00603 result = -1;
00604
00605 #else
00606
00607
00608
00609
00610
00611
00612
00613 const char *tmpdir = ACE_OS::getenv ("TMPDIR");
00614
00615 if (tmpdir == 0)
00616 tmpdir = "/tmp";
00617
00618 size_t len = ACE_OS::strlen (tmpdir);
00619
00620
00621
00622 if ((len + 2) > buffer_len)
00623 {
00624 result = -1;
00625 }
00626 else
00627 {
00628 ACE_OS::strcpy (buffer, ACE_TEXT_CHAR_TO_TCHAR (tmpdir));
00629
00630
00631
00632 buffer[len] = ACE_LIB_TEXT ('/');
00633 buffer[len + 1] = 0;
00634 result = 0;
00635 }
00636 #endif
00637 return result;
00638 }
00639
00640 ACE_HANDLE
00641 ACE::open_temp_file (const ACE_TCHAR *name, int mode, int perm)
00642 {
00643 #if defined (ACE_WIN32)
00644 ACE_UNUSED_ARG (perm);
00645 ACE_HANDLE handle = ACE_OS::open (name,
00646 mode,
00647 FILE_SHARE_READ
00648 | FILE_SHARE_WRITE
00649 | FILE_SHARE_DELETE);
00650 #else
00651
00652 ACE_HANDLE handle = ACE_OS::open (name, mode, perm);
00653 #endif
00654
00655 if (handle == ACE_INVALID_HANDLE)
00656 return ACE_INVALID_HANDLE;
00657
00658
00659
00660 if (ACE_OS::unlink (name) == -1)
00661 return ACE_INVALID_HANDLE;
00662 else
00663
00664 return handle;
00665 }
00666
00667 size_t
00668 ACE::strrepl (char *s, char search, char replace)
00669 {
00670 ACE_TRACE ("ACE::strrepl");
00671
00672 size_t replaced = 0;
00673
00674 for (size_t i = 0; s[i] != '\0'; i++)
00675 if (s[i] == search)
00676 {
00677 s[i] = replace;
00678 replaced++;
00679 }
00680
00681 return replaced;
00682 }
00683
00684
00685
00686
00687
00688 char *
00689 ACE::strsplit_r (char *str,
00690 const char *token,
00691 char *&next_start)
00692 {
00693 char *result = 0;
00694
00695 if (str != 0)
00696 next_start = str;
00697
00698 if (next_start != 0)
00699 {
00700 char *tok_loc = ACE_OS::strstr (next_start, token);
00701
00702 if (tok_loc != 0)
00703 {
00704
00705 result = next_start;
00706
00707
00708 *tok_loc = '\0';
00709 next_start = tok_loc + ACE_OS::strlen (token);
00710 }
00711 else
00712 {
00713 result = next_start;
00714 next_start = (char *) 0;
00715 }
00716 }
00717
00718 return result;
00719 }
00720
00721 #if defined (ACE_HAS_WCHAR)
00722 wchar_t *
00723 ACE::strsplit_r (wchar_t *str,
00724 const wchar_t *token,
00725 wchar_t *&next_start)
00726 {
00727 wchar_t *result = 0;
00728
00729 if (str != 0)
00730 next_start = str;
00731
00732 if (next_start != 0)
00733 {
00734 wchar_t *tok_loc = ACE_OS::strstr (next_start, token);
00735
00736 if (tok_loc != 0)
00737 {
00738
00739 result = next_start;
00740
00741
00742 *tok_loc = '\0';
00743 next_start = tok_loc + ACE_OS::strlen (token);
00744 }
00745 else
00746 {
00747 result = next_start;
00748 next_start = (wchar_t *) 0;
00749 }
00750 }
00751
00752 return result;
00753 }
00754
00755 size_t
00756 ACE::strrepl (wchar_t *s, wchar_t search, wchar_t replace)
00757 {
00758 ACE_TRACE ("ACE::strrepl");
00759
00760 size_t replaced = 0;
00761
00762 for (size_t i = 0; s[i] != '\0'; i++)
00763 if (s[i] == search)
00764 {
00765 s[i] = replace;
00766 replaced++;
00767 }
00768
00769 return replaced;
00770 }
00771 #endif
00772
00773 ACE_END_VERSIONED_NAMESPACE_DECL