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