MTK++ Latest version: 0.2.0

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

Generated on Fri Dec 23 2011 09:28:52 for MTK++ by Doxygen 1.7.5.1