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