Main Page | Class Hierarchy | Class List | File List | Class Members

tinystr.h

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

Generated on Sat Oct 8 14:15:30 2005 for TinyXml by  doxygen 1.4.4