00001
00002
00003 #ifndef ACE_STRING_BASE_CPP
00004 #define ACE_STRING_BASE_CPP
00005
00006 #include "ace/ACE.h"
00007 #include "ace/Malloc_Base.h"
00008 #include "ace/String_Base.h"
00009 #include "ace/Auto_Ptr.h"
00010 #include "ace/OS_NS_string.h"
00011
00012 #include <algorithm>
00013
00014 #if !defined (__ACE_INLINE__)
00015 #include "ace/String_Base.inl"
00016 #endif
00017
00018 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00019
00020 ACE_ALLOC_HOOK_DEFINE(ACE_String_Base)
00021
00022 template <class CHAR>
00023 CHAR ACE_String_Base<CHAR>::NULL_String_ = 0;
00024
00025
00026
00027 template <class CHAR>
00028 ACE_String_Base<CHAR>::ACE_String_Base (ACE_Allocator *the_allocator)
00029 : allocator_ (the_allocator ? the_allocator : ACE_Allocator::instance ()),
00030 len_ (0),
00031 buf_len_ (0),
00032 rep_ (&ACE_String_Base<CHAR>::NULL_String_),
00033 release_ (false)
00034 {
00035 ACE_TRACE ("ACE_String_Base<CHAR>::ACE_String_Base");
00036 }
00037
00038
00039
00040 template <class CHAR>
00041 ACE_String_Base<CHAR>::ACE_String_Base (const CHAR *s,
00042 ACE_Allocator *the_allocator,
00043 bool release)
00044 : allocator_ (the_allocator ? the_allocator : ACE_Allocator::instance ()),
00045 len_ (0),
00046 buf_len_ (0),
00047 rep_ (0),
00048 release_ (false)
00049 {
00050 ACE_TRACE ("ACE_String_Base<CHAR>::ACE_String_Base");
00051 this->set (s, release);
00052 }
00053
00054 template <class CHAR>
00055 ACE_String_Base<CHAR>::ACE_String_Base (CHAR c,
00056 ACE_Allocator *the_allocator)
00057 : allocator_ (the_allocator ? the_allocator : ACE_Allocator::instance ()),
00058 len_ (0),
00059 buf_len_ (0),
00060 rep_ (0),
00061 release_ (false)
00062 {
00063 ACE_TRACE ("ACE_String_Base<CHAR>::ACE_String_Base");
00064
00065 this->set (&c, 1, true);
00066 }
00067
00068
00069
00070 template <class CHAR>
00071 ACE_String_Base<CHAR>::ACE_String_Base (
00072 const CHAR *s,
00073 typename ACE_String_Base<CHAR>::size_type len,
00074 ACE_Allocator *the_allocator,
00075 bool release)
00076 : allocator_ (the_allocator ? the_allocator : ACE_Allocator::instance ()),
00077 len_ (0),
00078 buf_len_ (0),
00079 rep_ (0),
00080 release_ (false)
00081 {
00082 ACE_TRACE ("ACE_String_Base<CHAR>::ACE_String_Base");
00083
00084 this->set (s, len, release);
00085 }
00086
00087
00088
00089 template <class CHAR>
00090 ACE_String_Base<CHAR>::ACE_String_Base (const ACE_String_Base<CHAR> &s)
00091 : allocator_ (s.allocator_ ? s.allocator_ : ACE_Allocator::instance ()),
00092 len_ (0),
00093 buf_len_ (0),
00094 rep_ (0),
00095 release_ (false)
00096 {
00097 ACE_TRACE ("ACE_String_Base<CHAR>::ACE_String_Base");
00098
00099 this->set (s.rep_, s.len_, true);
00100 }
00101
00102 template <class CHAR>
00103 ACE_String_Base<CHAR>::ACE_String_Base (
00104 typename ACE_String_Base<CHAR>::size_type len,
00105 CHAR c,
00106 ACE_Allocator *the_allocator)
00107 : allocator_ (the_allocator ? the_allocator : ACE_Allocator::instance ()),
00108 len_ (0),
00109 buf_len_ (0),
00110 rep_ (0),
00111 release_ (false)
00112 {
00113 ACE_TRACE ("ACE_String_Base<CHAR>::ACE_String_Base");
00114
00115 this->resize (len, c);
00116 }
00117
00118 template <class CHAR>
00119 ACE_String_Base<CHAR>::~ACE_String_Base (void)
00120 {
00121 ACE_TRACE ("ACE_String_Base<CHAR>::~ACE_String_Base");
00122
00123 if (this->buf_len_ != 0 && this->release_)
00124 this->allocator_->free (this->rep_);
00125 }
00126
00127
00128 template <class CHAR> void
00129 ACE_String_Base<CHAR>::set (const CHAR *s,
00130 typename ACE_String_Base<CHAR>::size_type len,
00131 bool release)
00132 {
00133
00134 size_type new_buf_len = len + 1;
00135 if (s != 0 && len != 0 && release && this->buf_len_ < new_buf_len)
00136 {
00137 CHAR *temp;
00138 ACE_ALLOCATOR (temp,
00139 (CHAR *) this->allocator_->malloc (new_buf_len * sizeof (CHAR)));
00140
00141 if (this->buf_len_ != 0 && this->release_)
00142 this->allocator_->free (this->rep_);
00143
00144 this->rep_ = temp;
00145 this->buf_len_ = new_buf_len;
00146 this->release_ = true;
00147 this->len_ = len;
00148 ACE_OS::memcpy (this->rep_, s, len * sizeof (CHAR));
00149 this->rep_[len] = 0;
00150 }
00151 else
00152 {
00153
00154 if (!release || s == 0 || len == 0)
00155 {
00156 if (this->buf_len_ != 0 && this->release_)
00157 {
00158 this->allocator_->free (this->rep_);
00159 this->release_ = false;
00160 }
00161 }
00162
00163 if (s == 0 || len == 0)
00164 {
00165 this->buf_len_ = 0;
00166 this->len_ = 0;
00167 this->rep_ = &ACE_String_Base<CHAR>::NULL_String_;
00168 this->release_ = false;
00169 }
00170 else if (!release)
00171 {
00172 this->buf_len_ = len;
00173 this->len_ = len;
00174 this->rep_ = const_cast <CHAR *> (s);
00175 this->release_ = false;
00176 }
00177 else
00178 {
00179 ACE_OS::memcpy (this->rep_, s, len * sizeof (CHAR));
00180 this->rep_[len] = 0;
00181 this->len_ = len;
00182 }
00183 }
00184 }
00185
00186
00187 template <class CHAR> ACE_String_Base<CHAR>
00188 ACE_String_Base<CHAR>::substring (
00189 typename ACE_String_Base<CHAR>::size_type offset,
00190 typename ACE_String_Base<CHAR>::size_type length) const
00191 {
00192 ACE_String_Base<CHAR> nill;
00193 size_type count = length;
00194
00195
00196 if (this->len_ == 0)
00197 return nill;
00198
00199
00200 if (offset >= this->len_)
00201 return nill;
00202
00203 else if (length == 0)
00204 return nill;
00205
00206 else if (length == npos || count > (this->len_ - offset))
00207 count = this->len_ - offset;
00208
00209 return ACE_String_Base<CHAR> (&this->rep_[offset], count, this->allocator_);
00210 }
00211
00212 template <class CHAR> ACE_String_Base<CHAR> &
00213 ACE_String_Base<CHAR>::append (const CHAR* s,
00214 typename ACE_String_Base<CHAR>::size_type slen)
00215 {
00216 ACE_TRACE ("ACE_String_Base<CHAR>::append(const CHAR*, size_type)");
00217 if (slen > 0 && slen != npos)
00218 {
00219
00220 if (this->buf_len_ >= this->len_ + slen + 1)
00221 {
00222
00223 ACE_OS::memcpy (this->rep_ + this->len_, s, slen * sizeof (CHAR));
00224 }
00225 else
00226 {
00227 const size_type new_buf_len =
00228 ace_max(this->len_ + slen + 1, this->buf_len_ + this->buf_len_ / 2);
00229
00230 CHAR *t = 0;
00231
00232 ACE_ALLOCATOR_RETURN (t,
00233 (CHAR *) this->allocator_->malloc (new_buf_len * sizeof (CHAR)), *this);
00234
00235
00236 ACE_OS::memcpy (t, this->rep_, this->len_ * sizeof (CHAR));
00237
00238 ACE_OS::memcpy (t + this->len_, s, slen * sizeof (CHAR));
00239
00240 if (this->buf_len_ != 0 && this->release_)
00241 this->allocator_->free (this->rep_);
00242
00243 this->release_ = true;
00244 this->rep_ = t;
00245 this->buf_len_ = new_buf_len;
00246 }
00247
00248 this->len_ += slen;
00249 this->rep_[this->len_] = 0;
00250 }
00251
00252 return *this;
00253 }
00254
00255 template <class CHAR> u_long
00256 ACE_String_Base<CHAR>::hash (void) const
00257 {
00258 return
00259 ACE::hash_pjw (reinterpret_cast<char *> (
00260 const_cast<CHAR *> (this->rep_)),
00261 this->len_ * sizeof (CHAR));
00262 }
00263
00264 template <class CHAR> void
00265 ACE_String_Base<CHAR>::resize (typename ACE_String_Base<CHAR>::size_type len,
00266 CHAR c)
00267 {
00268 ACE_TRACE ("ACE_String_Base<CHAR>::resize");
00269
00270 fast_resize(len);
00271 ACE_OS::memset (this->rep_, c, this->buf_len_ * sizeof (CHAR));
00272 }
00273
00274 template <class CHAR> void
00275 ACE_String_Base<CHAR>::fast_resize (size_t len)
00276 {
00277 ACE_TRACE ("ACE_String_Base<CHAR>::fast_resize");
00278
00279
00280 if (this->buf_len_ <= len)
00281 {
00282 if (this->buf_len_ != 0 && this->release_)
00283 this->allocator_->free (this->rep_);
00284
00285 this->rep_ = static_cast<CHAR*>
00286 (this->allocator_->malloc ((len + 1) * sizeof (CHAR)));
00287 this->buf_len_ = len + 1;
00288 this->release_ = true;
00289 }
00290 this->len_ = 0;
00291 if (len > 0)
00292 this->rep_[0] = 0;
00293 }
00294
00295 template <class CHAR> void
00296 ACE_String_Base<CHAR>::clear (bool release)
00297 {
00298
00299 if (release)
00300 {
00301 if (this->buf_len_ != 0 && this->release_)
00302 this->allocator_->free (this->rep_);
00303
00304 this->rep_ = &ACE_String_Base<CHAR>::NULL_String_;
00305 this->len_ = 0;
00306 this->buf_len_ = 0;
00307 this->release_ = false;
00308 }
00309 else
00310 {
00311 this->fast_clear ();
00312 }
00313 }
00314
00315
00316 template <class CHAR> ACE_String_Base<CHAR> &
00317 ACE_String_Base<CHAR>::operator= (const CHAR *s)
00318 {
00319 ACE_TRACE ("ACE_String_Base<CHAR>::operator=");
00320 if (s != 0)
00321 this->set (s, true);
00322 return *this;
00323 }
00324
00325
00326 template <class CHAR> ACE_String_Base<CHAR> &
00327 ACE_String_Base<CHAR>::operator= (const ACE_String_Base<CHAR> &s)
00328 {
00329 ACE_TRACE ("ACE_String_Base<CHAR>::operator=");
00330
00331
00332 if (this != &s)
00333 {
00334 this->set (s.rep_, s.len_, true);
00335 }
00336
00337 return *this;
00338 }
00339
00340 template <class CHAR> void
00341 ACE_String_Base<CHAR>::set (const CHAR *s, bool release)
00342 {
00343 size_t length = 0;
00344 if (s != 0)
00345 length = ACE_OS::strlen (s);
00346
00347 this->set (s, length, release);
00348 }
00349
00350 template <class CHAR> void
00351 ACE_String_Base<CHAR>::fast_clear (void)
00352 {
00353 this->len_ = 0;
00354 if (this->release_)
00355 {
00356
00357 if (this->rep_ != &ACE_String_Base<CHAR>::NULL_String_)
00358 this->rep_[0] = 0;
00359 }
00360 else
00361 {
00362
00363 this->buf_len_ = 0;
00364 this->rep_ = &ACE_String_Base<CHAR>::NULL_String_;
00365 }
00366 }
00367
00368
00369
00370 template <class CHAR> CHAR *
00371 ACE_String_Base<CHAR>::rep (void) const
00372 {
00373 ACE_TRACE ("ACE_String_Base<CHAR>::rep");
00374
00375 CHAR *new_string;
00376 ACE_NEW_RETURN (new_string, CHAR[this->len_ + 1], 0);
00377 ACE_OS::strsncpy (new_string, this->rep_, this->len_+1);
00378
00379 return new_string;
00380 }
00381
00382 template <class CHAR> int
00383 ACE_String_Base<CHAR>::compare (const ACE_String_Base<CHAR> &s) const
00384 {
00385 ACE_TRACE ("ACE_String_Base<CHAR>::compare");
00386
00387 if (this->rep_ == s.rep_)
00388 return 0;
00389
00390
00391 size_type smaller_length = ace_min (this->len_, s.len_);
00392
00393 int result = ACE_OS::memcmp (this->rep_,
00394 s.rep_,
00395 smaller_length * sizeof (CHAR));
00396
00397 if (!result)
00398 result = static_cast<int> (this->len_ - s.len_);
00399 return result;
00400 }
00401
00402
00403
00404 template <class CHAR> bool
00405 ACE_String_Base<CHAR>::operator== (const ACE_String_Base<CHAR> &s) const
00406 {
00407 return this->len_ == s.len_ &&
00408 ACE_OS::memcmp (this->rep_,
00409 s.rep_,
00410 this->len_ * sizeof (CHAR)) == 0;
00411 }
00412
00413 template <class CHAR> bool
00414 ACE_String_Base<CHAR>::operator== (const CHAR *s) const
00415 {
00416 size_t len = ACE_OS::strlen (s);
00417 return this->len_ == len &&
00418 ACE_OS::memcmp (this->rep_,
00419 s,
00420 len * sizeof (CHAR)) == 0;
00421 }
00422
00423 template <class CHAR> typename ACE_String_Base<CHAR>::size_type
00424 ACE_String_Base<CHAR>::find (
00425 const CHAR *s,
00426 typename ACE_String_Base<CHAR>::size_type pos) const
00427 {
00428 CHAR *substr = this->rep_ + pos;
00429 size_t len = ACE_OS::strlen (s);
00430 CHAR *pointer = ACE_OS::strnstr (substr, s, len);
00431 if (pointer == 0)
00432 return ACE_String_Base<CHAR>::npos;
00433 else
00434 return pointer - this->rep_;
00435 }
00436
00437 template <class CHAR> typename ACE_String_Base<CHAR>::size_type
00438 ACE_String_Base<CHAR>::find (
00439 CHAR c,
00440 typename ACE_String_Base<CHAR>::size_type pos) const
00441 {
00442 CHAR *substr = this->rep_ + pos;
00443 CHAR *pointer = ACE_OS::strnchr (substr, c, this->len_ - pos);
00444 if (pointer == 0)
00445 return ACE_String_Base<CHAR>::npos;
00446 else
00447 return pointer - this->rep_;
00448 }
00449
00450 template <class CHAR> typename ACE_String_Base<CHAR>::size_type
00451 ACE_String_Base<CHAR>::rfind (
00452 CHAR c,
00453 typename ACE_String_Base<CHAR>::size_type pos) const
00454 {
00455 if (pos == npos || pos > this->len_)
00456 pos = this->len_;
00457
00458
00459
00460 for (size_type i = pos; i-- != 0; )
00461 if (this->rep_[i] == c)
00462 return i;
00463
00464 return ACE_String_Base<CHAR>::npos;
00465 }
00466
00467 template <class CHAR> void
00468 ACE_String_Base<CHAR>::swap (ACE_String_Base<CHAR> & str)
00469 {
00470 std::swap (this->allocator_ , str.allocator_);
00471 std::swap (this->len_ , str.len_);
00472 std::swap (this->buf_len_ , str.buf_len_);
00473 std::swap (this->rep_ , str.rep_);
00474 std::swap (this->release_ , str.release_);
00475 }
00476
00477
00478
00479 template <class CHAR> ACE_String_Base<CHAR>
00480 operator+ (const ACE_String_Base<CHAR> &s, const ACE_String_Base<CHAR> &t)
00481 {
00482 ACE_String_Base<CHAR> temp (s.length () + t.length ());
00483 temp += s;
00484 temp += t;
00485 return temp;
00486 }
00487
00488 template <class CHAR> ACE_String_Base<CHAR>
00489 operator+ (const CHAR *s, const ACE_String_Base<CHAR> &t)
00490 {
00491 size_t slen = 0;
00492 if (s != 0)
00493 slen = ACE_OS::strlen (s);
00494 ACE_String_Base<CHAR> temp (slen + t.length ());
00495 if (slen > 0)
00496 temp.append (s, slen);
00497 temp += t;
00498 return temp;
00499 }
00500
00501 template <class CHAR> ACE_String_Base<CHAR>
00502 operator+ (const ACE_String_Base<CHAR> &s, const CHAR *t)
00503 {
00504 size_t tlen = 0;
00505 if (t != 0)
00506 tlen = ACE_OS::strlen (t);
00507 ACE_String_Base<CHAR> temp (s.length () + tlen);
00508 temp += s;
00509 if (tlen > 0)
00510 temp.append (t, tlen);
00511 return temp;
00512 }
00513
00514 template <class CHAR> ACE_String_Base<CHAR>
00515 operator + (const ACE_String_Base<CHAR> &t,
00516 const CHAR c)
00517 {
00518 ACE_String_Base<CHAR> temp (t.length () + 1);
00519 temp += t;
00520 temp += c;
00521 return temp;
00522 }
00523
00524 template <class CHAR> ACE_String_Base<CHAR>
00525 operator + (const CHAR c,
00526 const ACE_String_Base<CHAR> &t)
00527 {
00528 ACE_String_Base<CHAR> temp (t.length () + 1);
00529 temp += c;
00530 temp += t;
00531 return temp;
00532 }
00533
00534 template <class CHAR>
00535 ACE_String_Base<CHAR> &
00536 ACE_String_Base<CHAR>::operator+= (const CHAR* s)
00537 {
00538 size_t slen = 0;
00539 if (s != 0)
00540 slen = ACE_OS::strlen (s);
00541 return this->append (s, slen);
00542 }
00543
00544 template <class CHAR>
00545 ACE_String_Base<CHAR> &
00546 ACE_String_Base<CHAR>::operator+= (const ACE_String_Base<CHAR> &s)
00547 {
00548 ACE_TRACE ("ACE_String_Base<CHAR>::operator+=(const ACE_String_Base<CHAR> &)");
00549 return this->append (s.rep_, s.len_);
00550 }
00551
00552 template <class CHAR>
00553 ACE_String_Base<CHAR> &
00554 ACE_String_Base<CHAR>::operator+= (const CHAR c)
00555 {
00556 ACE_TRACE ("ACE_String_Base<CHAR>::operator+=(const CHAR)");
00557 const size_type slen = 1;
00558 return this->append (&c, slen);
00559 }
00560
00561 ACE_END_VERSIONED_NAMESPACE_DECL
00562
00563 #endif