SString.cpp

Go to the documentation of this file.
00001 // SString.cpp,v 4.94 2006/04/19 19:13:09 jwillemsen Exp
00002 
00003 #include "ace/Malloc_T.h"
00004 #include "ace/OS_Memory.h"
00005 #if !defined (ACE_HAS_WINCE)
00006 //# include "ace/Service_Config.h"
00007 #endif /* !ACE_HAS_WINCE */
00008 #include "ace/SString.h"
00009 #include "ace/Auto_Ptr.h"
00010 #include "ace/OS_NS_string.h"
00011 
00012 #if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
00013 // FUZZ: disable check_for_streams_include
00014 # include "ace/streams.h"
00015 #endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
00016 
00017 #if !defined (__ACE_INLINE__)
00018 #include "ace/SString.inl"
00019 #endif /* __ACE_INLINE__ */
00020 
00021 ACE_RCSID (ace,
00022            SString,
00023            "SString.cpp,v 4.61 2001/03/04 00:55:30 brunsch Exp")
00024 
00025 
00026 // ************************************************************
00027 
00028 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00029 
00030 #if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
00031 ACE_OSTREAM_TYPE &
00032 operator<< (ACE_OSTREAM_TYPE &os, const ACE_CString &cs)
00033 {
00034   if (cs.fast_rep () != 0)
00035     os << cs.fast_rep ();
00036   return os;
00037 }
00038 
00039 ACE_OSTREAM_TYPE &
00040 operator<< (ACE_OSTREAM_TYPE &os, const ACE_WString &ws)
00041 {
00042   // @@ Need to figure out how to print the "wide" string
00043   //    on platforms that don't support "wide" strings.
00044 #if defined (ACE_HAS_WCHAR)
00045   os << ACE_Wide_To_Ascii (ws.fast_rep ()).char_rep ();
00046 #else
00047   ACE_UNUSED_ARG (ws);
00048   os << "(*non-printable string*)";
00049 #endif
00050   return os;
00051 }
00052 
00053 ACE_OSTREAM_TYPE &
00054 operator<< (ACE_OSTREAM_TYPE &os, const ACE_SString &ss)
00055 {
00056   if (ss.fast_rep () != 0)
00057     os << ss.fast_rep ();
00058   return os;
00059 }
00060 #endif /* !ACE_LACKS_IOSTREAM_TOTALLY */
00061 
00062 // *****************************************************************
00063 
00064 char *
00065 ACE_NS_WString::char_rep (void) const
00066 {
00067   ACE_TRACE ("ACE_NS_WString::char_rep");
00068   if (this->len_ <= 0)
00069     return 0;
00070   else
00071     {
00072       char *t = 0;
00073 
00074       ACE_NEW_RETURN (t,
00075                       char[this->len_ + 1],
00076                       0);
00077 
00078       for (size_t i = 0; i < this->len_; i++)
00079         // Note that this cast may lose data if wide chars are
00080         // actually used!
00081         t[i] = char (this->rep_[i]);
00082 
00083       t[this->len_] = '\0';
00084       return t;
00085     }
00086 }
00087 
00088 ACE_USHORT16 *
00089 ACE_NS_WString::ushort_rep (void) const
00090 {
00091   ACE_TRACE ("ACE_NS_WString::ushort_rep");
00092   if (this->len_ <= 0)
00093     return 0;
00094   else
00095     {
00096       ACE_USHORT16 *t = 0;
00097 
00098       ACE_NEW_RETURN (t,
00099                       ACE_USHORT16[this->len_ + 1],
00100                       0);
00101 
00102       for (size_t i = 0; i < this->len_; i++)
00103         // Note that this cast may lose data if wide chars are
00104         // actually used!
00105         t[i] = (ACE_USHORT16)this->rep_[i];
00106 
00107       t[this->len_] = 0;
00108       return t;
00109     }
00110 }
00111 
00112 ACE_NS_WString::ACE_NS_WString (const char *s,
00113                                 ACE_Allocator *alloc)
00114   : ACE_WString (alloc)
00115 {
00116   if (s == 0)
00117     return;
00118 
00119   this->len_ = this->buf_len_ = ACE_OS::strlen (s);
00120 
00121   if (this->buf_len_ == 0)
00122     return;
00123 
00124   ACE_ALLOCATOR (this->rep_,
00125                  (ACE_WSTRING_TYPE *)
00126                  this->allocator_->malloc ((this->buf_len_ + 1) *
00127                                            sizeof (ACE_WSTRING_TYPE)));
00128   this->release_ = 1;
00129   for (size_t i = 0; i <= this->buf_len_; i++)
00130     this->rep_[i] = s[i];
00131 }
00132 
00133 #if defined (ACE_WSTRING_HAS_USHORT_SUPPORT)
00134 ACE_NS_WString::ACE_NS_WString (const ACE_USHORT16 *s,
00135                                 size_t len,
00136                                 ACE_Allocator *alloc)
00137   : ACE_WString (alloc)
00138 {
00139   if (s == 0)
00140     return;
00141 
00142   this->buf_len_ = len;
00143 
00144   if (this->buf_len_ == 0)
00145     return;
00146 
00147   ACE_ALLOCATOR (this->rep_,
00148                  (ACE_WSTRING_TYPE *)
00149                  this->allocator_->malloc ((this->buf_len_) *
00150                                            sizeof (ACE_WSTRING_TYPE)));
00151   this->release_ = 1;
00152   for (size_t i = 0; i < this->buf_len_; i++)
00153     this->rep_[i] = s[i];
00154 }
00155 #endif /* ACE_WSTRING_HAS_USHORT_SUPPORT */
00156 
00157 // *****************************************************************
00158 
00159 const int ACE_SString::npos = -1;
00160 
00161 ACE_ALLOC_HOOK_DEFINE(ACE_SString)
00162 
00163 void
00164 ACE_SString::dump (void) const
00165 {
00166 #if defined (ACE_HAS_DUMP)
00167   ACE_TRACE ("ACE_SString::dump");
00168 #endif /* ACE_HAS_DUMP */
00169 }
00170 
00171 // Copy constructor.
00172 
00173 ACE_SString::ACE_SString (const ACE_SString &s)
00174   : allocator_ (s.allocator_),
00175     len_ (s.len_)
00176 {
00177   ACE_TRACE ("ACE_SString::ACE_SString");
00178 
00179   if (this->allocator_ == 0)
00180     this->allocator_ = ACE_Allocator::instance ();
00181 
00182   this->rep_ = (char *) this->allocator_->malloc (s.len_ + 1);
00183   ACE_OS::memcpy ((void *) this->rep_,
00184                   (const void *) s.rep_,
00185                   this->len_);
00186   this->rep_[this->len_] = '\0';
00187 }
00188 
00189 // Default constructor.
00190 
00191 ACE_SString::ACE_SString (ACE_Allocator *alloc)
00192   : allocator_ (alloc),
00193     len_ (0),
00194     rep_ (0)
00195 
00196 {
00197   ACE_TRACE ("ACE_SString::ACE_SString");
00198 
00199   if (this->allocator_ == 0)
00200     this->allocator_ = ACE_Allocator::instance ();
00201 
00202   this->len_ = 0;
00203   this->rep_ = (char *) this->allocator_->malloc (this->len_ + 1);
00204   this->rep_[this->len_] = '\0';
00205 }
00206 
00207 // Set the underlying pointer (does not copy memory).
00208 
00209 void
00210 ACE_SString::rep (char *s)
00211 {
00212   ACE_TRACE ("ACE_SString::rep");
00213 
00214   this->rep_ = s;
00215 
00216   if (s == 0)
00217     this->len_ = 0;
00218   else
00219     this->len_ = ACE_OS::strlen (s);
00220 }
00221 
00222 // Constructor that actually copies memory.
00223 
00224 ACE_SString::ACE_SString (const char *s,
00225                           ACE_Allocator *alloc)
00226   : allocator_ (alloc)
00227 {
00228   ACE_TRACE ("ACE_SString::ACE_SString");
00229 
00230   if (this->allocator_ == 0)
00231     this->allocator_ = ACE_Allocator::instance ();
00232 
00233   if (s == 0)
00234     {
00235       this->len_ = 0;
00236       this->rep_ = (char *) this->allocator_->malloc (this->len_ + 1);
00237       this->rep_[this->len_] = '\0';
00238     }
00239   else
00240     {
00241       this->len_ = ACE_OS::strlen (s);
00242       this->rep_ = (char *) this->allocator_->malloc (this->len_ + 1);
00243       ACE_OS::strcpy (this->rep_, s);
00244     }
00245 }
00246 
00247 ACE_SString::ACE_SString (char c,
00248                           ACE_Allocator *alloc)
00249   : allocator_ (alloc)
00250 {
00251   ACE_TRACE ("ACE_SString::ACE_SString");
00252 
00253   if (this->allocator_ == 0)
00254     this->allocator_ = ACE_Allocator::instance ();
00255 
00256   this->len_ = 1;
00257   this->rep_ = (char *) this->allocator_->malloc (this->len_ + 1);
00258   this->rep_[0] = c;
00259   this->rep_[this->len_] = '\0';
00260 }
00261 
00262 // Constructor that actually copies memory.
00263 
00264 ACE_SString::ACE_SString (const char *s,
00265                           size_t len,
00266                           ACE_Allocator *alloc)
00267   : allocator_ (alloc)
00268 {
00269   ACE_TRACE ("ACE_SString::ACE_SString");
00270 
00271   if (this->allocator_ == 0)
00272     this->allocator_ = ACE_Allocator::instance ();
00273 
00274   if (s == 0)
00275     {
00276       this->len_ = 0;
00277       this->rep_ = (char *) this->allocator_->malloc (this->len_ + 1);
00278       this->rep_[this->len_] = '\0';
00279     }
00280   else
00281     {
00282       this->len_ = len;
00283       this->rep_ = (char *) this->allocator_->malloc (this->len_ + 1);
00284       ACE_OS::memcpy (this->rep_, s, len);
00285       this->rep_[len] = '\0'; // Make sure to NUL terminate this!
00286     }
00287 }
00288 
00289 // Assignment operator (does copy memory).
00290 
00291 ACE_SString &
00292 ACE_SString::operator= (const ACE_SString &s)
00293 {
00294   ACE_TRACE ("ACE_SString::operator=");
00295   // Check for identify.
00296 
00297   if (this != &s)
00298     {
00299       // Only reallocate if we don't have enough space...
00300       if (this->len_ < s.len_)
00301         {
00302           this->allocator_->free (this->rep_);
00303           this->rep_ = (char *) this->allocator_->malloc (s.len_ + 1);
00304         }
00305       this->len_ = s.len_;
00306       ACE_OS::strcpy (this->rep_, s.rep_);
00307     }
00308 
00309   return *this;
00310 }
00311 
00312 // Return substring.
00313 ACE_SString
00314 ACE_SString::substring (size_t offset,
00315                         ssize_t length) const
00316 {
00317   ACE_SString nill;
00318   size_t count = length;
00319 
00320   // case 1. empty string
00321   if (len_ == 0)
00322     return nill;
00323 
00324   // case 2. start pos l
00325   if (offset >= len_)
00326     return nill;
00327 
00328   // get all remaining bytes
00329   if (length == -1 || count > (this->len_ - offset))
00330     count = len_ - offset;
00331 
00332   return ACE_SString (&rep_[offset], count, this->allocator_);
00333 }
00334 
00335 // ************************************************************
00336 
00337 ACE_Tokenizer::ACE_Tokenizer (ACE_TCHAR *buffer)
00338   : buffer_ (buffer),
00339     index_ (0),
00340     preserves_index_ (0),
00341     delimiter_index_ (0)
00342 {
00343 }
00344 
00345 int
00346 ACE_Tokenizer::delimiter (ACE_TCHAR d)
00347 {
00348   if (delimiter_index_ == MAX_DELIMITERS)
00349     return -1;
00350 
00351   delimiters_[delimiter_index_].delimiter_ = d;
00352   delimiters_[delimiter_index_].replace_ = 0;
00353   delimiter_index_++;
00354   return 0;
00355 }
00356 
00357 int
00358 ACE_Tokenizer::delimiter_replace (ACE_TCHAR d,
00359                                   ACE_TCHAR replacement)
00360 {
00361   // Make it possible to replace delimiters on-the-fly, e.g., parse
00362   // string until certain token count and then copy rest of the
00363   // original string.
00364   for (int i = 0; i < delimiter_index_; i++)
00365     if (delimiters_[i].delimiter_ == d)
00366       {
00367         delimiters_[i].replacement_ = replacement;
00368         delimiters_[i].replace_ = 1;
00369         return 0;
00370       }
00371 
00372   if (delimiter_index_ >= MAX_DELIMITERS)
00373     return -1;
00374 
00375   delimiters_[delimiter_index_].delimiter_ = d;
00376   delimiters_[delimiter_index_].replacement_ = replacement;
00377   delimiters_[delimiter_index_].replace_ = 1;
00378   delimiter_index_++;
00379   return 0;
00380 }
00381 
00382 int
00383 ACE_Tokenizer::preserve_designators (ACE_TCHAR start,
00384                                      ACE_TCHAR stop,
00385                                      int strip)
00386 {
00387   if (preserves_index_ == MAX_PRESERVES)
00388     return -1;
00389 
00390   preserves_[preserves_index_].start_ = start;
00391   preserves_[preserves_index_].stop_ = stop;
00392   preserves_[preserves_index_].strip_ = strip;
00393   preserves_index_++;
00394   return 0;
00395 }
00396 
00397 int
00398 ACE_Tokenizer::is_delimiter (ACE_TCHAR d,
00399                              int &replace,
00400                              ACE_TCHAR &r)
00401 {
00402   replace = 0;
00403 
00404   for (int x = 0; x < delimiter_index_; x++)
00405     if (delimiters_[x].delimiter_ == d)
00406       {
00407         if (delimiters_[x].replace_)
00408           {
00409             r = delimiters_[x].replacement_;
00410             replace = 1;
00411           }
00412         return 1;
00413       }
00414 
00415   return 0;
00416 }
00417 
00418 int
00419 ACE_Tokenizer::is_preserve_designator (ACE_TCHAR start,
00420                                        ACE_TCHAR &stop,
00421                                        int &strip)
00422 {
00423   for (int x = 0; x < preserves_index_; x++)
00424     if (preserves_[x].start_ == start)
00425       {
00426         stop = preserves_[x].stop_;
00427         strip = preserves_[x].strip_;
00428         return 1;
00429       }
00430 
00431   return 0;
00432 }
00433 
00434 ACE_TCHAR *
00435 ACE_Tokenizer::next (void)
00436 {
00437   // Check if the previous pass was the last one in the buffer.
00438   if (index_ == -1)
00439     {
00440       index_ = 0;
00441       return 0;
00442     }
00443 
00444   ACE_TCHAR replacement = 0;
00445   int replace;
00446   ACE_TCHAR *next_token;
00447 
00448   // Skip all leading delimiters.
00449   for (;;)
00450     {
00451       // Check for end of string.
00452       if (buffer_[index_] == '\0')
00453         {
00454           // If we hit EOS at the start, return 0.
00455           index_ = 0;
00456           return 0;
00457         }
00458 
00459       if (this->is_delimiter (buffer_[index_],
00460                               replace,
00461                               replacement))
00462         index_++;
00463       else
00464         break;
00465     }
00466 
00467   // When we reach this point, buffer_[index_] is a non-delimiter and
00468   // not EOS - the start of our next_token.
00469   next_token = buffer_ + index_;
00470 
00471   // A preserved region is it's own token.
00472   ACE_TCHAR stop;
00473   int strip;
00474   if (this->is_preserve_designator (buffer_[index_],
00475                                     stop,
00476                                     strip))
00477     {
00478       while (++index_)
00479         {
00480           if (buffer_[index_] == '\0')
00481             {
00482               index_ = -1;
00483               goto EXIT_LABEL;
00484             }
00485 
00486           if (buffer_[index_] == stop)
00487             break;
00488         }
00489 
00490       if (strip)
00491         {
00492           // Skip start preserve designator.
00493           next_token += 1;
00494           // Zap the stop preserve designator.
00495           buffer_[index_] = '\0';
00496           // Increment to the next token.
00497           index_++;
00498         }
00499 
00500       goto EXIT_LABEL;
00501     }
00502 
00503   // Step through finding the next delimiter or EOS.
00504   for (;;)
00505     {
00506       // Advance pointer.
00507       index_++;
00508 
00509       // Check for delimiter.
00510       if (this->is_delimiter (buffer_[index_],
00511                               replace,
00512                               replacement))
00513         {
00514           // Replace the delimiter.
00515           if (replace != 0)
00516             buffer_[index_] = replacement;
00517 
00518           // Move the pointer up and return.
00519           index_++;
00520           goto EXIT_LABEL;
00521         }
00522 
00523       // A preserve designator signifies the end of this token.
00524       if (this->is_preserve_designator (buffer_[index_],
00525                                         stop,
00526                                         strip))
00527         goto EXIT_LABEL;
00528 
00529       // Check for end of string.
00530       if (buffer_[index_] == '\0')
00531         {
00532           index_ = -1;
00533           goto EXIT_LABEL;
00534         }
00535     }
00536 
00537 EXIT_LABEL:
00538   return next_token;
00539 }
00540 
00541 // *************************************************************
00542 
00543 #if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION)
00544 template char ACE_String_Base<char>::NULL_String_;
00545 template ACE_WSTRING_TYPE ACE_String_Base<ACE_WSTRING_TYPE>::NULL_String_;
00546 #endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */
00547 
00548 ACE_END_VERSIONED_NAMESPACE_DECL

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