aboutsummaryrefslogtreecommitdiff
path: root/src/old
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2007-05-09 15:04:31 +0000
committerMike Buland <eichlan@xagasoft.com>2007-05-09 15:04:31 +0000
commitad92dc50b7cdf7cfe086f21d19442d03a90fd05d (patch)
tree9ca6f7bde704cb44276a05b6e83f36754e07f732 /src/old
parent2e035fee36768e3c765b7f5dc10bf0a3b7d2448b (diff)
downloadlibbu++-ad92dc50b7cdf7cfe086f21d19442d03a90fd05d.tar.gz
libbu++-ad92dc50b7cdf7cfe086f21d19442d03a90fd05d.tar.bz2
libbu++-ad92dc50b7cdf7cfe086f21d19442d03a90fd05d.tar.xz
libbu++-ad92dc50b7cdf7cfe086f21d19442d03a90fd05d.zip
Just a few things re-arranged, moved the new taf/xml systems to the inprogress
directory, and moved the old xml system in, so it will require heavy changes.
Diffstat (limited to 'src/old')
-rw-r--r--src/old/xmldocument.cpp149
-rw-r--r--src/old/xmldocument.h171
-rw-r--r--src/old/xmlnode.cpp445
-rw-r--r--src/old/xmlnode.h236
-rw-r--r--src/old/xmlreader.cpp602
-rw-r--r--src/old/xmlreader.h141
-rw-r--r--src/old/xmlwriter.cpp173
-rw-r--r--src/old/xmlwriter.h96
8 files changed, 0 insertions, 2013 deletions
diff --git a/src/old/xmldocument.cpp b/src/old/xmldocument.cpp
deleted file mode 100644
index d7867d5..0000000
--- a/src/old/xmldocument.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include "xmlwriter.h"
4
5XmlDocument::XmlDocument( XmlNode *pRoot )
6{
7 this->pRoot = pRoot;
8 pCurrent = NULL;
9 bCompleted = (pRoot!=NULL);
10}
11
12XmlDocument::~XmlDocument()
13{
14 if( pRoot )
15 {
16 delete pRoot;
17 }
18}
19
20void XmlDocument::addNode( const char *sName, const char *sContent, bool bClose )
21{
22 if( pRoot == NULL )
23 {
24 // This is the first node, so ignore position and just insert it.
25 pCurrent = pRoot = new XmlNode( sName, NULL, sContent );
26 }
27 else
28 {
29 pCurrent = pCurrent->addChild( sName, sContent );
30 }
31
32 if( bClose )
33 {
34 closeNode();
35 }
36}
37
38void XmlDocument::setName( const char *sName )
39{
40 pCurrent->setName( sName );
41}
42
43bool XmlDocument::isCompleted()
44{
45 return bCompleted;
46}
47
48XmlNode *XmlDocument::getRoot()
49{
50 return pRoot;
51}
52
53XmlNode *XmlDocument::detatchRoot()
54{
55 XmlNode *pTemp = pRoot;
56 pRoot = NULL;
57 return pTemp;
58}
59
60XmlNode *XmlDocument::getCurrent()
61{
62 return pCurrent;
63}
64
65void XmlDocument::closeNode()
66{
67 if( pCurrent != NULL )
68 {
69 pCurrent = pCurrent->getParent();
70
71 if( pCurrent == NULL )
72 {
73 bCompleted = true;
74 }
75 }
76}
77
78void XmlDocument::addProperty( const char *sName, const char *sValue )
79{
80 if( pCurrent )
81 {
82 pCurrent->addProperty( sName, sValue );
83 }
84}
85
86void XmlDocument::addProperty( const char *sName, const unsigned char nValue )
87{
88 char buf[12];
89 sprintf( buf, "%hhi", nValue );
90 addProperty( sName, buf );
91}
92
93void XmlDocument::addProperty( const char *sName, const char nValue )
94{
95 char buf[12];
96 sprintf( buf, "%hhi", nValue );
97 addProperty( sName, buf );
98}
99
100void XmlDocument::addProperty( const char *sName, const unsigned short nValue )
101{
102 char buf[12];
103 sprintf( buf, "%hi", nValue );
104 addProperty( sName, buf );
105}
106
107void XmlDocument::addProperty( const char *sName, const short nValue )
108{
109 char buf[12];
110 sprintf( buf, "%hi", nValue );
111 addProperty( sName, buf );
112}
113
114void XmlDocument::addProperty( const char *sName, const int nValue )
115{
116 char buf[12];
117 sprintf( buf, "%d", nValue );
118 addProperty( sName, buf );
119}
120
121void XmlDocument::addProperty( const char *sName, const unsigned long nValue )
122{
123 char buf[12];
124 sprintf( buf, "%li", nValue );
125 addProperty( sName, buf );
126}
127
128void XmlDocument::addProperty( const char *sName, const long nValue )
129{
130 char buf[12];
131 sprintf( buf, "%li", nValue );
132 addProperty( sName, buf );
133}
134
135void XmlDocument::addProperty( const char *sName, const double dValue )
136{
137 char buf[40];
138 sprintf( buf, "%f", dValue );
139 addProperty( sName, buf );
140}
141
142void XmlDocument::setContent( const char *sContent )
143{
144 if( pCurrent )
145 {
146 pCurrent->setContent( sContent );
147 }
148}
149
diff --git a/src/old/xmldocument.h b/src/old/xmldocument.h
deleted file mode 100644
index 6671c41..0000000
--- a/src/old/xmldocument.h
+++ /dev/null
@@ -1,171 +0,0 @@
1#ifndef XMLDOCUMENT
2#define XMLDOCUMENT
3
4#include "xmlnode.h"
5
6/**
7 * Keeps track of an easily managed set of XmlNode information. Allows simple
8 * operations for logical writing to and reading from XML structures. Using
9 * already formed structures is simply done through the XmlNode structures,
10 * and the getRoot function here. Creation is performed through a simple set
11 * of operations that creates the data in a stream type format.
12 *@author Mike Buland
13 */
14class XmlDocument
15{
16public:
17 /**
18 * Construct either a blank XmlDocuemnt or construct a document around an
19 * existing XmlNode. Be careful, once an XmlNode is passed into a document
20 * the document takes over ownership and will delete it when the XmlDocument
21 * is deleted.
22 *@param pRoot The XmlNode to use as the root of this document, or NULL if
23 * you want to start a new document.
24 */
25 XmlDocument( XmlNode *pRoot=NULL );
26
27 /**
28 * Destroy all contained nodes.
29 */
30 virtual ~XmlDocument();
31
32 /**
33 * Add a new node to the document. The new node is appended to the end of
34 * the current context, i.e. XmlNode, and the new node, provided it isn't
35 * close as part of this operation, will become the current context.
36 *@param sName The name of the new node to add.
37 *@param sContent A content string to be placed inside of the new node.
38 *@param bClose Set this to true to close the node immediately after adding
39 * the node and setting the content and name. If this is set to true the
40 * node is appended, but the context node doesn't change.
41 */
42 void addNode( const char *sName=NULL, const char *sContent=NULL, bool bClose=false );
43
44 /**
45 * Set the name of the current node context.
46 *@param sName The new name of the node.
47 */
48 void setName( const char *sName );
49
50 /**
51 * Close the current node context. This will move the current context to
52 * the parent node of the former current node. If the current node was the
53 * root then the "completed" flag is set and no more operations are allowed.
54 */
55 void closeNode();
56
57 /**
58 * Change the content of the current node at the current position between
59 * nodes.
60 *@param sContent The new content of the current node.
61 */
62 void setContent( const char *sContent );
63
64 /**
65 * Add a named property to the current context node.
66 *@param sName The name of the property to add.
67 *@param sValue The string value of the property.
68 */
69 void addProperty( const char *sName, const char *sValue );
70
71 /**
72 * Add a named property to the current context node, converting the
73 * numerical parameter to text using standrd printf style conversion.
74 *@param sName The name of the property to add.
75 *@param nValue The numerical value to add.
76 */
77 void addProperty( const char *sName, const unsigned char nValue );
78
79 /**
80 * Add a named property to the current context node, converting the
81 * numerical parameter to text using standrd printf style conversion.
82 *@param sName The name of the property to add.
83 *@param nValue The numerical value to add.
84 */
85 void addProperty( const char *sName, const char nValue );
86
87 /**
88 * Add a named property to the current context node, converting the
89 * numerical parameter to text using standrd printf style conversion.
90 *@param sName The name of the property to add.
91 *@param nValue The numerical value to add.
92 */
93 void addProperty( const char *sName, const unsigned short nValue );
94
95 /**
96 * Add a named property to the current context node, converting the
97 * numerical parameter to text using standrd printf style conversion.
98 *@param sName The name of the property to add.
99 *@param nValue The numerical value to add.
100 */
101 void addProperty( const char *sName, const short nValue );
102
103 /**
104 * Add a named property to the current context node, converting the
105 * numerical parameter to text using standrd printf style conversion.
106 *@param sName The name of the property to add.
107 *@param nValue The numerical value to add.
108 */
109 void addProperty( const char *sName, const unsigned long nValue );
110
111 /**
112 * Add a named property to the current context node, converting the
113 * numerical parameter to text using standrd printf style conversion.
114 *@param sName The name of the property to add.
115 *@param nValue The numerical value to add.
116 */
117 void addProperty( const char *sName, const long nValue );
118
119 /**
120 * Add a named property to the current context node, converting the
121 * numerical parameter to text using standrd printf style conversion.
122 *@param sName The name of the property to add.
123 *@param nValue The numerical value to add.
124 */
125 void addProperty( const char *sName, const int nValue );
126
127 /**
128 * Add a named property to the current context node, converting the
129 * numerical parameter to text using standrd printf style conversion.
130 *@param sName The name of the property to add.
131 *@param dValue The numerical value to add.
132 */
133 void addProperty( const char *sName, const double dValue );
134
135 /**
136 * The XmlDocuemnt is considered completed if the root node has been closed.
137 * Once an XmlDocument has been completed, you can no longer perform
138 * operations on it.
139 *@return True if completed, false if still in progress.
140 */
141 bool isCompleted();
142
143 /**
144 * Get a pointer to the root object of this XmlDocument.
145 *@returns A pointer to an internally owned XmlNode. Do not delete this
146 * XmlNode.
147 */
148 XmlNode *getRoot();
149
150 /**
151 * Get a pointer to the root object of this XmlDocument, and remove the
152 * ownership from this object.
153 *@returns A pointer to an internally owned XmlNode. Do not delete this
154 * XmlNode.
155 */
156 XmlNode *detatchRoot();
157
158 /**
159 * Get the current context node, which could be the same as the root node.
160 *@returns A pointer to an internally owned XmlNode. Do not delete this
161 * XmlNode.
162 */
163 XmlNode *getCurrent();
164
165private:
166 XmlNode *pRoot; /**< The root node. */
167 XmlNode *pCurrent; /**< The current node. */
168 bool bCompleted; /**< Is it completed? */
169};
170
171#endif
diff --git a/src/old/xmlnode.cpp b/src/old/xmlnode.cpp
deleted file mode 100644
index b1ed9a9..0000000
--- a/src/old/xmlnode.cpp
+++ /dev/null
@@ -1,445 +0,0 @@
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
184void 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
220void 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
230XmlNode *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
315void 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
325XmlNode *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
384void 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
442void XmlNode::replaceNodeWithChildren( int nIndex, XmlNode *pNewNode )
443{
444}
445
diff --git a/src/old/xmlnode.h b/src/old/xmlnode.h
deleted file mode 100644
index 7525306..0000000
--- a/src/old/xmlnode.h
+++ /dev/null
@@ -1,236 +0,0 @@
1#ifndef XMLNODE
2#define XMLNODE
3
4#include <iostream>
5#include "linkedlist.h"
6#include "hashtable.h"
7
8/**
9 * Maintains all data pertient to an XML node, including sub-nodes and content.
10 * All child nodes can be accessed through index and through name via a hash
11 * table. This makes it very easy to gain simple and fast access to all of
12 * your data. For most applications, the memory footprint is also rather
13 * small. While XmlNode objects can be used directly to create XML structures
14 * it is highly reccomended that all operations be performed through the
15 * XmlDocument class.
16 *@author Mike Buland
17 */
18class XmlNode
19{
20public:
21 /**
22 * Construct a new XmlNode.
23 *@param sName The name of the node.
24 *@param pParent The parent node.
25 *@param sContent The initial content string.
26 */
27 XmlNode(
28 const char *sName=NULL,
29 XmlNode *pParent = NULL,
30 const char *sContent=NULL
31 );
32
33 /**
34 * Delete the node and cleanup all memory.
35 */
36 virtual ~XmlNode();
37
38 /**
39 * Change the name of the node.
40 *@param sName The new name of the node.
41 */
42 void setName( const char *sName );
43
44 /**
45 * Construct a new node and add it as a child to this node, also return a
46 * pointer to the newly constructed node.
47 *@param sName The name of the new node.
48 *@param sContent The initial content of the new node.
49 *@returns A pointer to the newly created child node.
50 */
51 XmlNode *addChild( const char *sName, const char *sContent=NULL );
52
53 /**
54 * Add an already created XmlNode as a child to this node. The new child
55 * XmlNode's parent will be changed appropriately and the parent XmlNode
56 * will take ownership of the child.
57 *@param pChild The child XmlNode to add to this XmlNode.
58 *@returns A pointer to the child node that was just added.
59 */
60 XmlNode *addChild( XmlNode *pChild );
61
62 /**
63 * Add a new property to the XmlNode. Properties are name/value pairs.
64 *@param sName The name of the property. Specifying a name that's already
65 * in use will overwrite that property.
66 *@param sValue The textual value of the property.
67 */
68 void addProperty( const char *sName, const char *sValue );
69
70 /**
71 * Get a pointer to the parent node, if any.
72 *@returns A pointer to the node's parent, or NULL if there isn't one.
73 */
74 XmlNode *getParent();
75
76 /**
77 * Tells you if this node has children.
78 *@returns True if this node has at least one child, false otherwise.
79 */
80 bool hasChildren();
81
82 /**
83 * Tells you how many children this node has.
84 *@returns The number of children this node has.
85 */
86 int getNumChildren();
87
88 /**
89 * Get a child node at a specific index.
90 *@param nIndex The zero-based index of the child to retreive.
91 *@returns A pointer to the child, or NULL if you requested an invalid
92 * index.
93 */
94 XmlNode *getChild( int nIndex );
95
96 /**
97 * Get a child with the specified name, and possibly skip value. For an
98 * explination of skip values see the HashTable.
99 *@param sName The name of the child to find.
100 *@param nSkip The number of nodes with that name to skip.
101 *@returns A pointer to the child, or NULL if no child with that name was
102 * found.
103 */
104 XmlNode *getChild( const char *sName, int nSkip=0 );
105
106 /**
107 * Get a pointer to the name of this node. Do not change this, use setName
108 * instead.
109 *@returns A pointer to the name of this node.
110 */
111 const char *getName();
112
113 /**
114 * Set the content of this node, optionally at a specific index. Using the
115 * default of -1 will set the content after the last added node.
116 *@param sContent The content string to use.
117 *@param nIndex The index of the content.
118 */
119 void setContent( const char *sContent, int nIndex=-1 );
120
121 /**
122 * Get the content string at a given index, or zero for initial content.
123 *@param nIndex The index of the content.
124 *@returns A pointer to the content at that location.
125 */
126 const char *getContent( int nIndex = 0 );
127
128 /**
129 * Get the number of properties in this node.
130 *@returns The number of properties in this node.
131 */
132 int getNumProperties();
133
134 /**
135 * Get a property's name by index.
136 *@param nIndex The index of the property to examine.
137 *@returns A pointer to the name of the property specified, or NULL if none
138 * found.
139 */
140 const char *getPropertyName( int nIndex );
141
142 /**
143 * Get a proprty's value by index.
144 *@param nIndex The index of the property to examine.
145 *@returns A pointer to the value of the property specified, or NULL if none
146 * found.
147 */
148 const char *getProperty( int nIndex );
149
150 /**
151 * Get a propery's value by name.
152 *@param sName The name of the property to examine.
153 *@returns A pointer to the value of the property specified, or NULL if none
154 * found.
155 */
156 const char *getProperty( const char *sName );
157
158 /**
159 * Delete a property by index.
160 *@param nIndex The index of the property to delete.
161 *@returns True if the property was found and deleted, false if it wasn't
162 * found.
163 */
164 void deleteProperty( int nIndex );
165
166 /**
167 * Delete a child node, possibly replacing it with some text. This actually
168 * fixes all content strings around the newly deleted child node.
169 *@param nIndex The index of the node to delete.
170 *@param sReplacementText The optional text to replace the node with.
171 *@returns True of the node was found, and deleted, false if it wasn't
172 * found.
173 */
174 void deleteNode( int nIndex, const char *sReplacementText = NULL );
175
176 /**
177 * Delete a given node, but move all of it's children and content up to
178 * replace the deleted node. All of the content of the child node is
179 * spliced seamlessly into place with the parent node's content.
180 *@param nIndex The node to delete.
181 *@returns True if the node was found and deleted, false if it wasn't.
182 */
183 void deleteNodeKeepChildren( int nIndex );
184
185 /**
186 * Detatch a given child node from this node. This effectively works just
187 * like a deleteNode, except that instead of deleting the node it is removed
188 * and returned, and all ownership is given up.
189 *@param nIndex The index of the node to detatch.
190 *@param sReplacementText The optional text to replace the detatched node
191 * with.
192 *@returns A pointer to the newly detatched node, which then passes
193 * ownership to the caller.
194 */
195 XmlNode *detatchNode( int nIndex, const char *sReplacementText = NULL );
196
197 /**
198 * Replace a given node with a different node that is not currently owned by
199 * this XmlNode or any ancestor.
200 *@param nIndex The index of the node to replace.
201 *@param pNewNode The new node to replace the old node with.
202 *@returns True if the node was found and replaced, false if it wasn't.
203 */
204 void replaceNode( int nIndex, XmlNode *pNewNode );
205
206 /**
207 * Replace a given node with the children and content of a given node.
208 *@param nIndex The index of the node to replace.
209 *@param pNewNode The node that contains the children and content that will
210 * replace the node specified by nIndex.
211 *@returns True if the node was found and replaced, false if it wasn't.
212 */
213 void replaceNodeWithChildren( int nIndex, XmlNode *pNewNode );
214
215 /**
216 * Get a copy of this node and all children. getCopy is recursive, so
217 * beware copying large trees of xml.
218 *@returns A newly created copy of this node and all of it's children.
219 */
220 XmlNode *getCopy();
221
222private:
223 std::string sName; /**< The name of the node. */
224 std::string *sPreContent; /**< The content that goes before any node. */
225 LinkedList lChildren; /**< The children. */
226 LinkedList lPostContent; /**< The content that comes after children. */
227 HashTable hProperties; /**< Property hashtable. */
228 HashTable hChildren; /**< Children hashtable. */
229 LinkedList lPropNames; /**< List of property names. */
230 LinkedList lPropValues; /**< List of property values. */
231 XmlNode *pParent; /**< A pointer to the parent of this node. */
232 int nCurContent; /**< The current content we're on, for using the -1 on
233 setContent. */
234};
235
236#endif
diff --git a/src/old/xmlreader.cpp b/src/old/xmlreader.cpp
deleted file mode 100644
index 18df69c..0000000
--- a/src/old/xmlreader.cpp
+++ /dev/null
@@ -1,602 +0,0 @@
1#include "xmlreader.h"
2#include "exceptions.h"
3#include <string.h>
4#include "hashfunctionstring.h"
5
6XmlReader::XmlReader( bool bStrip ) :
7 bStrip( bStrip ),
8 htEntity( new HashFunctionString(), 11 )
9{
10}
11
12XmlReader::~XmlReader()
13{
14 void *i = htEntity.getFirstItemPos();
15 while( (i = htEntity.getNextItemPos( i ) ) )
16 {
17 free( (char *)(htEntity.getItemID( i )) );
18 delete (StaticString *)htEntity.getItemData( i );
19 }
20}
21
22void XmlReader::addEntity( const char *name, const char *value )
23{
24 if( htEntity[name] ) return;
25
26 char *sName = strdup( name );
27 StaticString *sValue = new StaticString( value );
28
29 htEntity.insert( sName, sValue );
30}
31
32#define gcall( x ) if( x == false ) return false;
33
34bool XmlReader::isws( char chr )
35{
36 return ( chr == ' ' || chr == '\t' || chr == '\n' || chr == '\r' );
37}
38
39bool XmlReader::ws()
40{
41 while( true )
42 {
43 char chr = getChar();
44 if( isws( chr ) )
45 {
46 usedChar();
47 }
48 else
49 {
50 return true;
51 }
52 }
53 return true;
54}
55
56bool XmlReader::buildDoc()
57{
58 // take care of initial whitespace
59 gcall( ws() );
60 textDecl();
61 entity();
62 addEntity("gt", ">");
63 addEntity("lt", "<");
64 addEntity("amp", "&");
65 addEntity("apos", "\'");
66 addEntity("quot", "\"");
67 gcall( node() );
68
69 return true;
70}
71
72void XmlReader::textDecl()
73{
74 if( getChar() == '<' && getChar( 1 ) == '?' )
75 {
76 usedChar( 2 );
77 for(;;)
78 {
79 if( getChar() == '?' )
80 {
81 if( getChar( 1 ) == '>' )
82 {
83 usedChar( 2 );
84 return;
85 }
86 }
87 usedChar();
88 }
89 }
90}
91
92void XmlReader::entity()
93{
94 for(;;)
95 {
96 ws();
97
98 if( getChar() == '<' && getChar( 1 ) == '!' )
99 {
100 usedChar( 2 );
101 ws();
102 std::string buf;
103 for(;;)
104 {
105 char chr = getChar();
106 usedChar();
107 if( isws( chr ) ) break;
108 buf += chr;
109 }
110
111 if( strcmp( buf.c_str(), "ENTITY") == 0 )
112 {
113 ws();
114 std::string name;
115 for(;;)
116 {
117 char chr = getChar();
118 usedChar();
119 if( isws( chr ) ) break;
120 name += chr;
121 }
122 ws();
123 char quot = getChar();
124 usedChar();
125 if( quot != '\'' && quot != '\"' )
126 {
127 throw XmlException(
128 "Only quoted entity values are supported."
129 );
130 }
131 std::string value;
132 for(;;)
133 {
134 char chr = getChar();
135 usedChar();
136 if( chr == '&' )
137 {
138 StaticString *tmp = getEscape();
139 if( tmp == NULL ) throw XmlException("Entity thing");
140 value += tmp->getString();
141 delete tmp;
142 }
143 else if( chr == quot )
144 {
145 break;
146 }
147 else
148 {
149 value += chr;
150 }
151 }
152 ws();
153 if( getChar() == '>' )
154 {
155 usedChar();
156
157 addEntity( name.c_str(), value.c_str() );
158 }
159 else
160 {
161 throw XmlException(
162 "Malformed ENTITY: unexpected '%c' found.",
163 getChar()
164 );
165 }
166 }
167 else
168 {
169 throw XmlException(
170 "Unsupported header symbol: %s",
171 buf.c_str()
172 );
173 }
174 }
175 else
176 {
177 return;
178 }
179 }
180}
181
182bool XmlReader::node()
183{
184 gcall( startNode() )
185
186 // At this point, we are closing the startNode
187 char chr = getChar();
188 if( chr == '>' )
189 {
190 usedChar();
191
192 // Now we process the guts of the node.
193 gcall( content() );
194 }
195 else if( chr == '/' )
196 {
197 // This is the tricky one, one more validation, then we close the node.
198 usedChar();
199 if( getChar() == '>' )
200 {
201 closeNode();
202 usedChar();
203 }
204 else
205 {
206 throw XmlException("Close node in singleNode malformed!");
207 }
208 }
209 else
210 {
211 throw XmlException("Close node expected, but not found.");
212 return false;
213 }
214
215 return true;
216}
217
218bool XmlReader::startNode()
219{
220 if( getChar() == '<' )
221 {
222 usedChar();
223
224 if( getChar() == '/' )
225 {
226 // Heh, it's actually a close node, go figure
227 FlexBuf fbName;
228 usedChar();
229 gcall( ws() );
230
231 while( true )
232 {
233 char chr = getChar();
234 if( isws( chr ) || chr == '>' )
235 {
236 // Here we actually compare the name we got to the name
237 // we already set, they have to match exactly.
238 if( !strcasecmp( getCurrent()->getName(), fbName.getData() ) )
239 {
240 closeNode();
241 break;
242 }
243 else
244 {
245 throw XmlException("Got a mismatched node close tag.");
246 }
247 }
248 else
249 {
250 fbName.appendData( chr );
251 usedChar();
252 }
253 }
254
255 gcall( ws() );
256 if( getChar() == '>' )
257 {
258 // Everything is cool.
259 usedChar();
260 }
261 else
262 {
263 throw XmlException("Got extra junk data instead of node close tag.");
264 }
265 }
266 else
267 {
268 // We're good, format is consistant
269 addNode();
270
271 // Skip extra whitespace
272 gcall( ws() );
273 gcall( name() );
274 gcall( ws() );
275 gcall( paramlist() );
276 gcall( ws() );
277 }
278 }
279 else
280 {
281 throw XmlException("Expected to find node opening char, '<'.");
282 }
283
284 return true;
285}
286
287bool XmlReader::name()
288{
289 FlexBuf fbName;
290
291 while( true )
292 {
293 char chr = getChar();
294 if( isws( chr ) || chr == '>' || chr == '/' )
295 {
296 setName( fbName.getData() );
297 return true;
298 }
299 else
300 {
301 fbName.appendData( chr );
302 usedChar();
303 }
304 }
305
306 return true;
307}
308
309bool XmlReader::paramlist()
310{
311 while( true )
312 {
313 char chr = getChar();
314 if( chr == '/' || chr == '>' )
315 {
316 return true;
317 }
318 else
319 {
320 gcall( param() );
321 gcall( ws() );
322 }
323 }
324
325 return true;
326}
327
328StaticString *XmlReader::getEscape()
329{
330 if( getChar( 1 ) == '#' )
331 {
332 // If the entity starts with a # it's a character escape code
333 int base = 10;
334 usedChar( 2 );
335 if( getChar() == 'x' )
336 {
337 base = 16;
338 usedChar();
339 }
340 char buf[4];
341 int j = 0;
342 for( j = 0; getChar() != ';'; j++ )
343 {
344 buf[j] = getChar();
345 usedChar();
346 }
347 usedChar();
348 buf[j] = '\0';
349 buf[0] = (char)strtol( buf, (char **)NULL, base );
350 buf[1] = '\0';
351
352 return new StaticString( buf );
353 }
354 else
355 {
356 // ...otherwise replace with the appropriate string...
357 std::string buf;
358 usedChar();
359 for(;;)
360 {
361 char cbuf = getChar();
362 usedChar();
363 if( cbuf == ';' ) break;
364 buf += cbuf;
365 }
366
367 StaticString *tmp = (StaticString *)htEntity[buf.c_str()];
368 if( tmp == NULL ) return NULL;
369
370 StaticString *ret = new StaticString( *tmp );
371 return ret;
372 }
373}
374
375bool XmlReader::param()
376{
377 FlexBuf fbName;
378 FlexBuf fbValue;
379
380 while( true )
381 {
382 char chr = getChar();
383 if( isws( chr ) || chr == '=' )
384 {
385 break;
386 }
387 else
388 {
389 fbName.appendData( chr );
390 usedChar();
391 }
392 }
393
394 gcall( ws() );
395
396 if( getChar() == '=' )
397 {
398 usedChar();
399
400 gcall( ws() );
401
402 char chr = getChar();
403 if( chr == '"' )
404 {
405 // Better quoted rhs
406 usedChar();
407
408 while( true )
409 {
410 chr = getChar();
411 if( chr == '"' )
412 {
413 usedChar();
414 addProperty( fbName.getData(), fbValue.getData() );
415 return true;
416 }
417 else
418 {
419 if( chr == '&' )
420 {
421 StaticString *tmp = getEscape();
422 if( tmp == NULL ) return false;
423 fbValue.appendData( tmp->getString() );
424 delete tmp;
425 }
426 else
427 {
428 fbValue.appendData( chr );
429 usedChar();
430 }
431 }
432 }
433 }
434 else
435 {
436 // Simple one-word rhs
437 while( true )
438 {
439 chr = getChar();
440 if( isws( chr ) || chr == '/' || chr == '>' )
441 {
442 addProperty( fbName.getData(), fbValue.getData() );
443 return true;
444 }
445 else
446 {
447 if( chr == '&' )
448 {
449 StaticString *tmp = getEscape();
450 if( tmp == NULL ) return false;
451 fbValue.appendData( tmp->getString() );
452 delete tmp;
453 }
454 else
455 {
456 fbValue.appendData( chr );
457 usedChar();
458 }
459 }
460 }
461 }
462 }
463 else
464 {
465 throw XmlException("Expected an equals to seperate the params.");
466 return false;
467 }
468
469 return true;
470}
471
472bool XmlReader::content()
473{
474 FlexBuf fbContent;
475
476 if( bStrip ) gcall( ws() );
477
478 while( true )
479 {
480 char chr = getChar();
481 if( chr == '<' )
482 {
483 if( getChar(1) == '/' )
484 {
485 if( fbContent.getLength() > 0 )
486 {
487 if( bStrip )
488 {
489 int j;
490 for( j = fbContent.getLength()-1; isws(fbContent.getData()[j]); j-- );
491 ((char *)fbContent.getData())[j+1] = '\0';
492 }
493 setContent( fbContent.getData() );
494 }
495 usedChar( 2 );
496 gcall( ws() );
497 FlexBuf fbName;
498 while( true )
499 {
500 chr = getChar();
501 if( isws( chr ) || chr == '>' )
502 {
503 if( !strcasecmp( getCurrent()->getName(), fbName.getData() ) )
504 {
505 closeNode();
506 break;
507 }
508 else
509 {
510 throw XmlException("Mismatched close tag found: <%s> to <%s>.", getCurrent()->getName(), fbName.getData() );
511 }
512 }
513 else
514 {
515 fbName.appendData( chr );
516 usedChar();
517 }
518 }
519 gcall( ws() );
520 if( getChar() == '>' )
521 {
522 usedChar();
523 return true;
524 }
525 else
526 {
527 throw XmlException("Malformed close tag.");
528 }
529 }
530 else if( getChar(1) == '!' )
531 {
532 // We know it's a comment, let's see if it's proper
533 if( getChar(2) != '-' ||
534 getChar(3) != '-' )
535 {
536 // Not a valid XML comment
537 throw XmlException("Malformed comment start tag found.");
538 }
539
540 usedChar( 4 );
541
542 // Now burn text until we find the close tag
543 for(;;)
544 {
545 if( getChar() == '-' )
546 {
547 if( getChar( 1 ) == '-' )
548 {
549 // The next one has to be a '>' now
550 if( getChar( 2 ) != '>' )
551 {
552 throw XmlException("Malformed comment close tag found. You cannot have a '--' that isn't followed by a '>' in a comment.");
553 }
554 usedChar( 3 );
555 break;
556 }
557 else
558 {
559 // Found a dash followed by a non dash, that's ok...
560 usedChar( 2 );
561 }
562 }
563 else
564 {
565 // Burn comment chars
566 usedChar();
567 }
568 }
569 }
570 else
571 {
572 if( fbContent.getLength() > 0 )
573 {
574 if( bStrip )
575 {
576 int j;
577 for( j = fbContent.getLength()-1; isws(fbContent.getData()[j]); j-- );
578 ((char *)fbContent.getData())[j+1] = '\0';
579 }
580 setContent( fbContent.getData() );
581 fbContent.clearData();
582 }
583 gcall( node() );
584 }
585
586 if( bStrip ) gcall( ws() );
587 }
588 else if( chr == '&' )
589 {
590 StaticString *tmp = getEscape();
591 if( tmp == NULL ) return false;
592 fbContent.appendData( tmp->getString() );
593 delete tmp;
594 }
595 else
596 {
597 fbContent.appendData( chr );
598 usedChar();
599 }
600 }
601}
602
diff --git a/src/old/xmlreader.h b/src/old/xmlreader.h
deleted file mode 100644
index c8f7202..0000000
--- a/src/old/xmlreader.h
+++ /dev/null
@@ -1,141 +0,0 @@
1#ifndef XMLREADER
2#define XMLREADER
3
4#include <stdio.h>
5#include "xmldocument.h"
6#include "flexbuf.h"
7#include "hashtable.h"
8#include "staticstring.h"
9
10/**
11 * Takes care of reading in xml formatted data from a file. This could/should
12 * be made more arbitrary in the future so that we can read the data from any
13 * source. This is actually made quite simple already since all data read in
14 * is handled by one single helper function and then palced into a FlexBuf for
15 * easy access by the other functions. The FlexBuf also allows for block
16 * reading from disk, which improves speed by a noticable amount.
17 * <br>
18 * There are also some extra features implemented that allow you to break the
19 * standard XML reader specs and eliminate leading and trailing whitespace in
20 * all read content. This is useful in situations where you allow additional
21 * whitespace in the files to make them easily human readable. The resturned
22 * content will be NULL in sitautions where all content between nodes was
23 * stripped.
24 *@author Mike Buland
25 */
26class XmlReader : public XmlDocument
27{
28public:
29 /**
30 * Create a standard XmlReader. The optional parameter bStrip allows you to
31 * create a reader that will strip out all leading and trailing whitespace
32 * in content, a-la html.
33 *@param bStrip Strip out leading and trailing whitespace?
34 */
35 XmlReader( bool bStrip=false );
36
37 /**
38 * Destroy this XmlReader.
39 */
40 virtual ~XmlReader();
41
42 /**
43 * Build a document based on some kind of input. This is called
44 * automatically by the constructor.
45 */
46 bool buildDoc();
47
48private:
49 /**
50 * This is called by the low level automoton in order to get the next
51 * character. This function should return a character at the current
52 * position plus nIndex, but does not increment the current character.
53 *@param nIndex The index of the character from the current stream position.
54 *@returns A single character at the requested position, or 0 for end of
55 * stream.
56 */
57 virtual char getChar( int nIndex = 0 ) = 0;
58
59 /**
60 * Called to increment the current stream position by a single character.
61 */
62 virtual void usedChar( int nAmnt = 1) = 0;
63
64 /**
65 * Automoton function: is whitespace.
66 *@param chr A character
67 *@returns True if chr is whitespace, false otherwise.
68 */
69 bool isws( char chr );
70
71 /**
72 * Automoton function: ws. Skips sections of whitespace.
73 *@returns True if everything was ok, False for end of stream.
74 */
75 bool ws();
76
77 /**
78 * Automoton function: node. Processes an XmlNode
79 *@returns True if everything was ok, False for end of stream.
80 */
81 bool node();
82
83 /**
84 * Automoton function: startNode. Processes the begining of a node.
85 *@returns True if everything was ok, False for end of stream.
86 */
87 bool startNode();
88
89 /**
90 * Automoton function: name. Processes the name of a node.
91 *@returns True if everything was ok, False for end of stream.
92 */
93 bool name();
94
95 /**
96 * Automoton function: textDecl. Processes the xml text decleration, if
97 * there is one.
98 */
99 void textDecl();
100
101 /**
102 * Automoton function: entity. Processes an entity from the header.
103 */
104 void entity();
105
106 /**
107 * Adds an entity to the list, if it doesn't already exist.
108 *@param name The name of the entity
109 *@param value The value of the entity
110 */
111 void addEntity( const char *name, const char *value );
112
113 StaticString *getEscape();
114
115 /**
116 * Automoton function: paramlist. Processes a list of node params.
117 *@returns True if everything was ok, False for end of stream.
118 */
119 bool paramlist();
120
121 /**
122 * Automoton function: param. Processes a single parameter.
123 *@returns True if everything was ok, False for end of stream.
124 */
125 bool param();
126
127 /**
128 * Automoton function: content. Processes node content.
129 *@returns True if everything was ok, False for end of stream.
130 */
131 bool content();
132
133 FlexBuf fbContent; /**< buffer for the current node's content. */
134 FlexBuf fbParamName; /**< buffer for the current param's name. */
135 FlexBuf fbParamValue; /**< buffer for the current param's value. */
136 bool bStrip; /**< Are we stripping whitespace? */
137
138 HashTable htEntity; /**< Entity type definitions. */
139};
140
141#endif
diff --git a/src/old/xmlwriter.cpp b/src/old/xmlwriter.cpp
deleted file mode 100644
index 56880b6..0000000
--- a/src/old/xmlwriter.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include "xmlwriter.h"
4
5XmlWriter::XmlWriter( const char *sIndent, XmlNode *pRoot ) :
6 XmlDocument( pRoot )
7{
8 if( sIndent == NULL )
9 {
10 this->sIndent = "";
11 }
12 else
13 {
14 this->sIndent = sIndent;
15 }
16}
17
18XmlWriter::~XmlWriter()
19{
20}
21
22void XmlWriter::write()
23{
24 write( getRoot(), sIndent.c_str() );
25}
26
27void XmlWriter::write( XmlNode *pRoot, const char *sIndent )
28{
29 writeNode( pRoot, 0, sIndent );
30}
31
32void XmlWriter::closeNode()
33{
34 XmlDocument::closeNode();
35
36 if( isCompleted() )
37 {
38 write( getRoot(), sIndent.c_str() );
39 }
40}
41
42void XmlWriter::writeIndent( int nIndent, const char *sIndent )
43{
44 if( sIndent == NULL ) return;
45 for( int j = 0; j < nIndent; j++ )
46 {
47 writeString( sIndent );
48 }
49}
50
51std::string XmlWriter::escape( std::string sIn )
52{
53 std::string sOut;
54
55 std::string::const_iterator i;
56 for( i = sIn.begin(); i != sIn.end(); i++ )
57 {
58 if( ((*i >= ' ' && *i <= '9') ||
59 (*i >= 'a' && *i <= 'z') ||
60 (*i >= 'A' && *i <= 'Z') ) &&
61 (*i != '\"' && *i != '\'' && *i != '&')
62 )
63 {
64 sOut += *i;
65 }
66 else
67 {
68 sOut += "&#";
69 char buf[4];
70 sprintf( buf, "%u", (unsigned char)*i );
71 sOut += buf;
72 sOut += ';';
73 }
74 }
75
76 return sOut;
77}
78
79void XmlWriter::writeNodeProps( XmlNode *pNode, int nIndent, const char *sIndent )
80{
81 for( int j = 0; j < pNode->getNumProperties(); j++ )
82 {
83 writeString(" ");
84 writeString( pNode->getPropertyName( j ) );
85 writeString("=\"");
86 writeString( escape( pNode->getProperty( j ) ).c_str() );
87 writeString("\"");
88 }
89}
90
91void XmlWriter::writeNode( XmlNode *pNode, int nIndent, const char *sIndent )
92{
93 if( pNode->hasChildren() )
94 {
95 writeIndent( nIndent, sIndent );
96 writeString("<");
97 writeString( pNode->getName() );
98 writeNodeProps( pNode, nIndent, sIndent );
99 if( sIndent )
100 writeString(">\n");
101 else
102 writeString(">");
103
104 if( pNode->getContent( 0 ) )
105 {
106 writeIndent( nIndent+1, sIndent );
107 if( sIndent )
108 {
109 writeString( pNode->getContent( 0 ) );
110 writeString("\n");
111 }
112 else
113 writeString( pNode->getContent( 0 ) );
114 }
115
116 int nNumChildren = pNode->getNumChildren();
117 for( int j = 0; j < nNumChildren; j++ )
118 {
119 writeNode( pNode->getChild( j ), nIndent+1, sIndent );
120 if( pNode->getContent( j+1 ) )
121 {
122 writeIndent( nIndent+1, sIndent );
123 if( sIndent )
124 {
125 writeString( pNode->getContent( j+1 ) );
126 writeString("\n");
127 }
128 else
129 writeString( pNode->getContent( j+1 ) );
130 }
131 }
132
133 writeIndent( nIndent, sIndent );
134 if( sIndent )
135 {
136 writeString("</");
137 writeString( pNode->getName() );
138 writeString(">\n");
139 }
140 else
141 {
142 writeString("</");
143 writeString( pNode->getName() );
144 writeString(">");
145 }
146 }
147 else if( pNode->getContent() )
148 {
149 writeIndent( nIndent, sIndent );
150 writeString("<");
151 writeString( pNode->getName() );
152 writeNodeProps( pNode, nIndent, sIndent );
153 writeString(">");
154 writeString( pNode->getContent() );
155 writeString("</");
156 writeString( pNode->getName() );
157 writeString(">");
158 if( sIndent )
159 writeString("\n");
160 }
161 else
162 {
163 writeIndent( nIndent, sIndent );
164 writeString("<");
165 writeString( pNode->getName() );
166 writeNodeProps( pNode, nIndent, sIndent );
167 if( sIndent )
168 writeString("/>\n");
169 else
170 writeString("/>");
171 }
172}
173
diff --git a/src/old/xmlwriter.h b/src/old/xmlwriter.h
deleted file mode 100644
index c48e810..0000000
--- a/src/old/xmlwriter.h
+++ /dev/null
@@ -1,96 +0,0 @@
1#ifndef XMLWRITER
2#define XMLWRITER
3
4#include "xmlnode.h"
5#include "xmldocument.h"
6
7/**
8 * Implements xml writing in the XML standard format. Also allows you to
9 * break that format and auto-indent your exported xml data for ease of
10 * reading. The auto-indenting will only be applied to sections that
11 * have no content of their own already. This means that except for
12 * whitespace all of your data will be preserved perfectly.
13 * You can create an XmlWriter object around a file, or access the static
14 * write function directly and just hand it a filename and a root XmlNode.
15 * When using an XmlWriter object the interface is identicle to that of
16 * the XmlDocument class, so reference that class for API info. However
17 * when the initial (or root) node is closed, and the document is finished
18 * the file will be created and written to automatically. The user can
19 * check to see if this is actually true by calling the isFinished
20 * function in the XmlDocument class.
21 *@author Mike Buland
22 */
23class XmlWriter : public XmlDocument
24{
25public:
26 /**
27 * Construct a standard XmlWriter.
28 *@param sIndent Set this to something other than NULL to include it as an
29 * indent before each node in the output that doesn't already have content.
30 * If you are using the whitespace stripping option in the XmlReader and set
31 * this to a tab or some spaces it will never effect the content of your
32 * file.
33 */
34 XmlWriter( const char *sIndent=NULL, XmlNode *pRoot=NULL );
35
36 /**
37 * Destroy the writer.
38 */
39 virtual ~XmlWriter();
40
41 /**
42 * This override of the parent class closeNode function calls the parent
43 * class, but also triggers a write operation when the final node is closed.
44 * This means that by checking the isCompleted() function the user may also
45 * check to see if their file has been written or not.
46 */
47 void closeNode();
48
49 void write();
50
51private:
52 std::string sIndent; /**< The indent string */
53
54 std::string escape( std::string sIn );
55
56 /**
57 * Write the file.
58 *@param pNode The root node
59 *@param sIndent The indent text.
60 */
61 void write( XmlNode *pNode, const char *sIndent=NULL );
62
63 /**
64 * Write a node in the file, including children.
65 *@param pNode The node to write.
66 *@param nIndent The indent level (the number of times to include sIndent)
67 *@param sIndent The indent text.
68 */
69 void writeNode( XmlNode *pNode, int nIndent, const char *sIndent );
70
71 /**
72 * Write the properties of a node.
73 *@param pNode The node who's properties to write.
74 *@param nIndent The indent level of the containing node
75 *@param sIndent The indent text.
76 */
77 void writeNodeProps( XmlNode *pNode, int nIndent, const char *sIndent );
78
79 /**
80 * Called to write the actual indent.
81 *@param nIndent The indent level.
82 *@param sIndent The indent text.
83 */
84 void writeIndent( int nIndent, const char *sIndent );
85
86 /**
87 * This is the function that must be overridden in order to use this class.
88 * It must write the null-terminated string sString, minus the mull,
89 * verbatum to it's output device. Adding extra characters for any reason
90 * will break the XML formatting.
91 *@param sString The string data to write to the output.
92 */
93 virtual void writeString( const char *sString ) = 0;
94};
95
96#endif