nux-1.14.0
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 /* 00024 www.sourceforge.net/projects/tinyxml 00025 Original file by Yves Berquin. 00026 00027 This software is provided 'as-is', without any express or implied 00028 warranty. In no event will the authors be held liable for any 00029 damages arising from the use of this software. 00030 00031 Permission is granted to anyone to use this software for any 00032 purpose, including commercial applications, and to alter it and 00033 redistribute it freely, subject to the following restrictions: 00034 00035 1. The origin of this software must not be misrepresented; you must 00036 not claim that you wrote the original software. If you use this 00037 software in a product, an acknowledgment in the product documentation 00038 would be appreciated but is not required. 00039 00040 2. Altered source versions must be plainly marked as such, and 00041 must not be misrepresented as being the original software. 00042 00043 3. This notice may not be removed or altered from any source 00044 distribution. 00045 */ 00046 00047 /* 00048 * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005. 00049 * 00050 * - completely rewritten. compact, clean, and fast implementation. 00051 * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems) 00052 * - fixed reserve() to work as per specification. 00053 * - fixed buggy compares operator==(), operator<(), and operator>() 00054 * - fixed operator+=() to take a const ref argument, following spec. 00055 * - added "copy" constructor with length, and most compare operators. 00056 * - added swap(), clear(), size(), capacity(), operator+(). 00057 */ 00058 00059 #ifndef TIXML_USE_STL 00060 00061 #ifndef TIXML_STRING_INCLUDED 00062 #define TIXML_STRING_INCLUDED 00063 00064 #include <assert.h> 00065 #include <string.h> 00066 00067 /* The support for explicit isn't that universal, and it isn't really 00068 required - it is used to check that the TiXmlString class isn't incorrectly 00069 used. Be nice to old compilers and macro it here: 00070 */ 00071 #if defined(_MSC_VER) && (_MSC_VER >= 1200 ) 00072 // Microsoft visual studio, version 6 and higher. 00073 #define TIXML_EXPLICIT explicit 00074 #elif defined(__GNUC__) && (__GNUC__ >= 3 ) 00075 // GCC version 3 and higher.s 00076 #define TIXML_EXPLICIT explicit 00077 #else 00078 #define TIXML_EXPLICIT 00079 #endif 00080 00081 00082 /* 00083 TiXmlString is an emulation of a subset of the std::string template. 00084 Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. 00085 Only the member functions relevant to the TinyXML project have been implemented. 00086 The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase 00087 a string and there's no more room, we allocate a buffer twice as big as we need. 00088 */ 00089 class TiXmlString 00090 { 00091 public : 00092 // The size type used 00093 typedef size_t size_type; 00094 00095 // Error value for find primitive 00096 static const size_type npos; // = -1; 00097 00098 00099 // TiXmlString empty constructor 00100 TiXmlString () : rep_ (&nullrep_) 00101 { 00102 } 00103 00104 // TiXmlString copy constructor 00105 TiXmlString ( const TiXmlString ©) : rep_ (0) 00106 { 00107 init (copy.length() ); 00108 memcpy (start(), copy.data(), length() ); 00109 } 00110 00111 // TiXmlString constructor, based on a string 00112 TIXML_EXPLICIT TiXmlString ( const char *copy) : rep_ (0) 00113 { 00114 init ( static_cast<size_type> ( strlen (copy) ) ); 00115 memcpy (start(), copy, length() ); 00116 } 00117 00118 // TiXmlString constructor, based on a string 00119 TIXML_EXPLICIT TiXmlString ( const char *str, size_type len) : rep_ (0) 00120 { 00121 init (len); 00122 memcpy (start(), str, len); 00123 } 00124 00125 // TiXmlString destructor 00126 ~TiXmlString () 00127 { 00128 quit(); 00129 } 00130 00131 // = operator 00132 TiXmlString &operator = (const char *copy) 00133 { 00134 return assign ( copy, (size_type) strlen (copy) ); 00135 } 00136 00137 // = operator 00138 TiXmlString &operator = (const TiXmlString ©) 00139 { 00140 return assign (copy.start(), copy.length() ); 00141 } 00142 00143 00144 // += operator. Maps to append 00145 TiXmlString &operator += (const char *suffix) 00146 { 00147 return append (suffix, static_cast<size_type> ( strlen (suffix) ) ); 00148 } 00149 00150 // += operator. Maps to append 00151 TiXmlString &operator += (char single) 00152 { 00153 return append (&single, 1); 00154 } 00155 00156 // += operator. Maps to append 00157 TiXmlString &operator += (const TiXmlString &suffix) 00158 { 00159 return append (suffix.data(), suffix.length() ); 00160 } 00161 00162 00163 // Convert a TiXmlString into a null-terminated char * 00164 const char *c_str () const 00165 { 00166 return rep_->str; 00167 } 00168 00169 // Convert a TiXmlString into a char * (need not be null terminated). 00170 const char *data () const 00171 { 00172 return rep_->str; 00173 } 00174 00175 // Return the length of a TiXmlString 00176 size_type length () const 00177 { 00178 return rep_->size; 00179 } 00180 00181 // Alias for length() 00182 size_type size () const 00183 { 00184 return rep_->size; 00185 } 00186 00187 // Checks if a TiXmlString is empty 00188 bool empty () const 00189 { 00190 return rep_->size == 0; 00191 } 00192 00193 // Return capacity of string 00194 size_type capacity () const 00195 { 00196 return rep_->capacity; 00197 } 00198 00199 00200 // single char extraction 00201 const char &at (size_type index) const 00202 { 00203 assert ( index < length() ); 00204 return rep_->str[ index ]; 00205 } 00206 00207 // [] operator 00208 char &operator [] (size_type index) const 00209 { 00210 assert ( index < length() ); 00211 return rep_->str[ index ]; 00212 } 00213 00214 // find a char in a string. Return TiXmlString::npos if not found 00215 size_type find (char lookup) const 00216 { 00217 return find (lookup, 0); 00218 } 00219 00220 // find a char in a string from an offset. Return TiXmlString::npos if not found 00221 size_type find (char tofind, size_type offset) const 00222 { 00223 if (offset >= length() ) return npos; 00224 00225 for (const char *p = c_str() + offset; *p != '\0'; ++p) 00226 { 00227 if (*p == tofind) return static_cast< size_type > ( p - c_str() ); 00228 } 00229 00230 return npos; 00231 } 00232 00233 void clear () 00234 { 00235 //Lee: 00236 //The original was just too strange, though correct: 00237 // TiXmlString().swap(*this); 00238 //Instead use the quit & re-init: 00239 quit(); 00240 init (0, 0); 00241 } 00242 00243 /* Function to reserve a big amount of data when we know we'll need it. Be aware that this 00244 function DOES NOT clear the content of the TiXmlString if any exists. 00245 */ 00246 void reserve (size_type cap); 00247 00248 TiXmlString &assign (const char *str, size_type len); 00249 00250 TiXmlString &append (const char *str, size_type len); 00251 00252 void swap (TiXmlString &other) 00253 { 00254 Rep *r = rep_; 00255 rep_ = other.rep_; 00256 other.rep_ = r; 00257 } 00258 00259 private: 00260 00261 void init (size_type sz) 00262 { 00263 init (sz, sz); 00264 } 00265 void set_size (size_type sz) 00266 { 00267 rep_->str[ rep_->size = sz ] = '\0'; 00268 } 00269 char *start() const 00270 { 00271 return rep_->str; 00272 } 00273 char *finish() const 00274 { 00275 return rep_->str + rep_->size; 00276 } 00277 00278 struct Rep 00279 { 00280 size_type size, capacity; 00281 char str[1]; 00282 }; 00283 00284 void init (size_type sz, size_type cap) 00285 { 00286 if (cap) 00287 { 00288 // Lee: the original form: 00289 // rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap)); 00290 // doesn't work in some cases of new being overloaded. Switching 00291 // to the normal allocation, although use an 'int' for systems 00292 // that are overly picky about structure alignment. 00293 const size_type bytesNeeded = sizeof (Rep) + cap; 00294 const size_type intsNeeded = ( bytesNeeded + sizeof (int) - 1 ) / sizeof ( int ); 00295 rep_ = reinterpret_cast<Rep *> ( new int[ intsNeeded ] ); 00296 00297 rep_->str[ rep_->size = sz ] = '\0'; 00298 rep_->capacity = cap; 00299 } 00300 else 00301 { 00302 rep_ = &nullrep_; 00303 } 00304 } 00305 00306 void quit() 00307 { 00308 if (rep_ != &nullrep_) 00309 { 00310 // The rep_ is really an array of ints. (see the allocator, above). 00311 // Cast it back before delete, so the compiler won't incorrectly call destructors. 00312 delete [] ( reinterpret_cast<int *> ( rep_ ) ); 00313 } 00314 } 00315 00316 Rep *rep_; 00317 static Rep nullrep_; 00318 00319 } ; 00320 00321 00322 inline bool operator == (const TiXmlString &a, const TiXmlString &b) 00323 { 00324 return ( a.length() == b.length() ) // optimization on some platforms 00325 && ( strcmp (a.c_str(), b.c_str() ) == 0 ); // actual compare 00326 } 00327 inline bool operator < (const TiXmlString &a, const TiXmlString &b) 00328 { 00329 return strcmp (a.c_str(), b.c_str() ) < 0; 00330 } 00331 00332 inline bool operator != (const TiXmlString &a, const TiXmlString &b) 00333 { 00334 return ! (a == b); 00335 } 00336 inline bool operator > (const TiXmlString &a, const TiXmlString &b) 00337 { 00338 return b < a; 00339 } 00340 inline bool operator <= (const TiXmlString &a, const TiXmlString &b) 00341 { 00342 return ! (b < a); 00343 } 00344 inline bool operator >= (const TiXmlString &a, const TiXmlString &b) 00345 { 00346 return ! (a < b); 00347 } 00348 00349 inline bool operator == (const TiXmlString &a, const char *b) 00350 { 00351 return strcmp (a.c_str(), b) == 0; 00352 } 00353 inline bool operator == (const char *a, const TiXmlString &b) 00354 { 00355 return b == a; 00356 } 00357 inline bool operator != (const TiXmlString &a, const char *b) 00358 { 00359 return ! (a == b); 00360 } 00361 inline bool operator != (const char *a, const TiXmlString &b) 00362 { 00363 return ! (b == a); 00364 } 00365 00366 TiXmlString operator + (const TiXmlString &a, const TiXmlString &b); 00367 TiXmlString operator + (const TiXmlString &a, const char *b); 00368 TiXmlString operator + (const char *a, const TiXmlString &b); 00369 00370 00371 /* 00372 TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. 00373 Only the operators that we need for TinyXML have been developped. 00374 */ 00375 class TiXmlOutStream : public TiXmlString 00376 { 00377 public : 00378 00379 // TiXmlOutStream << operator. 00380 TiXmlOutStream &operator << (const TiXmlString &in) 00381 { 00382 *this += in; 00383 return *this; 00384 } 00385 00386 // TiXmlOutStream << operator. 00387 TiXmlOutStream &operator << (const char *in) 00388 { 00389 *this += in; 00390 return *this; 00391 } 00392 00393 } ; 00394 00395 #endif // TIXML_STRING_INCLUDED 00396 #endif // TIXML_USE_STL