String_Base.cpp

Go to the documentation of this file.
00001 // String_Base.cpp,v 4.22 2006/06/04 00:50:30 schmidt Exp
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 /* __ACE_INLINE__ */
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 // Default constructor.
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 // Constructor that actually copies memory.
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 // Constructor that actually copies memory.
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 // Copy constructor.
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 // this method might benefit from a little restructuring.
00122 template <class CHAR> void
00123 ACE_String_Base<CHAR>::set (const CHAR *s, size_t len, int release)
00124 {
00125   // Case 1. Going from memory to more memory
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 // Case 2. No memory allocation is necessary.
00144     {
00145       // Free memory if necessary and figure out future ownership
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       // Populate data.
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) // Note: No guarantee that rep_ is null terminated.
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 // Return substring.
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   // case 1. empty string
00186   if (this->len_ == 0)
00187     return nill;
00188 
00189   // case 2. start pos past our end
00190   if (offset >= this->len_)
00191     return nill;
00192   // No length == empty string.
00193   else if (length == 0)
00194     return nill;
00195   // Get all remaining bytes.
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     // case 1. No memory allocation needed.
00209     if (this->buf_len_ >= this->len_ + slen + 1)
00210     {
00211       // Copy in data from new string.
00212       ACE_OS::memcpy (this->rep_ + this->len_, s, slen * sizeof (CHAR));
00213     }
00214     else // case 2. Memory reallocation is needed
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       // Copy memory from old string into new string.
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   // Only reallocate if we don't have enough space...
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   // This can't use set(), because that would free memory if release=0
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 // Assignment operator (does copy memory).
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 // Assignment operator (does copy memory).
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   // Check for identify.
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       // String retains the original buffer.
00335       if (this->rep_ != &ACE_String_Base<CHAR>::NULL_String_)
00336         this->rep_[0] = 0;
00337     }
00338   else
00339     {
00340       // External buffer: string relinquishes control of it.
00341       this->buf_len_ = 0;
00342       this->rep_ = &ACE_String_Base<CHAR>::NULL_String_;
00343     }
00344 }
00345 
00346 // Get a copy of the underlying representation.
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   // Pick smaller of the two lengths and perform the comparison.
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 // Comparison operator.
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  /* ACE_STRING_BASE_CPP */

Generated on Thu Nov 9 09:42:05 2006 for ACE by doxygen 1.3.6