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 ©) : 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 ©)
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