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