Back to index

nux  3.0.0
tinystr.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 /*
00024 www.sourceforge.net/projects/tinyxml
00025 Original file by Yves Berquin.
00026 
00027 This software is provided 'as-is', without any express or implied
00028 warranty. In no event will the authors be held liable for any
00029 damages arising from the use of this software.
00030 
00031 Permission is granted to anyone to use this software for any
00032 purpose, including commercial applications, and to alter it and
00033 redistribute it freely, subject to the following restrictions:
00034 
00035 1. The origin of this software must not be misrepresented; you must
00036 not claim that you wrote the original software. If you use this
00037 software in a product, an acknowledgment in the product documentation
00038 would be appreciated but is not required.
00039 
00040 2. Altered source versions must be plainly marked as such, and
00041 must not be misrepresented as being the original software.
00042 
00043 3. This notice may not be removed or altered from any source
00044 distribution.
00045 */
00046 
00047 /*
00048  * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005.
00049  *
00050  * - completely rewritten. compact, clean, and fast implementation.
00051  * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems)
00052  * - fixed reserve() to work as per specification.
00053  * - fixed buggy compares operator==(), operator<(), and operator>()
00054  * - fixed operator+=() to take a const ref argument, following spec.
00055  * - added "copy" constructor with length, and most compare operators.
00056  * - added swap(), clear(), size(), capacity(), operator+().
00057  */
00058 
00059 #ifndef TIXML_USE_STL
00060 
00061 #ifndef TIXML_STRING_INCLUDED
00062 #define TIXML_STRING_INCLUDED
00063 
00064 #include <assert.h>
00065 #include <string.h>
00066 
00067 /*     The support for explicit isn't that universal, and it isn't really
00068        required - it is used to check that the TiXmlString class isn't incorrectly
00069        used. Be nice to old compilers and macro it here:
00070 */
00071 #if defined(_MSC_VER) && (_MSC_VER >= 1200 )
00072 // Microsoft visual studio, version 6 and higher.
00073 #define TIXML_EXPLICIT explicit
00074 #elif defined(__GNUC__) && (__GNUC__ >= 3 )
00075 // GCC version 3 and higher.s
00076 #define TIXML_EXPLICIT explicit
00077 #else
00078 #define TIXML_EXPLICIT
00079 #endif
00080 
00081 
00082 /*
00083    TiXmlString is an emulation of a subset of the std::string template.
00084    Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
00085    Only the member functions relevant to the TinyXML project have been implemented.
00086    The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
00087    a string and there's no more room, we allocate a buffer twice as big as we need.
00088 */
00089 class TiXmlString
00090 {
00091 public :
00092   // The size type used
00093   typedef size_t size_type;
00094 
00095   // Error value for find primitive
00096   static const size_type npos; // = -1;
00097 
00098 
00099   // TiXmlString empty constructor
00100   TiXmlString () : rep_ (&nullrep_)
00101   {
00102   }
00103 
00104   // TiXmlString copy constructor
00105   TiXmlString ( const TiXmlString &copy) : rep_ (0)
00106   {
00107     init (copy.length() );
00108     memcpy (start(), copy.data(), length() );
00109   }
00110 
00111   // TiXmlString constructor, based on a string
00112   TIXML_EXPLICIT TiXmlString ( const char *copy) : rep_ (0)
00113   {
00114     init ( static_cast<size_type> ( strlen (copy) ) );
00115     memcpy (start(), copy, length() );
00116   }
00117 
00118   // TiXmlString constructor, based on a string
00119   TIXML_EXPLICIT TiXmlString ( const char *str, size_type len) : rep_ (0)
00120   {
00121     init (len);
00122     memcpy (start(), str, len);
00123   }
00124 
00125   // TiXmlString destructor
00126   ~TiXmlString ()
00127   {
00128     quit();
00129   }
00130 
00131   // = operator
00132   TiXmlString &operator = (const char *copy)
00133   {
00134     return assign ( copy, (size_type) strlen (copy) );
00135   }
00136 
00137   // = operator
00138   TiXmlString &operator = (const TiXmlString &copy)
00139   {
00140     return assign (copy.start(), copy.length() );
00141   }
00142 
00143 
00144   // += operator. Maps to append
00145   TiXmlString &operator += (const char *suffix)
00146   {
00147     return append (suffix, static_cast<size_type> ( strlen (suffix) ) );
00148   }
00149 
00150   // += operator. Maps to append
00151   TiXmlString &operator += (char single)
00152   {
00153     return append (&single, 1);
00154   }
00155 
00156   // += operator. Maps to append
00157   TiXmlString &operator += (const TiXmlString &suffix)
00158   {
00159     return append (suffix.data(), suffix.length() );
00160   }
00161 
00162 
00163   // Convert a TiXmlString into a null-terminated char *
00164   const char *c_str () const
00165   {
00166     return rep_->str;
00167   }
00168 
00169   // Convert a TiXmlString into a char * (need not be null terminated).
00170   const char *data () const
00171   {
00172     return rep_->str;
00173   }
00174 
00175   // Return the length of a TiXmlString
00176   size_type length () const
00177   {
00178     return rep_->size;
00179   }
00180 
00181   // Alias for length()
00182   size_type size () const
00183   {
00184     return rep_->size;
00185   }
00186 
00187   // Checks if a TiXmlString is empty
00188   bool empty () const
00189   {
00190     return rep_->size == 0;
00191   }
00192 
00193   // Return capacity of string
00194   size_type capacity () const
00195   {
00196     return rep_->capacity;
00197   }
00198 
00199 
00200   // single char extraction
00201   const char &at (size_type index) const
00202   {
00203     assert ( index < length() );
00204     return rep_->str[ index ];
00205   }
00206 
00207   // [] operator
00208   char &operator [] (size_type index) const
00209   {
00210     assert ( index < length() );
00211     return rep_->str[ index ];
00212   }
00213 
00214   // find a char in a string. Return TiXmlString::npos if not found
00215   size_type find (char lookup) const
00216   {
00217     return find (lookup, 0);
00218   }
00219 
00220   // find a char in a string from an offset. Return TiXmlString::npos if not found
00221   size_type find (char tofind, size_type offset) const
00222   {
00223     if (offset >= length() ) return npos;
00224 
00225     for (const char *p = c_str() + offset; *p != '\0'; ++p)
00226     {
00227       if (*p == tofind) return static_cast< size_type > ( p - c_str() );
00228     }
00229 
00230     return npos;
00231   }
00232 
00233   void clear ()
00234   {
00235     //Lee:
00236     //The original was just too strange, though correct:
00237     // TiXmlString().swap(*this);
00238     //Instead use the quit & re-init:
00239     quit();
00240     init (0, 0);
00241   }
00242 
00243   /*   Function to reserve a big amount of data when we know we'll need it. Be aware that this
00244        function DOES NOT clear the content of the TiXmlString if any exists.
00245   */
00246   void reserve (size_type cap);
00247 
00248   TiXmlString &assign (const char *str, size_type len);
00249 
00250   TiXmlString &append (const char *str, size_type len);
00251 
00252   void swap (TiXmlString &other)
00253   {
00254     Rep *r = rep_;
00255     rep_ = other.rep_;
00256     other.rep_ = r;
00257   }
00258 
00259 private:
00260 
00261   void init (size_type sz)
00262   {
00263     init (sz, sz);
00264   }
00265   void set_size (size_type sz)
00266   {
00267     rep_->str[ rep_->size = sz ] = '\0';
00268   }
00269   char *start() const
00270   {
00271     return rep_->str;
00272   }
00273   char *finish() const
00274   {
00275     return rep_->str + rep_->size;
00276   }
00277 
00278   struct Rep
00279   {
00280     size_type size, capacity;
00281     char str[1];
00282   };
00283 
00284   void init (size_type sz, size_type cap)
00285   {
00286     if (cap)
00287     {
00288       // Lee: the original form:
00289       //      rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
00290       // doesn't work in some cases of new being overloaded. Switching
00291       // to the normal allocation, although use an 'int' for systems
00292       // that are overly picky about structure alignment.
00293       const size_type bytesNeeded = sizeof (Rep) + cap;
00294       const size_type intsNeeded = ( bytesNeeded + sizeof (int) - 1 ) / sizeof ( int );
00295       rep_ = reinterpret_cast<Rep *> ( new int[ intsNeeded ] );
00296 
00297       rep_->str[ rep_->size = sz ] = '\0';
00298       rep_->capacity = cap;
00299     }
00300     else
00301     {
00302       rep_ = &nullrep_;
00303     }
00304   }
00305 
00306   void quit()
00307   {
00308     if (rep_ != &nullrep_)
00309     {
00310       // The rep_ is really an array of ints. (see the allocator, above).
00311       // Cast it back before delete, so the compiler won't incorrectly call destructors.
00312       delete [] ( reinterpret_cast<int *> ( rep_ ) );
00313     }
00314   }
00315 
00316   Rep *rep_;
00317   static Rep nullrep_;
00318 
00319 } ;
00320 
00321 
00322 inline bool operator == (const TiXmlString &a, const TiXmlString &b)
00323 {
00324   return    ( a.length() == b.length() )                       // optimization on some platforms
00325             && ( strcmp (a.c_str(), b.c_str() ) == 0 ); // actual compare
00326 }
00327 inline bool operator < (const TiXmlString &a, const TiXmlString &b)
00328 {
00329   return strcmp (a.c_str(), b.c_str() ) < 0;
00330 }
00331 
00332 inline bool operator != (const TiXmlString &a, const TiXmlString &b)
00333 {
00334   return ! (a == b);
00335 }
00336 inline bool operator >  (const TiXmlString &a, const TiXmlString &b)
00337 {
00338   return b < a;
00339 }
00340 inline bool operator <= (const TiXmlString &a, const TiXmlString &b)
00341 {
00342   return ! (b < a);
00343 }
00344 inline bool operator >= (const TiXmlString &a, const TiXmlString &b)
00345 {
00346   return ! (a < b);
00347 }
00348 
00349 inline bool operator == (const TiXmlString &a, const char *b)
00350 {
00351   return strcmp (a.c_str(), b) == 0;
00352 }
00353 inline bool operator == (const char *a, const TiXmlString &b)
00354 {
00355   return b == a;
00356 }
00357 inline bool operator != (const TiXmlString &a, const char *b)
00358 {
00359   return ! (a == b);
00360 }
00361 inline bool operator != (const char *a, const TiXmlString &b)
00362 {
00363   return ! (b == a);
00364 }
00365 
00366 TiXmlString operator + (const TiXmlString &a, const TiXmlString &b);
00367 TiXmlString operator + (const TiXmlString &a, const char *b);
00368 TiXmlString operator + (const char *a, const TiXmlString &b);
00369 
00370 
00371 /*
00372    TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
00373    Only the operators that we need for TinyXML have been developped.
00374 */
00375 class TiXmlOutStream : public TiXmlString
00376 {
00377 public :
00378 
00379   // TiXmlOutStream << operator.
00380   TiXmlOutStream &operator << (const TiXmlString &in)
00381   {
00382     *this += in;
00383     return *this;
00384   }
00385 
00386   // TiXmlOutStream << operator.
00387   TiXmlOutStream &operator << (const char *in)
00388   {
00389     *this += in;
00390     return *this;
00391   }
00392 
00393 } ;
00394 
00395 #endif // TIXML_STRING_INCLUDED
00396 #endif // TIXML_USE_STL