summaryrefslogtreecommitdiff
path: root/src/xmlnode.cpp
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2006-05-01 17:11:04 +0000
committerMike Buland <eichlan@xagasoft.com>2006-05-01 17:11:04 +0000
commitf7a9549bd6ad83f2e0bceec9cddacfa5e3f84a54 (patch)
tree53cec4864776e07950e3c72f2a990a1017d08045 /src/xmlnode.cpp
downloadlibbu++-f7a9549bd6ad83f2e0bceec9cddacfa5e3f84a54.tar.gz
libbu++-f7a9549bd6ad83f2e0bceec9cddacfa5e3f84a54.tar.bz2
libbu++-f7a9549bd6ad83f2e0bceec9cddacfa5e3f84a54.tar.xz
libbu++-f7a9549bd6ad83f2e0bceec9cddacfa5e3f84a54.zip
libbu++ is finally laid out the way it should be, trunk, branches, and tags.
Diffstat (limited to 'src/xmlnode.cpp')
-rw-r--r--src/xmlnode.cpp454
1 files changed, 454 insertions, 0 deletions
diff --git a/src/xmlnode.cpp b/src/xmlnode.cpp
new file mode 100644
index 0000000..e5c77e2
--- /dev/null
+++ b/src/xmlnode.cpp
@@ -0,0 +1,454 @@
1#include "xmlnode.h"
2#include "hashfunctionstring.h"
3
4XmlNode::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
24XmlNode::~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
51void 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
77void 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
104const 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
125XmlNode *XmlNode::addChild( const char *sName, const char *sContent )
126{
127 return addChild( new XmlNode( sName, this, sContent ) );
128}
129
130XmlNode *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
140XmlNode *XmlNode::getParent()
141{
142 return pParent;
143}
144
145void 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
155int XmlNode::getNumProperties()
156{
157 return lPropNames.getSize();
158}
159
160const 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
168const 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
176const 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
184bool 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
195bool XmlNode::hasChildren()
196{
197 return lChildren.getSize()>0;
198}
199
200int XmlNode::getNumChildren()
201{
202 return lChildren.getSize();
203}
204
205XmlNode *XmlNode::getChild( int nIndex )
206{
207 return (XmlNode *)lChildren[nIndex];
208}
209
210XmlNode *XmlNode::getChild( const char *sName, int nSkip )
211{
212 return (XmlNode *)hChildren.get( sName, nSkip );
213}
214
215const char *XmlNode::getName()
216{
217 return sName.c_str();
218}
219
220bool XmlNode::deleteNode( int nIndex, const char *sReplacementText )
221{
222 XmlNode *xRet = detatchNode( nIndex, sReplacementText );
223
224 if( xRet == NULL )
225 {
226 return false;
227 }
228 else
229 {
230 delete xRet;
231 return true;
232 }
233}
234
235XmlNode *XmlNode::detatchNode( int nIndex, const char *sReplacementText )
236{
237 if( nIndex < 0 || nIndex >= lChildren.getSize() )
238 return NULL;
239
240 // The real trick when deleteing a node isn't actually deleting it, it's
241 // reforming the content around the node that's now missing...hmmm...
242
243 if( nIndex == 0 )
244 {
245 // If the index is zero we have to deal with the pre-content
246 if( sReplacementText )
247 {
248 if( sPreContent == NULL )
249 {
250 sPreContent = new std::string( sReplacementText );
251 }
252 else
253 {
254 *sPreContent += sReplacementText;
255 }
256 }
257 if( lPostContent.getSize() > 0 )
258 {
259 if( lPostContent[0] != NULL )
260 {
261 if( sPreContent == NULL )
262 {
263 sPreContent = new std::string(
264 ((std::string *)lPostContent[0])->c_str()
265 );
266 }
267 else
268 {
269 *sPreContent +=
270 ((std::string *)lPostContent[0])->c_str();
271 }
272 }
273 delete (std::string *)lPostContent[0];
274 lPostContent.deleteAt( 0 );
275 }
276 }
277 else
278 {
279 int nCont = nIndex-1;
280 // If it's above zero we deal with the post-content only
281 if( sReplacementText )
282 {
283 if( lPostContent[nCont] == NULL )
284 {
285 lPostContent.setAt( nCont, new std::string( sReplacementText ) );
286 }
287 else
288 {
289 *((std::string *)lPostContent[nCont]) += sReplacementText;
290 }
291 }
292 if( lPostContent.getSize() > nIndex )
293 {
294 if( lPostContent[nIndex] != NULL )
295 {
296 if( lPostContent[nCont] == NULL )
297 {
298 lPostContent.setAt( nCont, new std::string(
299 ((std::string *)lPostContent[nIndex])->c_str()
300 ) );
301 }
302 else
303 {
304 *((std::string *)lPostContent[nCont]) +=
305 ((std::string *)lPostContent[nIndex])->c_str();
306 }
307 }
308 delete (std::string *)lPostContent[nIndex];
309 lPostContent.deleteAt( nIndex );
310 }
311 }
312
313 XmlNode *xRet = (XmlNode *)lChildren[nIndex];
314 hChildren.del( ((XmlNode *)lChildren[nIndex])->getName() );
315 lChildren.deleteAt( nIndex );
316
317 return xRet;
318}
319
320bool XmlNode::replaceNode( int nIndex, XmlNode *pNewNode )
321{
322 if( nIndex < 0 || nIndex >= lChildren.getSize() )
323 return false;
324
325 delete (XmlNode *)lChildren[nIndex];
326 lChildren.setAt( nIndex, pNewNode );
327 pNewNode->pParent = this;
328
329 return true;
330}
331
332XmlNode *XmlNode::getCopy()
333{
334 XmlNode *pNew = new XmlNode();
335
336 pNew->sName = sName;
337 if( sPreContent )
338 {
339 pNew->sPreContent = new std::string( sPreContent->c_str() );
340 }
341 else
342 {
343 pNew->sPreContent = NULL;
344 }
345 pNew->nCurContent = 0;
346
347 int nSize = lPostContent.getSize();
348 pNew->lPostContent.setSize( nSize );
349 for( int j = 0; j < nSize; j++ )
350 {
351 if( lPostContent[j] )
352 {
353 pNew->lPostContent.setAt(
354 j, new std::string(
355 ((std::string *)lPostContent[j])->c_str()
356 )
357 );
358 }
359 else
360 {
361 pNew->lPostContent.setAt( j, NULL );
362 }
363 }
364
365 nSize = lChildren.getSize();
366 pNew->lChildren.setSize( nSize );
367 for( int j = 0; j < nSize; j++ )
368 {
369 XmlNode *pChild = ((XmlNode *)lChildren[j])->getCopy();
370 pNew->lChildren.setAt( j, pChild );
371 pChild->pParent = this;
372 hChildren.insert( pChild->getName(), pChild );
373 }
374
375 nSize = lPropNames.getSize();
376 pNew->lPropNames.setSize( nSize );
377 pNew->lPropValues.setSize( nSize );
378 for( int j = 0; j < nSize; j++ )
379 {
380 std::string *pProp = new std::string( ((std::string *)lPropNames[j])->c_str() );
381 std::string *pVal = new std::string( ((std::string *)lPropValues[j])->c_str() );
382 pNew->lPropNames.setAt( j, pProp );
383 pNew->lPropValues.setAt( j, pVal );
384 pNew->hProperties.insert( pProp->c_str(), pVal->c_str() );
385 pNew->nCurContent++;
386 }
387
388 return pNew;
389}
390
391bool XmlNode::deleteNodeKeepChildren( int nIndex )
392{
393 // This is a tricky one...we need to do some patching to keep things all
394 // even...
395 XmlNode *xRet = (XmlNode *)lChildren[nIndex];
396
397 if( xRet == NULL )
398 {
399 return false;
400 }
401 else
402 {
403 if( getContent( nIndex ) )
404 {
405 std::string sBuf( getContent( nIndex ) );
406 sBuf += xRet->getContent( 0 );
407 setContent( sBuf.c_str(), nIndex );
408 }
409 else
410 {
411 setContent( xRet->getContent( 0 ), nIndex );
412 }
413
414 int nSize = xRet->lChildren.getSize();
415 for( int j = 0; j < nSize; j++ )
416 {
417 XmlNode *pCopy = ((XmlNode *)xRet->lChildren[j])->getCopy();
418 pCopy->pParent = this;
419 lChildren.insertBefore( pCopy, nIndex+j );
420
421 if( xRet->lPostContent[j] )
422 {
423 lPostContent.insertBefore(
424 new std::string( ((std::string *)xRet->lPostContent[j])->c_str() ),
425 nIndex+j
426 );
427 }
428 else
429 {
430 lPostContent.insertBefore( NULL, nIndex+j );
431 }
432 }
433
434 if( getContent( nIndex+nSize ) )
435 {
436 //SString sBuf( getContent( nIndex+nSize ) );
437 //sBuf.catfrom( xRet->getContent( nSize ) );
438 //setContent( sBuf, nIndex+nSize );
439 }
440 else
441 {
442 setContent( xRet->getContent( nSize ), nIndex+nSize );
443 }
444
445 deleteNode( nIndex+nSize );
446 return true;
447 }
448
449}
450
451bool XmlNode::replaceNodeWithChildren( int nIndex, XmlNode *pNewNode )
452{
453}
454