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