diff options
author | Mike Buland <eichlan@xagasoft.com> | 2007-04-03 03:49:53 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2007-04-03 03:49:53 +0000 |
commit | f4c20290509d7ed3a8fd5304577e7a4cc0b9d974 (patch) | |
tree | 13cdf64f7cf134f397a7165b7a3fe0807e37026b /src/old/xmlnode.cpp | |
parent | 74d4c8cd27334fc7204d5a8773deb3d424565778 (diff) | |
download | libbu++-f4c20290509d7ed3a8fd5304577e7a4cc0b9d974.tar.gz libbu++-f4c20290509d7ed3a8fd5304577e7a4cc0b9d974.tar.bz2 libbu++-f4c20290509d7ed3a8fd5304577e7a4cc0b9d974.tar.xz libbu++-f4c20290509d7ed3a8fd5304577e7a4cc0b9d974.zip |
Ok, no code is left in src, it's all in src/old. We'll gradually move code back
into src as it's fixed and re-org'd. This includes tests, which, I may write a
unit test system into libbu++ just to make my life easier.
Diffstat (limited to 'src/old/xmlnode.cpp')
-rw-r--r-- | src/old/xmlnode.cpp | 445 |
1 files changed, 445 insertions, 0 deletions
diff --git a/src/old/xmlnode.cpp b/src/old/xmlnode.cpp new file mode 100644 index 0000000..b1ed9a9 --- /dev/null +++ b/src/old/xmlnode.cpp | |||
@@ -0,0 +1,445 @@ | |||
1 | #include "xmlnode.h" | ||
2 | #include "hashfunctionstring.h" | ||
3 | |||
4 | XmlNode::XmlNode( const char *sName, XmlNode *pParent, const char *sContent ) : | ||
5 | hProperties( new HashFunctionString(), 53, false ), | ||
6 | hChildren( new HashFunctionString(), 53, true ) | ||
7 | { | ||
8 | this->pParent = pParent; | ||
9 | if( sName != NULL ) | ||
10 | { | ||
11 | setName( sName ); | ||
12 | } | ||
13 | if( sContent != NULL ) | ||
14 | { | ||
15 | this->sPreContent = new std::string( sContent ); | ||
16 | } | ||
17 | else | ||
18 | { | ||
19 | this->sPreContent = NULL; | ||
20 | } | ||
21 | nCurContent = 0; | ||
22 | } | ||
23 | |||
24 | XmlNode::~XmlNode() | ||
25 | { | ||
26 | for( int j = 0; j < lChildren.getSize(); j++ ) | ||
27 | { | ||
28 | delete (XmlNode *)lChildren[j]; | ||
29 | } | ||
30 | for( int j = 0; j < lPropNames.getSize(); j++ ) | ||
31 | { | ||
32 | delete (std::string *)lPropNames[j]; | ||
33 | } | ||
34 | for( int j = 0; j < lPropValues.getSize(); j++ ) | ||
35 | { | ||
36 | delete (std::string *)lPropValues[j]; | ||
37 | } | ||
38 | for( int j = 0; j < lPostContent.getSize(); j++ ) | ||
39 | { | ||
40 | if( lPostContent[j] != NULL ) | ||
41 | { | ||
42 | delete (std::string *)lPostContent[j]; | ||
43 | } | ||
44 | } | ||
45 | if( sPreContent ) | ||
46 | { | ||
47 | delete sPreContent; | ||
48 | } | ||
49 | } | ||
50 | |||
51 | void XmlNode::setName( const char *sName ) | ||
52 | { | ||
53 | if( pParent ) | ||
54 | { | ||
55 | if( this->sName.size() == 0 ) | ||
56 | { | ||
57 | // We're not in the hash yet, so add us | ||
58 | this->sName = sName; | ||
59 | pParent->hChildren.insert( this->sName.c_str(), this ); | ||
60 | } | ||
61 | else | ||
62 | { | ||
63 | // Slightly more tricky, delete us, then add us... | ||
64 | pParent->hChildren.del( this->sName.c_str() ); | ||
65 | this->sName = sName; | ||
66 | pParent->hChildren.insert( this->sName.c_str(), this ); | ||
67 | } | ||
68 | } | ||
69 | else | ||
70 | { | ||
71 | // If we have no parent, then just set the name string, we don't need | ||
72 | // to worry about hashing. | ||
73 | this->sName = sName; | ||
74 | } | ||
75 | } | ||
76 | |||
77 | void XmlNode::setContent( const char *sContent, int nIndex ) | ||
78 | { | ||
79 | if( nIndex == -1 ) | ||
80 | { | ||
81 | nIndex = nCurContent; | ||
82 | } | ||
83 | if( nIndex == 0 ) | ||
84 | { | ||
85 | if( this->sPreContent ) | ||
86 | { | ||
87 | delete this->sPreContent; | ||
88 | } | ||
89 | |||
90 | this->sPreContent = new std::string( sContent ); | ||
91 | } | ||
92 | else | ||
93 | { | ||
94 | nIndex--; | ||
95 | if( lPostContent[nIndex] ) | ||
96 | { | ||
97 | delete (std::string *)lPostContent[nIndex]; | ||
98 | } | ||
99 | |||
100 | lPostContent.setAt( nIndex, new std::string( sContent ) ); | ||
101 | } | ||
102 | } | ||
103 | |||
104 | const char *XmlNode::getContent( int nIndex ) | ||
105 | { | ||
106 | if( nIndex == 0 ) | ||
107 | { | ||
108 | if( sPreContent ) | ||
109 | { | ||
110 | return sPreContent->c_str(); | ||
111 | } | ||
112 | } | ||
113 | else | ||
114 | { | ||
115 | nIndex--; | ||
116 | if( lPostContent[nIndex] ) | ||
117 | { | ||
118 | return ((std::string *)lPostContent[nIndex])->c_str(); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | return NULL; | ||
123 | } | ||
124 | |||
125 | XmlNode *XmlNode::addChild( const char *sName, const char *sContent ) | ||
126 | { | ||
127 | return addChild( new XmlNode( sName, this, sContent ) ); | ||
128 | } | ||
129 | |||
130 | XmlNode *XmlNode::addChild( XmlNode *pNode ) | ||
131 | { | ||
132 | lChildren.append( pNode ); | ||
133 | lPostContent.append( NULL ); | ||
134 | nCurContent++; | ||
135 | pNode->pParent = this; | ||
136 | |||
137 | return pNode; | ||
138 | } | ||
139 | |||
140 | XmlNode *XmlNode::getParent() | ||
141 | { | ||
142 | return pParent; | ||
143 | } | ||
144 | |||
145 | void XmlNode::addProperty( const char *sName, const char *sValue ) | ||
146 | { | ||
147 | std::string *pName = new std::string( sName ); | ||
148 | std::string *pValue = new std::string( sValue ); | ||
149 | |||
150 | hProperties.insert( pName->c_str(), pValue->c_str() ); | ||
151 | lPropNames.append( pName ); | ||
152 | lPropValues.append( pValue ); | ||
153 | } | ||
154 | |||
155 | int XmlNode::getNumProperties() | ||
156 | { | ||
157 | return lPropNames.getSize(); | ||
158 | } | ||
159 | |||
160 | const char *XmlNode::getPropertyName( int nIndex ) | ||
161 | { | ||
162 | std::string *tmp = ((std::string *)lPropNames[nIndex]); | ||
163 | if( tmp == NULL ) | ||
164 | return NULL; | ||
165 | return tmp->c_str(); | ||
166 | } | ||
167 | |||
168 | const char *XmlNode::getProperty( int nIndex ) | ||
169 | { | ||
170 | std::string *tmp = ((std::string *)lPropValues[nIndex]); | ||
171 | if( tmp == NULL ) | ||
172 | return NULL; | ||
173 | return tmp->c_str(); | ||
174 | } | ||
175 | |||
176 | const char *XmlNode::getProperty( const char *sName ) | ||
177 | { | ||
178 | const char *tmp = (const char *)hProperties[sName]; | ||
179 | if( tmp == NULL ) | ||
180 | return NULL; | ||
181 | return tmp; | ||
182 | } | ||
183 | |||
184 | void XmlNode::deleteProperty( int nIndex ) | ||
185 | { | ||
186 | hProperties.del( ((std::string *)lPropNames[nIndex])->c_str() ); | ||
187 | |||
188 | delete (std::string *)lPropNames[nIndex]; | ||
189 | delete (std::string *)lPropValues[nIndex]; | ||
190 | |||
191 | lPropNames.deleteAt( nIndex ); | ||
192 | lPropValues.deleteAt( nIndex ); | ||
193 | } | ||
194 | |||
195 | bool XmlNode::hasChildren() | ||
196 | { | ||
197 | return lChildren.getSize()>0; | ||
198 | } | ||
199 | |||
200 | int XmlNode::getNumChildren() | ||
201 | { | ||
202 | return lChildren.getSize(); | ||
203 | } | ||
204 | |||
205 | XmlNode *XmlNode::getChild( int nIndex ) | ||
206 | { | ||
207 | return (XmlNode *)lChildren[nIndex]; | ||
208 | } | ||
209 | |||
210 | XmlNode *XmlNode::getChild( const char *sName, int nSkip ) | ||
211 | { | ||
212 | return (XmlNode *)hChildren.get( sName, nSkip ); | ||
213 | } | ||
214 | |||
215 | const char *XmlNode::getName() | ||
216 | { | ||
217 | return sName.c_str(); | ||
218 | } | ||
219 | |||
220 | void XmlNode::deleteNode( int nIndex, const char *sReplacementText ) | ||
221 | { | ||
222 | XmlNode *xRet = detatchNode( nIndex, sReplacementText ); | ||
223 | |||
224 | if( xRet != NULL ) | ||
225 | { | ||
226 | delete xRet; | ||
227 | } | ||
228 | } | ||
229 | |||
230 | XmlNode *XmlNode::detatchNode( int nIndex, const char *sReplacementText ) | ||
231 | { | ||
232 | if( nIndex < 0 || nIndex >= lChildren.getSize() ) | ||
233 | return NULL; | ||
234 | |||
235 | // The real trick when deleteing a node isn't actually deleting it, it's | ||
236 | // reforming the content around the node that's now missing...hmmm... | ||
237 | |||
238 | if( nIndex == 0 ) | ||
239 | { | ||
240 | // If the index is zero we have to deal with the pre-content | ||
241 | if( sReplacementText ) | ||
242 | { | ||
243 | if( sPreContent == NULL ) | ||
244 | { | ||
245 | sPreContent = new std::string( sReplacementText ); | ||
246 | } | ||
247 | else | ||
248 | { | ||
249 | *sPreContent += sReplacementText; | ||
250 | } | ||
251 | } | ||
252 | if( lPostContent.getSize() > 0 ) | ||
253 | { | ||
254 | if( lPostContent[0] != NULL ) | ||
255 | { | ||
256 | if( sPreContent == NULL ) | ||
257 | { | ||
258 | sPreContent = new std::string( | ||
259 | ((std::string *)lPostContent[0])->c_str() | ||
260 | ); | ||
261 | } | ||
262 | else | ||
263 | { | ||
264 | *sPreContent += | ||
265 | ((std::string *)lPostContent[0])->c_str(); | ||
266 | } | ||
267 | } | ||
268 | delete (std::string *)lPostContent[0]; | ||
269 | lPostContent.deleteAt( 0 ); | ||
270 | } | ||
271 | } | ||
272 | else | ||
273 | { | ||
274 | int nCont = nIndex-1; | ||
275 | // If it's above zero we deal with the post-content only | ||
276 | if( sReplacementText ) | ||
277 | { | ||
278 | if( lPostContent[nCont] == NULL ) | ||
279 | { | ||
280 | lPostContent.setAt( nCont, new std::string( sReplacementText ) ); | ||
281 | } | ||
282 | else | ||
283 | { | ||
284 | *((std::string *)lPostContent[nCont]) += sReplacementText; | ||
285 | } | ||
286 | } | ||
287 | if( lPostContent.getSize() > nIndex ) | ||
288 | { | ||
289 | if( lPostContent[nIndex] != NULL ) | ||
290 | { | ||
291 | if( lPostContent[nCont] == NULL ) | ||
292 | { | ||
293 | lPostContent.setAt( nCont, new std::string( | ||
294 | ((std::string *)lPostContent[nIndex])->c_str() | ||
295 | ) ); | ||
296 | } | ||
297 | else | ||
298 | { | ||
299 | *((std::string *)lPostContent[nCont]) += | ||
300 | ((std::string *)lPostContent[nIndex])->c_str(); | ||
301 | } | ||
302 | } | ||
303 | delete (std::string *)lPostContent[nIndex]; | ||
304 | lPostContent.deleteAt( nIndex ); | ||
305 | } | ||
306 | } | ||
307 | |||
308 | XmlNode *xRet = (XmlNode *)lChildren[nIndex]; | ||
309 | hChildren.del( ((XmlNode *)lChildren[nIndex])->getName() ); | ||
310 | lChildren.deleteAt( nIndex ); | ||
311 | |||
312 | return xRet; | ||
313 | } | ||
314 | |||
315 | void XmlNode::replaceNode( int nIndex, XmlNode *pNewNode ) | ||
316 | { | ||
317 | if( nIndex < 0 || nIndex >= lChildren.getSize() ) | ||
318 | return; //TODO: throw an exception | ||
319 | |||
320 | delete (XmlNode *)lChildren[nIndex]; | ||
321 | lChildren.setAt( nIndex, pNewNode ); | ||
322 | pNewNode->pParent = this; | ||
323 | } | ||
324 | |||
325 | XmlNode *XmlNode::getCopy() | ||
326 | { | ||
327 | XmlNode *pNew = new XmlNode(); | ||
328 | |||
329 | pNew->sName = sName; | ||
330 | if( sPreContent ) | ||
331 | { | ||
332 | pNew->sPreContent = new std::string( sPreContent->c_str() ); | ||
333 | } | ||
334 | else | ||
335 | { | ||
336 | pNew->sPreContent = NULL; | ||
337 | } | ||
338 | pNew->nCurContent = 0; | ||
339 | |||
340 | int nSize = lPostContent.getSize(); | ||
341 | pNew->lPostContent.setSize( nSize ); | ||
342 | for( int j = 0; j < nSize; j++ ) | ||
343 | { | ||
344 | if( lPostContent[j] ) | ||
345 | { | ||
346 | pNew->lPostContent.setAt( | ||
347 | j, new std::string( | ||
348 | ((std::string *)lPostContent[j])->c_str() | ||
349 | ) | ||
350 | ); | ||
351 | } | ||
352 | else | ||
353 | { | ||
354 | pNew->lPostContent.setAt( j, NULL ); | ||
355 | } | ||
356 | } | ||
357 | |||
358 | nSize = lChildren.getSize(); | ||
359 | pNew->lChildren.setSize( nSize ); | ||
360 | for( int j = 0; j < nSize; j++ ) | ||
361 | { | ||
362 | XmlNode *pChild = ((XmlNode *)lChildren[j])->getCopy(); | ||
363 | pNew->lChildren.setAt( j, pChild ); | ||
364 | pChild->pParent = pNew; | ||
365 | pNew->hChildren.insert( pChild->getName(), pChild ); | ||
366 | } | ||
367 | |||
368 | nSize = lPropNames.getSize(); | ||
369 | pNew->lPropNames.setSize( nSize ); | ||
370 | pNew->lPropValues.setSize( nSize ); | ||
371 | for( int j = 0; j < nSize; j++ ) | ||
372 | { | ||
373 | std::string *pProp = new std::string( ((std::string *)lPropNames[j])->c_str() ); | ||
374 | std::string *pVal = new std::string( ((std::string *)lPropValues[j])->c_str() ); | ||
375 | pNew->lPropNames.setAt( j, pProp ); | ||
376 | pNew->lPropValues.setAt( j, pVal ); | ||
377 | pNew->hProperties.insert( pProp->c_str(), pVal->c_str() ); | ||
378 | pNew->nCurContent++; | ||
379 | } | ||
380 | |||
381 | return pNew; | ||
382 | } | ||
383 | |||
384 | void XmlNode::deleteNodeKeepChildren( int nIndex ) | ||
385 | { | ||
386 | // This is a tricky one...we need to do some patching to keep things all | ||
387 | // even... | ||
388 | XmlNode *xRet = (XmlNode *)lChildren[nIndex]; | ||
389 | |||
390 | if( xRet == NULL ) | ||
391 | { | ||
392 | return; | ||
393 | } | ||
394 | else | ||
395 | { | ||
396 | if( getContent( nIndex ) ) | ||
397 | { | ||
398 | std::string sBuf( getContent( nIndex ) ); | ||
399 | sBuf += xRet->getContent( 0 ); | ||
400 | setContent( sBuf.c_str(), nIndex ); | ||
401 | } | ||
402 | else | ||
403 | { | ||
404 | setContent( xRet->getContent( 0 ), nIndex ); | ||
405 | } | ||
406 | |||
407 | int nSize = xRet->lChildren.getSize(); | ||
408 | for( int j = 0; j < nSize; j++ ) | ||
409 | { | ||
410 | XmlNode *pCopy = ((XmlNode *)xRet->lChildren[j])->getCopy(); | ||
411 | pCopy->pParent = this; | ||
412 | lChildren.insertBefore( pCopy, nIndex+j ); | ||
413 | |||
414 | if( xRet->lPostContent[j] ) | ||
415 | { | ||
416 | lPostContent.insertBefore( | ||
417 | new std::string( ((std::string *)xRet->lPostContent[j])->c_str() ), | ||
418 | nIndex+j | ||
419 | ); | ||
420 | } | ||
421 | else | ||
422 | { | ||
423 | lPostContent.insertBefore( NULL, nIndex+j ); | ||
424 | } | ||
425 | } | ||
426 | |||
427 | if( getContent( nIndex+nSize ) ) | ||
428 | { | ||
429 | //SString sBuf( getContent( nIndex+nSize ) ); | ||
430 | //sBuf.catfrom( xRet->getContent( nSize ) ); | ||
431 | //setContent( sBuf, nIndex+nSize ); | ||
432 | } | ||
433 | else | ||
434 | { | ||
435 | setContent( xRet->getContent( nSize ), nIndex+nSize ); | ||
436 | } | ||
437 | |||
438 | deleteNode( nIndex+nSize ); | ||
439 | } | ||
440 | } | ||
441 | |||
442 | void XmlNode::replaceNodeWithChildren( int nIndex, XmlNode *pNewNode ) | ||
443 | { | ||
444 | } | ||
445 | |||