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    TiXmlString is an emulation of a subset of the std::string template.
00061    Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
00062    Only the member functions relevant to the TinyXML project have been implemented.
00063    The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
00064    a string and there's no more room, we allocate a buffer twice as big as we need.
00065    */
00066 class TiXmlString {
00067     public:
00068         // The size type used
00069         typedef size_t size_type;
00070 
00071         // Error value for find primitive
00072         static const size_type npos; // = -1;
00073 
00074 
00075         // TiXmlString empty constructor
00076         TiXmlString() :
00077             rep_(&nullrep_) {
00078             }
00079 
00080         // TiXmlString copy constructor
00081         TiXmlString(const TiXmlString & copy) :
00082             rep_(0) {
00083                 init(copy.length());
00084                 memcpy(start(), copy.data(), length());
00085             }
00086 
00087         // TiXmlString constructor, based on a string
00088         TIXML_EXPLICIT TiXmlString(const char * copy) :
00089             rep_(0) {
00090                 init(static_cast<size_type> (strlen(copy)));
00091                 memcpy(start(), copy, length());
00092             }
00093 
00094         // TiXmlString constructor, based on a string
00095         TIXML_EXPLICIT TiXmlString(const char * str, size_type len) :
00096             rep_(0) {
00097                 init(len);
00098                 memcpy(start(), str, len);
00099             }
00100 
00101         // TiXmlString destructor
00102         ~TiXmlString() {
00103             quit();
00104         }
00105 
00106         // = operator
00107         TiXmlString& operator =(const char * copy) {
00108             return assign(copy, (size_type) strlen(copy));
00109         }
00110 
00111         // = operator
00112         TiXmlString& operator =(const TiXmlString & copy) {
00113             return assign(copy.start(), copy.length());
00114         }
00115 
00116         // += operator. Maps to append
00117         TiXmlString& operator +=(const char * suffix) {
00118             return append(suffix, static_cast<size_type> (strlen(suffix)));
00119         }
00120 
00121         // += operator. Maps to append
00122         TiXmlString& operator +=(char single) {
00123             return append(&single, 1);
00124         }
00125 
00126         // += operator. Maps to append
00127         TiXmlString& operator +=(const TiXmlString & suffix) {
00128             return append(suffix.data(), suffix.length());
00129         }
00130 
00131         // Convert a TiXmlString into a null-terminated char *
00132         const char * c_str() const {
00133             return rep_->str;
00134         }
00135 
00136         // Convert a TiXmlString into a char * (need not be null terminated).
00137         const char * data() const {
00138             return rep_->str;
00139         }
00140 
00141         // Return the length of a TiXmlString
00142         size_type length() const {
00143             return rep_->size;
00144         }
00145 
00146         // Alias for length()
00147         size_type size() const {
00148             return rep_->size;
00149         }
00150 
00151         // Checks if a TiXmlString is empty
00152         bool empty() const {
00153             return rep_->size == 0;
00154         }
00155 
00156         // Return capacity of string
00157         size_type capacity() const {
00158             return rep_->capacity;
00159         }
00160 
00161         // single char extraction
00162         const char& at(size_type index) const {
00163             assert( index < length() );
00164             return rep_->str[index];
00165         }
00166 
00167         // [] operator
00168         char& operator [](size_type index) const {
00169             assert( index < length() );
00170             return rep_->str[index];
00171         }
00172 
00173         // find a char in a string. Return TiXmlString::npos if not found
00174         size_type find(char lookup) const {
00175             return find(lookup, 0);
00176         }
00177 
00178         // find a char in a string from an offset. Return TiXmlString::npos if not found
00179         size_type find(char tofind, size_type offset) const {
00180             if (offset >= length())
00181                 return npos;
00182 
00183             for (const char* p = c_str() + offset; *p != '\0'; ++p) {
00184                 if (*p == tofind)
00185                     return static_cast<size_type> (p - c_str());
00186             }
00187             return npos;
00188         }
00189 
00190         void clear() {
00191             //Lee:
00192             //The original was just too strange, though correct:
00193             //  TiXmlString().swap(*this);
00194             //Instead use the quit & re-init:
00195             quit();
00196             init(0, 0);
00197         }
00198 
00199         /*      Function to reserve a big amount of data when we know we'll need it. Be aware that this
00200             function DOES NOT clear the content of the TiXmlString if any exists.
00201             */
00202         void reserve(size_type cap);
00203 
00204         TiXmlString& assign(const char* str, size_type len);
00205 
00206         TiXmlString& append(const char* str, size_type len);
00207 
00208         void swap(TiXmlString& other) {
00209             Rep* r = rep_;
00210             rep_ = other.rep_;
00211             other.rep_ = r;
00212         }
00213 
00214     private:
00215 
00216         void init(size_type sz) {
00217             init(sz, sz);
00218         }
00219         void set_size(size_type sz) {
00220             rep_->str[rep_->size = sz] = '\0';
00221         }
00222         char* start() const {
00223             return rep_->str;
00224         }
00225         char* finish() const {
00226             return rep_->str + rep_->size;
00227         }
00228 
00229         struct Rep {
00230             size_type size, capacity;
00231             char str[1];
00232         };
00233 
00234         void init(size_type sz, size_type cap) {
00235             if (cap) {
00236                 // Lee: the original form:
00237                 //      rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
00238                 // doesn't work in some cases of new being overloaded. Switching
00239                 // to the normal allocation, although use an 'int' for systems
00240                 // that are overly picky about structure alignment.
00241                 const size_type bytesNeeded = sizeof(Rep) + cap;
00242                 const size_type intsNeeded = (bytesNeeded + sizeof(int) - 1)
00243                     / sizeof(int);
00244                 rep_ = reinterpret_cast<Rep*> (new int[intsNeeded]);
00245 
00246                 rep_->str[rep_->size = sz] = '\0';
00247                 rep_->capacity = cap;
00248             } else {
00249                 rep_ = &nullrep_;
00250             }
00251         }
00252 
00253         void quit() {
00254             if (rep_ != &nullrep_) {
00255                 // The rep_ is really an array of ints. (see the allocator, above).
00256                 // Cast it back before delete, so the compiler won't incorrectly call destructors.
00257                 delete[] (reinterpret_cast<int*> (rep_));
00258             }
00259         }
00260 
00261         Rep * rep_;
00262         static Rep nullrep_;
00263 
00264 };
00265 
00266     inline bool operator ==(const TiXmlString & a, const TiXmlString & b) {
00267         return (a.length() == b.length()) // optimization on some platforms
00268             && (strcmp(a.c_str(), b.c_str()) == 0); // actual compare
00269     }
00270 inline bool operator <(const TiXmlString & a, const TiXmlString & b) {
00271     return strcmp(a.c_str(), b.c_str()) < 0;
00272 }
00273 
00274 inline bool operator !=(const TiXmlString & a, const TiXmlString & b) {
00275     return !(a == b);
00276 }
00277 inline bool operator>(const TiXmlString & a, const TiXmlString & b) {
00278     return b < a;
00279 }
00280 inline bool operator <=(const TiXmlString & a, const TiXmlString & b) {
00281     return !(b < a);
00282 }
00283 inline bool operator >=(const TiXmlString & a, const TiXmlString & b) {
00284     return !(a < b);
00285 }
00286 
00287 inline bool operator ==(const TiXmlString & a, const char* b) {
00288     return strcmp(a.c_str(), b) == 0;
00289 }
00290 inline bool operator ==(const char* a, const TiXmlString & b) {
00291     return b == a;
00292 }
00293 inline bool operator !=(const TiXmlString & a, const char* b) {
00294     return !(a == b);
00295 }
00296 inline bool operator !=(const char* a, const TiXmlString & b) {
00297     return !(b == a);
00298 }
00299 
00300 TiXmlString operator +(const TiXmlString & a, const TiXmlString & b);
00301 TiXmlString operator +(const TiXmlString & a, const char* b);
00302 TiXmlString operator +(const char* a, const TiXmlString & b);
00303 
00304 /*
00305    TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
00306    Only the operators that we need for TinyXML have been developped.
00307    */
00308 class TiXmlOutStream: public TiXmlString {
00309     public:
00310 
00311         // TiXmlOutStream << operator.
00312         TiXmlOutStream & operator <<(const TiXmlString & in) {
00313             *this += in;
00314             return *this;
00315         }
00316 
00317         // TiXmlOutStream << operator.
00318         TiXmlOutStream & operator <<(const char * in) {
00319             *this += in;
00320             return *this;
00321         }
00322 
00323 };
00324 
00325 #endif  // TIXML_STRING_INCLUDED
00326 #endif  // TIXML_USE_STL


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:29