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 #include "tinyxml.h"
26
27 #ifndef TIXML_USE_STL
28
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <ctype.h>
33
34 #include "TinyStr.h"
35
36 // TiXmlString constructor, based on a C string
TiXmlString(const char * instring)37 TiXmlString::TiXmlString (const char* instring)
38 {
39 unsigned newlen;
40 char * newstring;
41
42 if (!instring)
43 {
44 allocated = 0;
45 cstring = NULL;
46 current_length = 0;
47 return;
48 }
49 newlen = strlen (instring) + 1;
50 newstring = new char [newlen];
51 memcpy (newstring, instring, newlen);
52 // strcpy (newstring, instring);
53 allocated = newlen;
54 cstring = newstring;
55 current_length = newlen - 1;
56 }
57
58 // TiXmlString copy constructor
TiXmlString(const TiXmlString & copy)59 TiXmlString::TiXmlString (const TiXmlString& copy)
60 {
61 unsigned newlen;
62 char * newstring;
63
64 // Prevent copy to self!
65 if ( © == this )
66 return;
67
68 if (! copy . allocated)
69 {
70 allocated = 0;
71 cstring = NULL;
72 current_length = 0;
73 return;
74 }
75 newlen = copy . length () + 1;
76 newstring = new char [newlen];
77 // strcpy (newstring, copy . cstring);
78 memcpy (newstring, copy . cstring, newlen);
79 allocated = newlen;
80 cstring = newstring;
81 current_length = newlen - 1;
82 }
83
84 // TiXmlString = operator. Safe when assign own content
operator =(const char * content)85 void TiXmlString ::operator = (const char * content)
86 {
87 unsigned newlen;
88 char * newstring;
89
90 if (! content)
91 {
92 empty_it ();
93 return;
94 }
95 newlen = strlen (content) + 1;
96 newstring = new char [newlen];
97 // strcpy (newstring, content);
98 memcpy (newstring, content, newlen);
99 empty_it ();
100 allocated = newlen;
101 cstring = newstring;
102 current_length = newlen - 1;
103 }
104
105 // = operator. Safe when assign own content
operator =(const TiXmlString & copy)106 void TiXmlString ::operator = (const TiXmlString & copy)
107 {
108 unsigned newlen;
109 char * newstring;
110
111 if (! copy . length ())
112 {
113 empty_it ();
114 return;
115 }
116 newlen = copy . length () + 1;
117 newstring = new char [newlen];
118 // strcpy (newstring, copy . c_str ());
119 memcpy (newstring, copy . c_str (), newlen);
120 empty_it ();
121 allocated = newlen;
122 cstring = newstring;
123 current_length = newlen - 1;
124 }
125
126
127 // append a const char * to an existing TiXmlString
append(const char * str,int len)128 void TiXmlString::append( const char* str, int len )
129 {
130 char * new_string;
131 unsigned new_alloc, new_size, size_suffix;
132
133 // don't use strlen - it can overrun the len passed in!
134 const char* p = str;
135 size_suffix = 0;
136
137 while ( *p && size_suffix < (unsigned)len )
138 {
139 ++p;
140 ++size_suffix;
141 }
142 if ( !size_suffix)
143 return;
144
145 new_size = length () + size_suffix + 1;
146 // check if we need to expand
147 if (new_size > allocated)
148 {
149 // compute new size
150 new_alloc = assign_new_size (new_size);
151
152 // allocate new buffer
153 new_string = new char [new_alloc];
154 new_string [0] = 0;
155
156 // copy the previous allocated buffer into this one
157 if (allocated && cstring)
158 // strcpy (new_string, cstring);
159 memcpy (new_string, cstring, length ());
160
161 // append the suffix. It does exist, otherwize we wouldn't be expanding
162 // strncat (new_string, str, len);
163 memcpy (new_string + length (),
164 str,
165 size_suffix);
166
167 // return previsously allocated buffer if any
168 if (allocated && cstring)
169 delete [] cstring;
170
171 // update member variables
172 cstring = new_string;
173 allocated = new_alloc;
174 }
175 else
176 {
177 // we know we can safely append the new string
178 // strncat (cstring, str, len);
179 memcpy (cstring + length (),
180 str,
181 size_suffix);
182 }
183 current_length = new_size - 1;
184 cstring [current_length] = 0;
185 }
186
187
188 // append a const char * to an existing TiXmlString
append(const char * suffix)189 void TiXmlString::append( const char * suffix )
190 {
191 char * new_string;
192 unsigned new_alloc, new_size;
193
194 new_size = length () + strlen (suffix) + 1;
195 // check if we need to expand
196 if (new_size > allocated)
197 {
198 // compute new size
199 new_alloc = assign_new_size (new_size);
200
201 // allocate new buffer
202 new_string = new char [new_alloc];
203 new_string [0] = 0;
204
205 // copy the previous allocated buffer into this one
206 if (allocated && cstring)
207 memcpy (new_string, cstring, 1 + length ());
208 // strcpy (new_string, cstring);
209
210 // append the suffix. It does exist, otherwize we wouldn't be expanding
211 // strcat (new_string, suffix);
212 memcpy (new_string + length (),
213 suffix,
214 strlen (suffix) + 1);
215
216 // return previsously allocated buffer if any
217 if (allocated && cstring)
218 delete [] cstring;
219
220 // update member variables
221 cstring = new_string;
222 allocated = new_alloc;
223 }
224 else
225 {
226 // we know we can safely append the new string
227 // strcat (cstring, suffix);
228 memcpy (cstring + length (),
229 suffix,
230 strlen (suffix) + 1);
231 }
232 current_length = new_size - 1;
233 }
234
235 // Check for TiXmlString equuivalence
236 //bool TiXmlString::operator == (const TiXmlString & compare) const
237 //{
238 // return (! strcmp (c_str (), compare . c_str ()));
239 //}
240
241 //unsigned TiXmlString::length () const
242 //{
243 // if (allocated)
244 // // return strlen (cstring);
245 // return current_length;
246 // return 0;
247 //}
248
249
find(char tofind,unsigned offset) const250 unsigned TiXmlString::find (char tofind, unsigned offset) const
251 {
252 char * lookup;
253
254 if (offset >= length ())
255 return (unsigned) notfound;
256 for (lookup = cstring + offset; * lookup; lookup++)
257 if (* lookup == tofind)
258 return lookup - cstring;
259 return (unsigned) notfound;
260 }
261
262
operator ==(const TiXmlString & compare) const263 bool TiXmlString::operator == (const TiXmlString & compare) const
264 {
265 if ( allocated && compare.allocated )
266 {
267 assert( cstring );
268 assert( compare.cstring );
269 return ( strcmp( cstring, compare.cstring ) == 0 );
270 }
271 return false;
272 }
273
274
operator <(const TiXmlString & compare) const275 bool TiXmlString::operator < (const TiXmlString & compare) const
276 {
277 if ( allocated && compare.allocated )
278 {
279 assert( cstring );
280 assert( compare.cstring );
281 return ( strcmp( cstring, compare.cstring ) > 0 );
282 }
283 return false;
284 }
285
286
operator >(const TiXmlString & compare) const287 bool TiXmlString::operator > (const TiXmlString & compare) const
288 {
289 if ( allocated && compare.allocated )
290 {
291 assert( cstring );
292 assert( compare.cstring );
293 return ( strcmp( cstring, compare.cstring ) < 0 );
294 }
295 return false;
296 }
297
298
299 #endif // TIXML_USE_STL
300