Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

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

Generated for TinyXPath by doxygen SourceForge Logo