diff options
| author | Mike Buland <eichlan@xagasoft.com> | 2007-05-09 15:04:31 +0000 |
|---|---|---|
| committer | Mike Buland <eichlan@xagasoft.com> | 2007-05-09 15:04:31 +0000 |
| commit | ad92dc50b7cdf7cfe086f21d19442d03a90fd05d (patch) | |
| tree | 9ca6f7bde704cb44276a05b6e83f36754e07f732 /src/old | |
| parent | 2e035fee36768e3c765b7f5dc10bf0a3b7d2448b (diff) | |
| download | libbu++-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 '')
| -rw-r--r-- | src/old/xmldocument.cpp | 149 | ||||
| -rw-r--r-- | src/old/xmldocument.h | 171 | ||||
| -rw-r--r-- | src/old/xmlnode.cpp | 445 | ||||
| -rw-r--r-- | src/old/xmlnode.h | 236 | ||||
| -rw-r--r-- | src/old/xmlreader.cpp | 602 | ||||
| -rw-r--r-- | src/old/xmlreader.h | 141 | ||||
| -rw-r--r-- | src/old/xmlwriter.cpp | 173 | ||||
| -rw-r--r-- | src/old/xmlwriter.h | 96 |
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 | |||
| 5 | XmlDocument::XmlDocument( XmlNode *pRoot ) | ||
| 6 | { | ||
| 7 | this->pRoot = pRoot; | ||
| 8 | pCurrent = NULL; | ||
| 9 | bCompleted = (pRoot!=NULL); | ||
| 10 | } | ||
| 11 | |||
| 12 | XmlDocument::~XmlDocument() | ||
| 13 | { | ||
| 14 | if( pRoot ) | ||
| 15 | { | ||
| 16 | delete pRoot; | ||
| 17 | } | ||
| 18 | } | ||
| 19 | |||
| 20 | void 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 | |||
| 38 | void XmlDocument::setName( const char *sName ) | ||
| 39 | { | ||
| 40 | pCurrent->setName( sName ); | ||
| 41 | } | ||
| 42 | |||
| 43 | bool XmlDocument::isCompleted() | ||
| 44 | { | ||
| 45 | return bCompleted; | ||
| 46 | } | ||
| 47 | |||
| 48 | XmlNode *XmlDocument::getRoot() | ||
| 49 | { | ||
| 50 | return pRoot; | ||
| 51 | } | ||
| 52 | |||
| 53 | XmlNode *XmlDocument::detatchRoot() | ||
| 54 | { | ||
| 55 | XmlNode *pTemp = pRoot; | ||
| 56 | pRoot = NULL; | ||
| 57 | return pTemp; | ||
| 58 | } | ||
| 59 | |||
| 60 | XmlNode *XmlDocument::getCurrent() | ||
| 61 | { | ||
| 62 | return pCurrent; | ||
| 63 | } | ||
| 64 | |||
| 65 | void 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 | |||
| 78 | void XmlDocument::addProperty( const char *sName, const char *sValue ) | ||
| 79 | { | ||
| 80 | if( pCurrent ) | ||
| 81 | { | ||
| 82 | pCurrent->addProperty( sName, sValue ); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | void 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 | |||
| 93 | void XmlDocument::addProperty( const char *sName, const char nValue ) | ||
| 94 | { | ||
| 95 | char buf[12]; | ||
| 96 | sprintf( buf, "%hhi", nValue ); | ||
| 97 | addProperty( sName, buf ); | ||
| 98 | } | ||
| 99 | |||
| 100 | void 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 | |||
| 107 | void XmlDocument::addProperty( const char *sName, const short nValue ) | ||
| 108 | { | ||
| 109 | char buf[12]; | ||
| 110 | sprintf( buf, "%hi", nValue ); | ||
| 111 | addProperty( sName, buf ); | ||
| 112 | } | ||
| 113 | |||
| 114 | void XmlDocument::addProperty( const char *sName, const int nValue ) | ||
| 115 | { | ||
| 116 | char buf[12]; | ||
| 117 | sprintf( buf, "%d", nValue ); | ||
| 118 | addProperty( sName, buf ); | ||
| 119 | } | ||
| 120 | |||
| 121 | void 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 | |||
| 128 | void XmlDocument::addProperty( const char *sName, const long nValue ) | ||
| 129 | { | ||
| 130 | char buf[12]; | ||
| 131 | sprintf( buf, "%li", nValue ); | ||
| 132 | addProperty( sName, buf ); | ||
| 133 | } | ||
| 134 | |||
| 135 | void XmlDocument::addProperty( const char *sName, const double dValue ) | ||
| 136 | { | ||
| 137 | char buf[40]; | ||
| 138 | sprintf( buf, "%f", dValue ); | ||
| 139 | addProperty( sName, buf ); | ||
| 140 | } | ||
| 141 | |||
| 142 | void 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 | */ | ||
| 14 | class XmlDocument | ||
| 15 | { | ||
| 16 | public: | ||
| 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 | |||
| 165 | private: | ||
| 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 | |||
| 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 | |||
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 | */ | ||
| 18 | class XmlNode | ||
| 19 | { | ||
| 20 | public: | ||
| 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 | |||
| 222 | private: | ||
| 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 | |||
| 6 | XmlReader::XmlReader( bool bStrip ) : | ||
| 7 | bStrip( bStrip ), | ||
| 8 | htEntity( new HashFunctionString(), 11 ) | ||
| 9 | { | ||
| 10 | } | ||
| 11 | |||
| 12 | XmlReader::~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 | |||
| 22 | void 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 | |||
| 34 | bool XmlReader::isws( char chr ) | ||
| 35 | { | ||
| 36 | return ( chr == ' ' || chr == '\t' || chr == '\n' || chr == '\r' ); | ||
| 37 | } | ||
| 38 | |||
| 39 | bool 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 | |||
| 56 | bool 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 | |||
| 72 | void 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 | |||
| 92 | void 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 | |||
| 182 | bool 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 | |||
| 218 | bool 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 | |||
| 287 | bool 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 | |||
| 309 | bool 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 | |||
| 328 | StaticString *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 | |||
| 375 | bool 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 | |||
| 472 | bool 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 | */ | ||
| 26 | class XmlReader : public XmlDocument | ||
| 27 | { | ||
| 28 | public: | ||
| 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 | |||
| 48 | private: | ||
| 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 | |||
| 5 | XmlWriter::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 | |||
| 18 | XmlWriter::~XmlWriter() | ||
| 19 | { | ||
| 20 | } | ||
| 21 | |||
| 22 | void XmlWriter::write() | ||
| 23 | { | ||
| 24 | write( getRoot(), sIndent.c_str() ); | ||
| 25 | } | ||
| 26 | |||
| 27 | void XmlWriter::write( XmlNode *pRoot, const char *sIndent ) | ||
| 28 | { | ||
| 29 | writeNode( pRoot, 0, sIndent ); | ||
| 30 | } | ||
| 31 | |||
| 32 | void XmlWriter::closeNode() | ||
| 33 | { | ||
| 34 | XmlDocument::closeNode(); | ||
| 35 | |||
| 36 | if( isCompleted() ) | ||
| 37 | { | ||
| 38 | write( getRoot(), sIndent.c_str() ); | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | void 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 | |||
| 51 | std::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 | |||
| 79 | void 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 | |||
| 91 | void 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 | */ | ||
| 23 | class XmlWriter : public XmlDocument | ||
| 24 | { | ||
| 25 | public: | ||
| 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 | |||
| 51 | private: | ||
| 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 | ||
