Yate

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