Main Page | Class Hierarchy | Class List | File List | Class Members

# tinystr.h

    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)
    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)
    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)
    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