Alexander Steiger / tinyxml
Committer:
steiger
Date:
Sun Nov 21 00:49:17 2010 +0000
Revision:
0:7c97dcef700c

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
steiger 0:7c97dcef700c 1 /*
steiger 0:7c97dcef700c 2 www.sourceforge.net/projects/tinyxml
steiger 0:7c97dcef700c 3 Original file by Yves Berquin.
steiger 0:7c97dcef700c 4
steiger 0:7c97dcef700c 5 This software is provided 'as-is', without any express or implied
steiger 0:7c97dcef700c 6 warranty. In no event will the authors be held liable for any
steiger 0:7c97dcef700c 7 damages arising from the use of this software.
steiger 0:7c97dcef700c 8
steiger 0:7c97dcef700c 9 Permission is granted to anyone to use this software for any
steiger 0:7c97dcef700c 10 purpose, including commercial applications, and to alter it and
steiger 0:7c97dcef700c 11 redistribute it freely, subject to the following restrictions:
steiger 0:7c97dcef700c 12
steiger 0:7c97dcef700c 13 1. The origin of this software must not be misrepresented; you must
steiger 0:7c97dcef700c 14 not claim that you wrote the original software. If you use this
steiger 0:7c97dcef700c 15 software in a product, an acknowledgment in the product documentation
steiger 0:7c97dcef700c 16 would be appreciated but is not required.
steiger 0:7c97dcef700c 17
steiger 0:7c97dcef700c 18 2. Altered source versions must be plainly marked as such, and
steiger 0:7c97dcef700c 19 must not be misrepresented as being the original software.
steiger 0:7c97dcef700c 20
steiger 0:7c97dcef700c 21 3. This notice may not be removed or altered from any source
steiger 0:7c97dcef700c 22 distribution.
steiger 0:7c97dcef700c 23 */
steiger 0:7c97dcef700c 24
steiger 0:7c97dcef700c 25 /*
steiger 0:7c97dcef700c 26 * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005.
steiger 0:7c97dcef700c 27 *
steiger 0:7c97dcef700c 28 * - completely rewritten. compact, clean, and fast implementation.
steiger 0:7c97dcef700c 29 * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems)
steiger 0:7c97dcef700c 30 * - fixed reserve() to work as per specification.
steiger 0:7c97dcef700c 31 * - fixed buggy compares operator==(), operator<(), and operator>()
steiger 0:7c97dcef700c 32 * - fixed operator+=() to take a const ref argument, following spec.
steiger 0:7c97dcef700c 33 * - added "copy" constructor with length, and most compare operators.
steiger 0:7c97dcef700c 34 * - added swap(), clear(), size(), capacity(), operator+().
steiger 0:7c97dcef700c 35 */
steiger 0:7c97dcef700c 36
steiger 0:7c97dcef700c 37 #ifndef TIXML_USE_STL
steiger 0:7c97dcef700c 38
steiger 0:7c97dcef700c 39 #ifndef TIXML_STRING_INCLUDED
steiger 0:7c97dcef700c 40 #define TIXML_STRING_INCLUDED
steiger 0:7c97dcef700c 41
steiger 0:7c97dcef700c 42 #include <assert.h>
steiger 0:7c97dcef700c 43 #include <string.h>
steiger 0:7c97dcef700c 44
steiger 0:7c97dcef700c 45 /* The support for explicit isn't that universal, and it isn't really
steiger 0:7c97dcef700c 46 required - it is used to check that the TiXmlString class isn't incorrectly
steiger 0:7c97dcef700c 47 used. Be nice to old compilers and macro it here:
steiger 0:7c97dcef700c 48 */
steiger 0:7c97dcef700c 49 #if defined(_MSC_VER) && (_MSC_VER >= 1200 )
steiger 0:7c97dcef700c 50 // Microsoft visual studio, version 6 and higher.
steiger 0:7c97dcef700c 51 #define TIXML_EXPLICIT explicit
steiger 0:7c97dcef700c 52 #elif defined(__GNUC__) && (__GNUC__ >= 3 )
steiger 0:7c97dcef700c 53 // GCC version 3 and higher.s
steiger 0:7c97dcef700c 54 #define TIXML_EXPLICIT explicit
steiger 0:7c97dcef700c 55 #else
steiger 0:7c97dcef700c 56 #define TIXML_EXPLICIT
steiger 0:7c97dcef700c 57 #endif
steiger 0:7c97dcef700c 58
steiger 0:7c97dcef700c 59
steiger 0:7c97dcef700c 60 /*
steiger 0:7c97dcef700c 61 TiXmlString is an emulation of a subset of the std::string template.
steiger 0:7c97dcef700c 62 Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
steiger 0:7c97dcef700c 63 Only the member functions relevant to the TinyXML project have been implemented.
steiger 0:7c97dcef700c 64 The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
steiger 0:7c97dcef700c 65 a string and there's no more room, we allocate a buffer twice as big as we need.
steiger 0:7c97dcef700c 66 */
steiger 0:7c97dcef700c 67 class TiXmlString
steiger 0:7c97dcef700c 68 {
steiger 0:7c97dcef700c 69 public :
steiger 0:7c97dcef700c 70 // The size type used
steiger 0:7c97dcef700c 71 typedef size_t size_type;
steiger 0:7c97dcef700c 72
steiger 0:7c97dcef700c 73 // Error value for find primitive
steiger 0:7c97dcef700c 74 static const size_type npos; // = -1;
steiger 0:7c97dcef700c 75
steiger 0:7c97dcef700c 76
steiger 0:7c97dcef700c 77 // TiXmlString empty constructor
steiger 0:7c97dcef700c 78 TiXmlString () : rep_(&nullrep_)
steiger 0:7c97dcef700c 79 {
steiger 0:7c97dcef700c 80 }
steiger 0:7c97dcef700c 81
steiger 0:7c97dcef700c 82 // TiXmlString copy constructor
steiger 0:7c97dcef700c 83 TiXmlString ( const TiXmlString & copy) : rep_(0)
steiger 0:7c97dcef700c 84 {
steiger 0:7c97dcef700c 85 init(copy.length());
steiger 0:7c97dcef700c 86 memcpy(start(), copy.data(), length());
steiger 0:7c97dcef700c 87 }
steiger 0:7c97dcef700c 88
steiger 0:7c97dcef700c 89 // TiXmlString constructor, based on a string
steiger 0:7c97dcef700c 90 TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0)
steiger 0:7c97dcef700c 91 {
steiger 0:7c97dcef700c 92 init( static_cast<size_type>( strlen(copy) ));
steiger 0:7c97dcef700c 93 memcpy(start(), copy, length());
steiger 0:7c97dcef700c 94 }
steiger 0:7c97dcef700c 95
steiger 0:7c97dcef700c 96 // TiXmlString constructor, based on a string
steiger 0:7c97dcef700c 97 TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0)
steiger 0:7c97dcef700c 98 {
steiger 0:7c97dcef700c 99 init(len);
steiger 0:7c97dcef700c 100 memcpy(start(), str, len);
steiger 0:7c97dcef700c 101 }
steiger 0:7c97dcef700c 102
steiger 0:7c97dcef700c 103 // TiXmlString destructor
steiger 0:7c97dcef700c 104 ~TiXmlString ()
steiger 0:7c97dcef700c 105 {
steiger 0:7c97dcef700c 106 quit();
steiger 0:7c97dcef700c 107 }
steiger 0:7c97dcef700c 108
steiger 0:7c97dcef700c 109 // = operator
steiger 0:7c97dcef700c 110 TiXmlString& operator = (const char * copy)
steiger 0:7c97dcef700c 111 {
steiger 0:7c97dcef700c 112 return assign( copy, (size_type)strlen(copy));
steiger 0:7c97dcef700c 113 }
steiger 0:7c97dcef700c 114
steiger 0:7c97dcef700c 115 // = operator
steiger 0:7c97dcef700c 116 TiXmlString& operator = (const TiXmlString & copy)
steiger 0:7c97dcef700c 117 {
steiger 0:7c97dcef700c 118 return assign(copy.start(), copy.length());
steiger 0:7c97dcef700c 119 }
steiger 0:7c97dcef700c 120
steiger 0:7c97dcef700c 121
steiger 0:7c97dcef700c 122 // += operator. Maps to append
steiger 0:7c97dcef700c 123 TiXmlString& operator += (const char * suffix)
steiger 0:7c97dcef700c 124 {
steiger 0:7c97dcef700c 125 return append(suffix, static_cast<size_type>( strlen(suffix) ));
steiger 0:7c97dcef700c 126 }
steiger 0:7c97dcef700c 127
steiger 0:7c97dcef700c 128 // += operator. Maps to append
steiger 0:7c97dcef700c 129 TiXmlString& operator += (char single)
steiger 0:7c97dcef700c 130 {
steiger 0:7c97dcef700c 131 return append(&single, 1);
steiger 0:7c97dcef700c 132 }
steiger 0:7c97dcef700c 133
steiger 0:7c97dcef700c 134 // += operator. Maps to append
steiger 0:7c97dcef700c 135 TiXmlString& operator += (const TiXmlString & suffix)
steiger 0:7c97dcef700c 136 {
steiger 0:7c97dcef700c 137 return append(suffix.data(), suffix.length());
steiger 0:7c97dcef700c 138 }
steiger 0:7c97dcef700c 139
steiger 0:7c97dcef700c 140
steiger 0:7c97dcef700c 141 // Convert a TiXmlString into a null-terminated char *
steiger 0:7c97dcef700c 142 const char * c_str () const { return rep_->str; }
steiger 0:7c97dcef700c 143
steiger 0:7c97dcef700c 144 // Convert a TiXmlString into a char * (need not be null terminated).
steiger 0:7c97dcef700c 145 const char * data () const { return rep_->str; }
steiger 0:7c97dcef700c 146
steiger 0:7c97dcef700c 147 // Return the length of a TiXmlString
steiger 0:7c97dcef700c 148 size_type length () const { return rep_->size; }
steiger 0:7c97dcef700c 149
steiger 0:7c97dcef700c 150 // Alias for length()
steiger 0:7c97dcef700c 151 size_type size () const { return rep_->size; }
steiger 0:7c97dcef700c 152
steiger 0:7c97dcef700c 153 // Checks if a TiXmlString is empty
steiger 0:7c97dcef700c 154 bool empty () const { return rep_->size == 0; }
steiger 0:7c97dcef700c 155
steiger 0:7c97dcef700c 156 // Return capacity of string
steiger 0:7c97dcef700c 157 size_type capacity () const { return rep_->capacity; }
steiger 0:7c97dcef700c 158
steiger 0:7c97dcef700c 159
steiger 0:7c97dcef700c 160 // single char extraction
steiger 0:7c97dcef700c 161 const char& at (size_type index) const
steiger 0:7c97dcef700c 162 {
steiger 0:7c97dcef700c 163 assert( index < length() );
steiger 0:7c97dcef700c 164 return rep_->str[ index ];
steiger 0:7c97dcef700c 165 }
steiger 0:7c97dcef700c 166
steiger 0:7c97dcef700c 167 // [] operator
steiger 0:7c97dcef700c 168 char& operator [] (size_type index) const
steiger 0:7c97dcef700c 169 {
steiger 0:7c97dcef700c 170 assert( index < length() );
steiger 0:7c97dcef700c 171 return rep_->str[ index ];
steiger 0:7c97dcef700c 172 }
steiger 0:7c97dcef700c 173
steiger 0:7c97dcef700c 174 // find a char in a string. Return TiXmlString::npos if not found
steiger 0:7c97dcef700c 175 size_type find (char lookup) const
steiger 0:7c97dcef700c 176 {
steiger 0:7c97dcef700c 177 return find(lookup, 0);
steiger 0:7c97dcef700c 178 }
steiger 0:7c97dcef700c 179
steiger 0:7c97dcef700c 180 // find a char in a string from an offset. Return TiXmlString::npos if not found
steiger 0:7c97dcef700c 181 size_type find (char tofind, size_type offset) const
steiger 0:7c97dcef700c 182 {
steiger 0:7c97dcef700c 183 if (offset >= length()) return npos;
steiger 0:7c97dcef700c 184
steiger 0:7c97dcef700c 185 for (const char* p = c_str() + offset; *p != '\0'; ++p)
steiger 0:7c97dcef700c 186 {
steiger 0:7c97dcef700c 187 if (*p == tofind) return static_cast< size_type >( p - c_str() );
steiger 0:7c97dcef700c 188 }
steiger 0:7c97dcef700c 189 return npos;
steiger 0:7c97dcef700c 190 }
steiger 0:7c97dcef700c 191
steiger 0:7c97dcef700c 192 void clear ()
steiger 0:7c97dcef700c 193 {
steiger 0:7c97dcef700c 194 //Lee:
steiger 0:7c97dcef700c 195 //The original was just too strange, though correct:
steiger 0:7c97dcef700c 196 // TiXmlString().swap(*this);
steiger 0:7c97dcef700c 197 //Instead use the quit & re-init:
steiger 0:7c97dcef700c 198 quit();
steiger 0:7c97dcef700c 199 init(0,0);
steiger 0:7c97dcef700c 200 }
steiger 0:7c97dcef700c 201
steiger 0:7c97dcef700c 202 /* Function to reserve a big amount of data when we know we'll need it. Be aware that this
steiger 0:7c97dcef700c 203 function DOES NOT clear the content of the TiXmlString if any exists.
steiger 0:7c97dcef700c 204 */
steiger 0:7c97dcef700c 205 void reserve (size_type cap);
steiger 0:7c97dcef700c 206
steiger 0:7c97dcef700c 207 TiXmlString& assign (const char* str, size_type len);
steiger 0:7c97dcef700c 208
steiger 0:7c97dcef700c 209 TiXmlString& append (const char* str, size_type len);
steiger 0:7c97dcef700c 210
steiger 0:7c97dcef700c 211 void swap (TiXmlString& other)
steiger 0:7c97dcef700c 212 {
steiger 0:7c97dcef700c 213 Rep* r = rep_;
steiger 0:7c97dcef700c 214 rep_ = other.rep_;
steiger 0:7c97dcef700c 215 other.rep_ = r;
steiger 0:7c97dcef700c 216 }
steiger 0:7c97dcef700c 217
steiger 0:7c97dcef700c 218 private:
steiger 0:7c97dcef700c 219
steiger 0:7c97dcef700c 220 void init(size_type sz) { init(sz, sz); }
steiger 0:7c97dcef700c 221 void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
steiger 0:7c97dcef700c 222 char* start() const { return rep_->str; }
steiger 0:7c97dcef700c 223 char* finish() const { return rep_->str + rep_->size; }
steiger 0:7c97dcef700c 224
steiger 0:7c97dcef700c 225 struct Rep
steiger 0:7c97dcef700c 226 {
steiger 0:7c97dcef700c 227 size_type size, capacity;
steiger 0:7c97dcef700c 228 char str[1];
steiger 0:7c97dcef700c 229 };
steiger 0:7c97dcef700c 230
steiger 0:7c97dcef700c 231 void init(size_type sz, size_type cap)
steiger 0:7c97dcef700c 232 {
steiger 0:7c97dcef700c 233 if (cap)
steiger 0:7c97dcef700c 234 {
steiger 0:7c97dcef700c 235 // Lee: the original form:
steiger 0:7c97dcef700c 236 // rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
steiger 0:7c97dcef700c 237 // doesn't work in some cases of new being overloaded. Switching
steiger 0:7c97dcef700c 238 // to the normal allocation, although use an 'int' for systems
steiger 0:7c97dcef700c 239 // that are overly picky about structure alignment.
steiger 0:7c97dcef700c 240 const size_type bytesNeeded = sizeof(Rep) + cap;
steiger 0:7c97dcef700c 241 const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int );
steiger 0:7c97dcef700c 242 rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
steiger 0:7c97dcef700c 243
steiger 0:7c97dcef700c 244 rep_->str[ rep_->size = sz ] = '\0';
steiger 0:7c97dcef700c 245 rep_->capacity = cap;
steiger 0:7c97dcef700c 246 }
steiger 0:7c97dcef700c 247 else
steiger 0:7c97dcef700c 248 {
steiger 0:7c97dcef700c 249 rep_ = &nullrep_;
steiger 0:7c97dcef700c 250 }
steiger 0:7c97dcef700c 251 }
steiger 0:7c97dcef700c 252
steiger 0:7c97dcef700c 253 void quit()
steiger 0:7c97dcef700c 254 {
steiger 0:7c97dcef700c 255 if (rep_ != &nullrep_)
steiger 0:7c97dcef700c 256 {
steiger 0:7c97dcef700c 257 // The rep_ is really an array of ints. (see the allocator, above).
steiger 0:7c97dcef700c 258 // Cast it back before delete, so the compiler won't incorrectly call destructors.
steiger 0:7c97dcef700c 259 delete [] ( reinterpret_cast<int*>( rep_ ) );
steiger 0:7c97dcef700c 260 }
steiger 0:7c97dcef700c 261 }
steiger 0:7c97dcef700c 262
steiger 0:7c97dcef700c 263 Rep * rep_;
steiger 0:7c97dcef700c 264 static Rep nullrep_;
steiger 0:7c97dcef700c 265
steiger 0:7c97dcef700c 266 } ;
steiger 0:7c97dcef700c 267
steiger 0:7c97dcef700c 268
steiger 0:7c97dcef700c 269 inline bool operator == (const TiXmlString & a, const TiXmlString & b)
steiger 0:7c97dcef700c 270 {
steiger 0:7c97dcef700c 271 return ( a.length() == b.length() ) // optimization on some platforms
steiger 0:7c97dcef700c 272 && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare
steiger 0:7c97dcef700c 273 }
steiger 0:7c97dcef700c 274 inline bool operator < (const TiXmlString & a, const TiXmlString & b)
steiger 0:7c97dcef700c 275 {
steiger 0:7c97dcef700c 276 return strcmp(a.c_str(), b.c_str()) < 0;
steiger 0:7c97dcef700c 277 }
steiger 0:7c97dcef700c 278
steiger 0:7c97dcef700c 279 inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); }
steiger 0:7c97dcef700c 280 inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; }
steiger 0:7c97dcef700c 281 inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); }
steiger 0:7c97dcef700c 282 inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); }
steiger 0:7c97dcef700c 283
steiger 0:7c97dcef700c 284 inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; }
steiger 0:7c97dcef700c 285 inline bool operator == (const char* a, const TiXmlString & b) { return b == a; }
steiger 0:7c97dcef700c 286 inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); }
steiger 0:7c97dcef700c 287 inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); }
steiger 0:7c97dcef700c 288
steiger 0:7c97dcef700c 289 TiXmlString operator + (const TiXmlString & a, const TiXmlString & b);
steiger 0:7c97dcef700c 290 TiXmlString operator + (const TiXmlString & a, const char* b);
steiger 0:7c97dcef700c 291 TiXmlString operator + (const char* a, const TiXmlString & b);
steiger 0:7c97dcef700c 292
steiger 0:7c97dcef700c 293
steiger 0:7c97dcef700c 294 /*
steiger 0:7c97dcef700c 295 TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
steiger 0:7c97dcef700c 296 Only the operators that we need for TinyXML have been developped.
steiger 0:7c97dcef700c 297 */
steiger 0:7c97dcef700c 298 class TiXmlOutStream : public TiXmlString
steiger 0:7c97dcef700c 299 {
steiger 0:7c97dcef700c 300 public :
steiger 0:7c97dcef700c 301
steiger 0:7c97dcef700c 302 // TiXmlOutStream << operator.
steiger 0:7c97dcef700c 303 TiXmlOutStream & operator << (const TiXmlString & in)
steiger 0:7c97dcef700c 304 {
steiger 0:7c97dcef700c 305 *this += in;
steiger 0:7c97dcef700c 306 return *this;
steiger 0:7c97dcef700c 307 }
steiger 0:7c97dcef700c 308
steiger 0:7c97dcef700c 309 // TiXmlOutStream << operator.
steiger 0:7c97dcef700c 310 TiXmlOutStream & operator << (const char * in)
steiger 0:7c97dcef700c 311 {
steiger 0:7c97dcef700c 312 *this += in;
steiger 0:7c97dcef700c 313 return *this;
steiger 0:7c97dcef700c 314 }
steiger 0:7c97dcef700c 315
steiger 0:7c97dcef700c 316 } ;
steiger 0:7c97dcef700c 317
steiger 0:7c97dcef700c 318 #endif // TIXML_STRING_INCLUDED
steiger 0:7c97dcef700c 319 #endif // TIXML_USE_STL