SString.cpp

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

Generated on Tue Feb 2 17:18:42 2010 for ACE by  doxygen 1.4.7