TinyXml: tinystr.h Source File

- Main Page
- Related Pages
- Classes
- Files

- File List

# tinystr.h

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