Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

SString.cpp

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

Generated on Mon Jun 16 11:21:23 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002