osgEarth 2.1.1
|
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