diff options
Diffstat (limited to '')
| -rw-r--r-- | src/fstring.h | 14 | ||||
| -rw-r--r-- | src/list.cpp | 2 | ||||
| -rw-r--r-- | src/list.h | 176 | ||||
| -rw-r--r-- | src/tests/list.cpp | 22 | ||||
| -rw-r--r-- | src/tests/xml.cpp | 6 | ||||
| -rw-r--r-- | src/xmldocument.cpp | 20 | ||||
| -rw-r--r-- | src/xmldocument.h | 8 | ||||
| -rw-r--r-- | src/xmlnode.cpp | 106 | ||||
| -rw-r--r-- | src/xmlnode.h | 101 | ||||
| -rw-r--r-- | src/xmlreader.cpp | 170 | ||||
| -rw-r--r-- | src/xmlreader.h | 31 | ||||
| -rw-r--r-- | src/xmlwriter.cpp | 62 | ||||
| -rw-r--r-- | src/xmlwriter.h | 16 |
13 files changed, 428 insertions, 306 deletions
diff --git a/src/fstring.h b/src/fstring.h index 877e5a7..f738f63 100644 --- a/src/fstring.h +++ b/src/fstring.h | |||
| @@ -28,7 +28,7 @@ namespace Bu | |||
| 28 | * data is actually copied. This also means that you never need to put any | 28 | * data is actually copied. This also means that you never need to put any |
| 29 | * FBasicString into a ref-counting container class. | 29 | * FBasicString into a ref-counting container class. |
| 30 | */ | 30 | */ |
| 31 | template< typename chr, typename chralloc=std::allocator<chr>, typename chunkalloc=std::allocator<struct FStringChunk<chr> > > | 31 | template< typename chr, int nMinSize=256, typename chralloc=std::allocator<chr>, typename chunkalloc=std::allocator<struct FStringChunk<chr> > > |
| 32 | class FBasicString : public Archival | 32 | class FBasicString : public Archival |
| 33 | { | 33 | { |
| 34 | #ifndef VALTEST | 34 | #ifndef VALTEST |
| @@ -36,7 +36,7 @@ namespace Bu | |||
| 36 | #endif | 36 | #endif |
| 37 | private: | 37 | private: |
| 38 | typedef struct FStringChunk<chr> Chunk; | 38 | typedef struct FStringChunk<chr> Chunk; |
| 39 | typedef struct FBasicString<chr, chralloc, chunkalloc> MyType; | 39 | typedef struct FBasicString<chr, nMinSize, chralloc, chunkalloc> MyType; |
| 40 | 40 | ||
| 41 | public: | 41 | public: |
| 42 | FBasicString() : | 42 | FBasicString() : |
| @@ -131,6 +131,11 @@ namespace Bu | |||
| 131 | appendChunk( pNew ); | 131 | appendChunk( pNew ); |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | void append( const chr cData ) | ||
| 135 | { | ||
| 136 | append( &cData, 1 ); | ||
| 137 | } | ||
| 138 | |||
| 134 | void prepend( const chr *pData ) | 139 | void prepend( const chr *pData ) |
| 135 | { | 140 | { |
| 136 | long nLen; | 141 | long nLen; |
| @@ -231,8 +236,7 @@ namespace Bu | |||
| 231 | 236 | ||
| 232 | MyType &operator +=( const chr pData ) | 237 | MyType &operator +=( const chr pData ) |
| 233 | { | 238 | { |
| 234 | chr tmp[2] = { pData, (chr)0 }; | 239 | append( &pData, 1 ); |
| 235 | append( tmp ); | ||
| 236 | 240 | ||
| 237 | return (*this); | 241 | return (*this); |
| 238 | } | 242 | } |
| @@ -475,7 +479,7 @@ namespace Bu | |||
| 475 | } | 479 | } |
| 476 | } | 480 | } |
| 477 | 481 | ||
| 478 | void copyFrom( const FBasicString<chr, chralloc, chunkalloc> &rSrc ) | 482 | void copyFrom( const FBasicString<chr, nMinSize, chralloc, chunkalloc> &rSrc ) |
| 479 | { | 483 | { |
| 480 | if( rSrc.pFirst == NULL ) | 484 | if( rSrc.pFirst == NULL ) |
| 481 | return; | 485 | return; |
diff --git a/src/list.cpp b/src/list.cpp new file mode 100644 index 0000000..abe92ad --- /dev/null +++ b/src/list.cpp | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | #include "bu/list.h" | ||
| 2 | |||
diff --git a/src/list.h b/src/list.h new file mode 100644 index 0000000..ec63496 --- /dev/null +++ b/src/list.h | |||
| @@ -0,0 +1,176 @@ | |||
| 1 | #ifndef LIST_H | ||
| 2 | #define LIST_H | ||
| 3 | |||
| 4 | #include <memory> | ||
| 5 | #include "bu/exceptionbase.h" | ||
| 6 | |||
| 7 | namespace Bu | ||
| 8 | { | ||
| 9 | template<typename value> | ||
| 10 | struct ListLink | ||
| 11 | { | ||
| 12 | value *pValue; | ||
| 13 | ListLink *pNext; | ||
| 14 | ListLink *pPrev; | ||
| 15 | }; | ||
| 16 | template<typename value, typename valuealloc=std::allocator<value>, typename linkalloc=std::allocator<struct ListLink<value> > > | ||
| 17 | class List | ||
| 18 | { | ||
| 19 | private: | ||
| 20 | typedef struct ListLink<value> Link; | ||
| 21 | typedef class List<value, valuealloc, linkalloc> MyType; | ||
| 22 | |||
| 23 | public: | ||
| 24 | List() : | ||
| 25 | pFirst( NULL ), | ||
| 26 | pLast( NULL ) | ||
| 27 | { | ||
| 28 | } | ||
| 29 | |||
| 30 | void append( value v ) | ||
| 31 | { | ||
| 32 | Link *pNew = la.allocate( sizeof( Link ) ); | ||
| 33 | pNew->pValue = va.allocate( sizeof( value ) ); | ||
| 34 | va.construct( pNew->pValue, v ); | ||
| 35 | if( pFirst == NULL ) | ||
| 36 | { | ||
| 37 | // Empty list | ||
| 38 | pFirst = pLast = pNew; | ||
| 39 | pNew->pNext = pNew->pPrev = NULL; | ||
| 40 | } | ||
| 41 | else | ||
| 42 | { | ||
| 43 | pNew->pNext = NULL; | ||
| 44 | pNew->pPrev = pLast; | ||
| 45 | pLast->pNext = pNew; | ||
| 46 | pLast = pNew; | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | void prepend( value v ) | ||
| 51 | { | ||
| 52 | Link *pNew = la.allocate( sizeof( Link ) ); | ||
| 53 | pNew->pValue = va.allocate( sizeof( value ) ); | ||
| 54 | va.construct( pNew->pValue, v ); | ||
| 55 | if( pFirst == NULL ) | ||
| 56 | { | ||
| 57 | // Empty list | ||
| 58 | pFirst = pLast = pNew; | ||
| 59 | pNew->pNext = pNew->pPrev = NULL; | ||
| 60 | } | ||
| 61 | else | ||
| 62 | { | ||
| 63 | pNew->pNext = pFirst; | ||
| 64 | pNew->pPrev = NULL; | ||
| 65 | pFirst->pPrev = pNew; | ||
| 66 | pFirst = pNew; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | typedef struct iterator | ||
| 71 | { | ||
| 72 | friend class List<value, valuealloc, linkalloc>; | ||
| 73 | private: | ||
| 74 | Link *pLink; | ||
| 75 | iterator() : | ||
| 76 | pLink( NULL ) | ||
| 77 | { | ||
| 78 | } | ||
| 79 | |||
| 80 | iterator( Link *pLink ) : | ||
| 81 | pLink( pLink ) | ||
| 82 | { | ||
| 83 | } | ||
| 84 | |||
| 85 | public: | ||
| 86 | bool operator==( const iterator &oth ) | ||
| 87 | { | ||
| 88 | return ( pLink == oth.pLink ); | ||
| 89 | } | ||
| 90 | |||
| 91 | bool operator==( const Link *pOth ) | ||
| 92 | { | ||
| 93 | return ( pLink == pOth ); | ||
| 94 | } | ||
| 95 | |||
| 96 | bool operator!=( const iterator &oth ) | ||
| 97 | { | ||
| 98 | return ( pLink != oth.pLink ); | ||
| 99 | } | ||
| 100 | |||
| 101 | bool operator!=( const Link *pOth ) | ||
| 102 | { | ||
| 103 | return ( pLink != pOth ); | ||
| 104 | } | ||
| 105 | |||
| 106 | value &operator*() | ||
| 107 | { | ||
| 108 | return *(pLink->pValue); | ||
| 109 | } | ||
| 110 | |||
| 111 | value *operator->() | ||
| 112 | { | ||
| 113 | return pLink->pValue(); | ||
| 114 | } | ||
| 115 | |||
| 116 | iterator operator++() | ||
| 117 | { | ||
| 118 | if( pLink != NULL ) | ||
| 119 | pLink = pLink->pNext; | ||
| 120 | return *this; | ||
| 121 | } | ||
| 122 | |||
| 123 | iterator operator--() | ||
| 124 | { | ||
| 125 | if( pLink != NULL ) | ||
| 126 | pLink = pLink->pPrev; | ||
| 127 | return *this; | ||
| 128 | } | ||
| 129 | |||
| 130 | iterator operator++( int ) | ||
| 131 | { | ||
| 132 | if( pLink != NULL ) | ||
| 133 | pLink = pLink->pNext; | ||
| 134 | return *this; | ||
| 135 | } | ||
| 136 | |||
| 137 | iterator operator--( int ) | ||
| 138 | { | ||
| 139 | if( pLink != NULL ) | ||
| 140 | pLink = pLink->pPrev; | ||
| 141 | return *this; | ||
| 142 | } | ||
| 143 | |||
| 144 | iterator operator=( const iterator &oth ) | ||
| 145 | { | ||
| 146 | pLink = oth.pLink; | ||
| 147 | } | ||
| 148 | }; | ||
| 149 | |||
| 150 | iterator begin() | ||
| 151 | { | ||
| 152 | return iterator( pFirst ); | ||
| 153 | } | ||
| 154 | |||
| 155 | const Link *end() | ||
| 156 | { | ||
| 157 | return NULL; | ||
| 158 | } | ||
| 159 | |||
| 160 | int getSize() | ||
| 161 | { | ||
| 162 | int j = 0; | ||
| 163 | for( Link *pCur = pFirst; pCur; pCur = pCur->pNext ) | ||
| 164 | j++; | ||
| 165 | return j; | ||
| 166 | } | ||
| 167 | |||
| 168 | private: | ||
| 169 | Link *pFirst; | ||
| 170 | Link *pLast; | ||
| 171 | linkalloc la; | ||
| 172 | valuealloc va; | ||
| 173 | }; | ||
| 174 | } | ||
| 175 | |||
| 176 | #endif | ||
diff --git a/src/tests/list.cpp b/src/tests/list.cpp new file mode 100644 index 0000000..34ab656 --- /dev/null +++ b/src/tests/list.cpp | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | #include "bu/list.h" | ||
| 2 | |||
| 3 | int main() | ||
| 4 | { | ||
| 5 | Bu::List<int> l; | ||
| 6 | |||
| 7 | l.append( 0 ); | ||
| 8 | |||
| 9 | for( int j = 3; j <= 21; j += 3 ) | ||
| 10 | { | ||
| 11 | l.append( j ); | ||
| 12 | l.prepend( -j ); | ||
| 13 | } | ||
| 14 | |||
| 15 | for( Bu::List<int>::iterator i = l.begin(); i != l.end(); i++ ) | ||
| 16 | { | ||
| 17 | printf("%d ", *i ); | ||
| 18 | } | ||
| 19 | |||
| 20 | printf("\n\n"); | ||
| 21 | } | ||
| 22 | |||
diff --git a/src/tests/xml.cpp b/src/tests/xml.cpp index 9ef6a7e..9689a28 100644 --- a/src/tests/xml.cpp +++ b/src/tests/xml.cpp | |||
| @@ -6,9 +6,9 @@ | |||
| 6 | int main() | 6 | int main() |
| 7 | { | 7 | { |
| 8 | Bu::File f("test.xml", "r"); | 8 | Bu::File f("test.xml", "r"); |
| 9 | Bu::XmlReader xr( f ); | 9 | XmlReader xr( f ); |
| 10 | 10 | ||
| 11 | xr.read(); | 11 | //xr.read(); |
| 12 | 12 | ||
| 13 | return 0; | 13 | return 0; |
| 14 | } | 14 | } |
diff --git a/src/xmldocument.cpp b/src/xmldocument.cpp index d7867d5..95b9788 100644 --- a/src/xmldocument.cpp +++ b/src/xmldocument.cpp | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #include <stdio.h> | 1 | #include <stdio.h> |
| 2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
| 3 | #include "xmlwriter.h" | 3 | #include "xmldocument.h" |
| 4 | 4 | ||
| 5 | XmlDocument::XmlDocument( XmlNode *pRoot ) | 5 | XmlDocument::XmlDocument( XmlNode *pRoot ) |
| 6 | { | 6 | { |
| @@ -17,28 +17,23 @@ XmlDocument::~XmlDocument() | |||
| 17 | } | 17 | } |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | void XmlDocument::addNode( const char *sName, const char *sContent, bool bClose ) | 20 | void XmlDocument::addNode( const Bu::FString &sName ) |
| 21 | { | 21 | { |
| 22 | if( pRoot == NULL ) | 22 | if( pRoot == NULL ) |
| 23 | { | 23 | { |
| 24 | // This is the first node, so ignore position and just insert it. | 24 | // This is the first node, so ignore position and just insert it. |
| 25 | pCurrent = pRoot = new XmlNode( sName, NULL, sContent ); | 25 | pCurrent = pRoot = new XmlNode( sName ); |
| 26 | } | 26 | } |
| 27 | else | 27 | else |
| 28 | { | 28 | { |
| 29 | pCurrent = pCurrent->addChild( sName, sContent ); | 29 | pCurrent = pCurrent->addChild( sName ); |
| 30 | } | ||
| 31 | |||
| 32 | if( bClose ) | ||
| 33 | { | ||
| 34 | closeNode(); | ||
| 35 | } | 30 | } |
| 36 | } | 31 | } |
| 37 | 32 | /* | |
| 38 | void XmlDocument::setName( const char *sName ) | 33 | void XmlDocument::setName( const char *sName ) |
| 39 | { | 34 | { |
| 40 | pCurrent->setName( sName ); | 35 | pCurrent->setName( sName ); |
| 41 | } | 36 | }*/ |
| 42 | 37 | ||
| 43 | bool XmlDocument::isCompleted() | 38 | bool XmlDocument::isCompleted() |
| 44 | { | 39 | { |
| @@ -143,7 +138,8 @@ void XmlDocument::setContent( const char *sContent ) | |||
| 143 | { | 138 | { |
| 144 | if( pCurrent ) | 139 | if( pCurrent ) |
| 145 | { | 140 | { |
| 146 | pCurrent->setContent( sContent ); | 141 | printf("XmlDocument::setContent: not yet implemented.\n"); |
| 142 | //pCurrent->setContent( sContent ); | ||
| 147 | } | 143 | } |
| 148 | } | 144 | } |
| 149 | 145 | ||
diff --git a/src/xmldocument.h b/src/xmldocument.h index 6671c41..e0c36eb 100644 --- a/src/xmldocument.h +++ b/src/xmldocument.h | |||
| @@ -39,13 +39,7 @@ public: | |||
| 39 | * the node and setting the content and name. If this is set to true the | 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. | 40 | * node is appended, but the context node doesn't change. |
| 41 | */ | 41 | */ |
| 42 | void addNode( const char *sName=NULL, const char *sContent=NULL, bool bClose=false ); | 42 | void addNode( const Bu::FString &sName ); |
| 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 | 43 | ||
| 50 | /** | 44 | /** |
| 51 | * Close the current node context. This will move the current context to | 45 | * Close the current node context. This will move the current context to |
diff --git a/src/xmlnode.cpp b/src/xmlnode.cpp index b1ed9a9..96d5850 100644 --- a/src/xmlnode.cpp +++ b/src/xmlnode.cpp | |||
| @@ -1,53 +1,15 @@ | |||
| 1 | #include "xmlnode.h" | 1 | #include "xmlnode.h" |
| 2 | #include "hashfunctionstring.h" | ||
| 3 | 2 | ||
| 4 | XmlNode::XmlNode( const char *sName, XmlNode *pParent, const char *sContent ) : | 3 | XmlNode::XmlNode( const Bu::FString &sName, XmlNode *pParent ) : |
| 5 | hProperties( new HashFunctionString(), 53, false ), | 4 | sName( sName ), |
| 6 | hChildren( new HashFunctionString(), 53, true ) | 5 | pParent( pParent ) |
| 7 | { | 6 | { |
| 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 | } | 7 | } |
| 23 | 8 | ||
| 24 | XmlNode::~XmlNode() | 9 | XmlNode::~XmlNode() |
| 25 | { | 10 | { |
| 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 | } | 11 | } |
| 50 | 12 | /* | |
| 51 | void XmlNode::setName( const char *sName ) | 13 | void XmlNode::setName( const char *sName ) |
| 52 | { | 14 | { |
| 53 | if( pParent ) | 15 | if( pParent ) |
| @@ -120,18 +82,18 @@ const char *XmlNode::getContent( int nIndex ) | |||
| 120 | } | 82 | } |
| 121 | 83 | ||
| 122 | return NULL; | 84 | return NULL; |
| 123 | } | 85 | }*/ |
| 124 | 86 | ||
| 125 | XmlNode *XmlNode::addChild( const char *sName, const char *sContent ) | 87 | XmlNode *XmlNode::addChild( const Bu::FString &sName ) |
| 126 | { | 88 | { |
| 127 | return addChild( new XmlNode( sName, this, sContent ) ); | 89 | return addChild( new XmlNode( sName, this ) ); |
| 128 | } | 90 | } |
| 129 | 91 | ||
| 130 | XmlNode *XmlNode::addChild( XmlNode *pNode ) | 92 | XmlNode *XmlNode::addChild( XmlNode *pNode ) |
| 131 | { | 93 | { |
| 132 | lChildren.append( pNode ); | 94 | Child c = { typeNode }; |
| 133 | lPostContent.append( NULL ); | 95 | c.pNode = pNode; |
| 134 | nCurContent++; | 96 | lChildren.append( c ); |
| 135 | pNode->pParent = this; | 97 | pNode->pParent = this; |
| 136 | 98 | ||
| 137 | return pNode; | 99 | return pNode; |
| @@ -142,21 +104,16 @@ XmlNode *XmlNode::getParent() | |||
| 142 | return pParent; | 104 | return pParent; |
| 143 | } | 105 | } |
| 144 | 106 | ||
| 145 | void XmlNode::addProperty( const char *sName, const char *sValue ) | 107 | void XmlNode::addProperty( const Bu::FString &sName, const Bu::FString &sValue ) |
| 146 | { | 108 | { |
| 147 | std::string *pName = new std::string( sName ); | 109 | hProperties.insert( sName, sValue ); |
| 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 | } | 110 | } |
| 154 | 111 | ||
| 155 | int XmlNode::getNumProperties() | 112 | int XmlNode::getNumProperties() |
| 156 | { | 113 | { |
| 157 | return lPropNames.getSize(); | 114 | return hProperties.size(); |
| 158 | } | 115 | } |
| 159 | 116 | /* | |
| 160 | const char *XmlNode::getPropertyName( int nIndex ) | 117 | const char *XmlNode::getPropertyName( int nIndex ) |
| 161 | { | 118 | { |
| 162 | std::string *tmp = ((std::string *)lPropNames[nIndex]); | 119 | std::string *tmp = ((std::string *)lPropNames[nIndex]); |
| @@ -172,15 +129,12 @@ const char *XmlNode::getProperty( int nIndex ) | |||
| 172 | return NULL; | 129 | return NULL; |
| 173 | return tmp->c_str(); | 130 | return tmp->c_str(); |
| 174 | } | 131 | } |
| 175 | 132 | */ | |
| 176 | const char *XmlNode::getProperty( const char *sName ) | 133 | Bu::FString XmlNode::getProperty( const Bu::FString &sName ) |
| 177 | { | 134 | { |
| 178 | const char *tmp = (const char *)hProperties[sName]; | 135 | return hProperties[sName]; |
| 179 | if( tmp == NULL ) | ||
| 180 | return NULL; | ||
| 181 | return tmp; | ||
| 182 | } | 136 | } |
| 183 | 137 | /* | |
| 184 | void XmlNode::deleteProperty( int nIndex ) | 138 | void XmlNode::deleteProperty( int nIndex ) |
| 185 | { | 139 | { |
| 186 | hProperties.del( ((std::string *)lPropNames[nIndex])->c_str() ); | 140 | hProperties.del( ((std::string *)lPropNames[nIndex])->c_str() ); |
| @@ -194,29 +148,33 @@ void XmlNode::deleteProperty( int nIndex ) | |||
| 194 | 148 | ||
| 195 | bool XmlNode::hasChildren() | 149 | bool XmlNode::hasChildren() |
| 196 | { | 150 | { |
| 197 | return lChildren.getSize()>0; | 151 | return hChildren.getSize()>0; |
| 198 | } | 152 | }*/ |
| 199 | 153 | ||
| 200 | int XmlNode::getNumChildren() | 154 | int XmlNode::getNumChildren() |
| 201 | { | 155 | { |
| 202 | return lChildren.getSize(); | 156 | return lChildren.getSize(); |
| 203 | } | 157 | } |
| 204 | 158 | /* | |
| 205 | XmlNode *XmlNode::getChild( int nIndex ) | 159 | XmlNode *XmlNode::getChild( int nIndex ) |
| 206 | { | 160 | { |
| 207 | return (XmlNode *)lChildren[nIndex]; | 161 | return (XmlNode *)lChildren[nIndex]; |
| 208 | } | 162 | } |
| 209 | 163 | */ | |
| 210 | XmlNode *XmlNode::getChild( const char *sName, int nSkip ) | 164 | XmlNode *XmlNode::getChild( const Bu::FString &sName, int nSkip ) |
| 211 | { | 165 | { |
| 212 | return (XmlNode *)hChildren.get( sName, nSkip ); | 166 | if( !hChildren.has( sName ) ) |
| 167 | return NULL; | ||
| 168 | |||
| 169 | Bu::List<XmlNode *>::iterator i = hChildren[sName]->begin(); | ||
| 170 | return *i; | ||
| 213 | } | 171 | } |
| 214 | 172 | ||
| 215 | const char *XmlNode::getName() | 173 | Bu::FString XmlNode::getName() |
| 216 | { | 174 | { |
| 217 | return sName.c_str(); | 175 | return sName; |
| 218 | } | 176 | } |
| 219 | 177 | /* | |
| 220 | void XmlNode::deleteNode( int nIndex, const char *sReplacementText ) | 178 | void XmlNode::deleteNode( int nIndex, const char *sReplacementText ) |
| 221 | { | 179 | { |
| 222 | XmlNode *xRet = detatchNode( nIndex, sReplacementText ); | 180 | XmlNode *xRet = detatchNode( nIndex, sReplacementText ); |
| @@ -442,4 +400,4 @@ void XmlNode::deleteNodeKeepChildren( int nIndex ) | |||
| 442 | void XmlNode::replaceNodeWithChildren( int nIndex, XmlNode *pNewNode ) | 400 | void XmlNode::replaceNodeWithChildren( int nIndex, XmlNode *pNewNode ) |
| 443 | { | 401 | { |
| 444 | } | 402 | } |
| 445 | 403 | */ | |
diff --git a/src/xmlnode.h b/src/xmlnode.h index 7525306..c895cd8 100644 --- a/src/xmlnode.h +++ b/src/xmlnode.h | |||
| @@ -2,8 +2,9 @@ | |||
| 2 | #define XMLNODE | 2 | #define XMLNODE |
| 3 | 3 | ||
| 4 | #include <iostream> | 4 | #include <iostream> |
| 5 | #include "linkedlist.h" | 5 | #include "bu/list.h" |
| 6 | #include "hashtable.h" | 6 | #include "bu/hash.h" |
| 7 | #include "bu/fstring.h" | ||
| 7 | 8 | ||
| 8 | /** | 9 | /** |
| 9 | * Maintains all data pertient to an XML node, including sub-nodes and content. | 10 | * Maintains all data pertient to an XML node, including sub-nodes and content. |
| @@ -25,9 +26,8 @@ public: | |||
| 25 | *@param sContent The initial content string. | 26 | *@param sContent The initial content string. |
| 26 | */ | 27 | */ |
| 27 | XmlNode( | 28 | XmlNode( |
| 28 | const char *sName=NULL, | 29 | const Bu::FString &sName, |
| 29 | XmlNode *pParent = NULL, | 30 | XmlNode *pParent=NULL |
| 30 | const char *sContent=NULL | ||
| 31 | ); | 31 | ); |
| 32 | 32 | ||
| 33 | /** | 33 | /** |
| @@ -39,7 +39,7 @@ public: | |||
| 39 | * Change the name of the node. | 39 | * Change the name of the node. |
| 40 | *@param sName The new name of the node. | 40 | *@param sName The new name of the node. |
| 41 | */ | 41 | */ |
| 42 | void setName( const char *sName ); | 42 | //void setName( const char *sName ); |
| 43 | 43 | ||
| 44 | /** | 44 | /** |
| 45 | * Construct a new node and add it as a child to this node, also return a | 45 | * Construct a new node and add it as a child to this node, also return a |
| @@ -48,7 +48,7 @@ public: | |||
| 48 | *@param sContent The initial content of the new node. | 48 | *@param sContent The initial content of the new node. |
| 49 | *@returns A pointer to the newly created child node. | 49 | *@returns A pointer to the newly created child node. |
| 50 | */ | 50 | */ |
| 51 | XmlNode *addChild( const char *sName, const char *sContent=NULL ); | 51 | XmlNode *addChild( const Bu::FString &sName ); |
| 52 | 52 | ||
| 53 | /** | 53 | /** |
| 54 | * Add an already created XmlNode as a child to this node. The new child | 54 | * Add an already created XmlNode as a child to this node. The new child |
| @@ -65,7 +65,7 @@ public: | |||
| 65 | * in use will overwrite that property. | 65 | * in use will overwrite that property. |
| 66 | *@param sValue The textual value of the property. | 66 | *@param sValue The textual value of the property. |
| 67 | */ | 67 | */ |
| 68 | void addProperty( const char *sName, const char *sValue ); | 68 | void addProperty( const Bu::FString &sName, const Bu::FString &sValue ); |
| 69 | 69 | ||
| 70 | /** | 70 | /** |
| 71 | * Get a pointer to the parent node, if any. | 71 | * Get a pointer to the parent node, if any. |
| @@ -86,14 +86,6 @@ public: | |||
| 86 | int getNumChildren(); | 86 | int getNumChildren(); |
| 87 | 87 | ||
| 88 | /** | 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 | 89 | * Get a child with the specified name, and possibly skip value. For an |
| 98 | * explination of skip values see the HashTable. | 90 | * explination of skip values see the HashTable. |
| 99 | *@param sName The name of the child to find. | 91 | *@param sName The name of the child to find. |
| @@ -101,14 +93,14 @@ public: | |||
| 101 | *@returns A pointer to the child, or NULL if no child with that name was | 93 | *@returns A pointer to the child, or NULL if no child with that name was |
| 102 | * found. | 94 | * found. |
| 103 | */ | 95 | */ |
| 104 | XmlNode *getChild( const char *sName, int nSkip=0 ); | 96 | XmlNode *getChild( const Bu::FString &sName, int nSkip=0 ); |
| 105 | 97 | ||
| 106 | /** | 98 | /** |
| 107 | * Get a pointer to the name of this node. Do not change this, use setName | 99 | * Get a pointer to the name of this node. Do not change this, use setName |
| 108 | * instead. | 100 | * instead. |
| 109 | *@returns A pointer to the name of this node. | 101 | *@returns A pointer to the name of this node. |
| 110 | */ | 102 | */ |
| 111 | const char *getName(); | 103 | Bu::FString getName(); |
| 112 | 104 | ||
| 113 | /** | 105 | /** |
| 114 | * Set the content of this node, optionally at a specific index. Using the | 106 | * Set the content of this node, optionally at a specific index. Using the |
| @@ -116,14 +108,7 @@ public: | |||
| 116 | *@param sContent The content string to use. | 108 | *@param sContent The content string to use. |
| 117 | *@param nIndex The index of the content. | 109 | *@param nIndex The index of the content. |
| 118 | */ | 110 | */ |
| 119 | void setContent( const char *sContent, int nIndex=-1 ); | 111 | //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 | 112 | ||
| 128 | /** | 113 | /** |
| 129 | * Get the number of properties in this node. | 114 | * Get the number of properties in this node. |
| @@ -132,36 +117,12 @@ public: | |||
| 132 | int getNumProperties(); | 117 | int getNumProperties(); |
| 133 | 118 | ||
| 134 | /** | 119 | /** |
| 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. | 120 | * Get a propery's value by name. |
| 152 | *@param sName The name of the property to examine. | 121 | *@param sName The name of the property to examine. |
| 153 | *@returns A pointer to the value of the property specified, or NULL if none | 122 | *@returns A pointer to the value of the property specified, or NULL if none |
| 154 | * found. | 123 | * found. |
| 155 | */ | 124 | */ |
| 156 | const char *getProperty( const char *sName ); | 125 | Bu::FString getProperty( const Bu::FString &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 | 126 | ||
| 166 | /** | 127 | /** |
| 167 | * Delete a child node, possibly replacing it with some text. This actually | 128 | * Delete a child node, possibly replacing it with some text. This actually |
| @@ -171,7 +132,7 @@ public: | |||
| 171 | *@returns True of the node was found, and deleted, false if it wasn't | 132 | *@returns True of the node was found, and deleted, false if it wasn't |
| 172 | * found. | 133 | * found. |
| 173 | */ | 134 | */ |
| 174 | void deleteNode( int nIndex, const char *sReplacementText = NULL ); | 135 | //void deleteNode( int nIndex, const char *sReplacementText = NULL ); |
| 175 | 136 | ||
| 176 | /** | 137 | /** |
| 177 | * Delete a given node, but move all of it's children and content up to | 138 | * Delete a given node, but move all of it's children and content up to |
| @@ -180,7 +141,7 @@ public: | |||
| 180 | *@param nIndex The node to delete. | 141 | *@param nIndex The node to delete. |
| 181 | *@returns True if the node was found and deleted, false if it wasn't. | 142 | *@returns True if the node was found and deleted, false if it wasn't. |
| 182 | */ | 143 | */ |
| 183 | void deleteNodeKeepChildren( int nIndex ); | 144 | //void deleteNodeKeepChildren( int nIndex ); |
| 184 | 145 | ||
| 185 | /** | 146 | /** |
| 186 | * Detatch a given child node from this node. This effectively works just | 147 | * Detatch a given child node from this node. This effectively works just |
| @@ -192,7 +153,7 @@ public: | |||
| 192 | *@returns A pointer to the newly detatched node, which then passes | 153 | *@returns A pointer to the newly detatched node, which then passes |
| 193 | * ownership to the caller. | 154 | * ownership to the caller. |
| 194 | */ | 155 | */ |
| 195 | XmlNode *detatchNode( int nIndex, const char *sReplacementText = NULL ); | 156 | //XmlNode *detatchNode( int nIndex, const char *sReplacementText = NULL ); |
| 196 | 157 | ||
| 197 | /** | 158 | /** |
| 198 | * Replace a given node with a different node that is not currently owned by | 159 | * Replace a given node with a different node that is not currently owned by |
| @@ -201,7 +162,7 @@ public: | |||
| 201 | *@param pNewNode The new node to replace the old node with. | 162 | *@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. | 163 | *@returns True if the node was found and replaced, false if it wasn't. |
| 203 | */ | 164 | */ |
| 204 | void replaceNode( int nIndex, XmlNode *pNewNode ); | 165 | //void replaceNode( int nIndex, XmlNode *pNewNode ); |
| 205 | 166 | ||
| 206 | /** | 167 | /** |
| 207 | * Replace a given node with the children and content of a given node. | 168 | * Replace a given node with the children and content of a given node. |
| @@ -210,24 +171,34 @@ public: | |||
| 210 | * replace the node specified by nIndex. | 171 | * replace the node specified by nIndex. |
| 211 | *@returns True if the node was found and replaced, false if it wasn't. | 172 | *@returns True if the node was found and replaced, false if it wasn't. |
| 212 | */ | 173 | */ |
| 213 | void replaceNodeWithChildren( int nIndex, XmlNode *pNewNode ); | 174 | //void replaceNodeWithChildren( int nIndex, XmlNode *pNewNode ); |
| 214 | 175 | ||
| 215 | /** | 176 | /** |
| 216 | * Get a copy of this node and all children. getCopy is recursive, so | 177 | * Get a copy of this node and all children. getCopy is recursive, so |
| 217 | * beware copying large trees of xml. | 178 | * beware copying large trees of xml. |
| 218 | *@returns A newly created copy of this node and all of it's children. | 179 | *@returns A newly created copy of this node and all of it's children. |
| 219 | */ | 180 | */ |
| 220 | XmlNode *getCopy(); | 181 | //XmlNode *getCopy(); |
| 182 | |||
| 183 | enum ChildType | ||
| 184 | { | ||
| 185 | typeNode, | ||
| 186 | typeContent | ||
| 187 | }; | ||
| 221 | 188 | ||
| 222 | private: | 189 | private: |
| 223 | std::string sName; /**< The name of the node. */ | 190 | typedef struct |
| 224 | std::string *sPreContent; /**< The content that goes before any node. */ | 191 | { |
| 225 | LinkedList lChildren; /**< The children. */ | 192 | uint8_t nType; |
| 226 | LinkedList lPostContent; /**< The content that comes after children. */ | 193 | union { |
| 227 | HashTable hProperties; /**< Property hashtable. */ | 194 | XmlNode *pNode; |
| 228 | HashTable hChildren; /**< Children hashtable. */ | 195 | Bu::FString *pContent; |
| 229 | LinkedList lPropNames; /**< List of property names. */ | 196 | }; |
| 230 | LinkedList lPropValues; /**< List of property values. */ | 197 | } Child; |
| 198 | Bu::FString sName; /**< The name of the node. */ | ||
| 199 | Bu::List<Child> lChildren; /**< The children. */ | ||
| 200 | Bu::Hash<Bu::FString, Bu::FString> hProperties; /**< Property hashtable. */ | ||
| 201 | Bu::Hash<Bu::FString, Bu::List<XmlNode *> > hChildren; /**< Children hashtable. */ | ||
| 231 | XmlNode *pParent; /**< A pointer to the parent of this node. */ | 202 | XmlNode *pParent; /**< A pointer to the parent of this node. */ |
| 232 | int nCurContent; /**< The current content we're on, for using the -1 on | 203 | int nCurContent; /**< The current content we're on, for using the -1 on |
| 233 | setContent. */ | 204 | setContent. */ |
diff --git a/src/xmlreader.cpp b/src/xmlreader.cpp index 18df69c..38cad5f 100644 --- a/src/xmlreader.cpp +++ b/src/xmlreader.cpp | |||
| @@ -1,32 +1,49 @@ | |||
| 1 | #include "xmlreader.h" | 1 | #include "bu/xmlreader.h" |
| 2 | #include "exceptions.h" | 2 | #include "bu/exceptions.h" |
| 3 | #include <string.h> | 3 | #include <string.h> |
| 4 | #include "hashfunctionstring.h" | ||
| 5 | 4 | ||
| 6 | XmlReader::XmlReader( bool bStrip ) : | 5 | XmlReader::XmlReader( Bu::Stream &sIn, bool bStrip ) : |
| 7 | bStrip( bStrip ), | 6 | sIn( sIn ), |
| 8 | htEntity( new HashFunctionString(), 11 ) | 7 | bStrip( bStrip ) |
| 9 | { | 8 | { |
| 9 | buildDoc(); | ||
| 10 | } | 10 | } |
| 11 | 11 | ||
| 12 | XmlReader::~XmlReader() | 12 | XmlReader::~XmlReader() |
| 13 | { | 13 | { |
| 14 | void *i = htEntity.getFirstItemPos(); | 14 | } |
| 15 | while( (i = htEntity.getNextItemPos( i ) ) ) | 15 | |
| 16 | char XmlReader::getChar( int nIndex ) | ||
| 17 | { | ||
| 18 | if( sBuf.getSize() <= nIndex ) | ||
| 16 | { | 19 | { |
| 17 | free( (char *)(htEntity.getItemID( i )) ); | 20 | int nInc = nIndex-sBuf.getSize()+1; |
| 18 | delete (StaticString *)htEntity.getItemData( i ); | 21 | char *buf = new char[nInc]; |
| 22 | sIn.read( buf, nInc ); | ||
| 23 | sBuf.append( buf, nInc ); | ||
| 24 | delete[] buf; | ||
| 19 | } | 25 | } |
| 26 | |||
| 27 | return sBuf[nIndex]; | ||
| 20 | } | 28 | } |
| 21 | 29 | ||
| 22 | void XmlReader::addEntity( const char *name, const char *value ) | 30 | void XmlReader::usedChar( int nAmnt ) |
| 23 | { | 31 | { |
| 24 | if( htEntity[name] ) return; | 32 | if( nAmnt >= sBuf.getSize() ) |
| 25 | 33 | { | |
| 26 | char *sName = strdup( name ); | 34 | sBuf.clear(); |
| 27 | StaticString *sValue = new StaticString( value ); | 35 | } |
| 36 | else | ||
| 37 | { | ||
| 38 | char *s = sBuf.getStr(); | ||
| 39 | memcpy( s, s+nAmnt, sBuf.getSize()-nAmnt ); | ||
| 40 | sBuf.resize( sBuf.getSize()-nAmnt ); | ||
| 41 | } | ||
| 42 | } | ||
| 28 | 43 | ||
| 29 | htEntity.insert( sName, sValue ); | 44 | void XmlReader::addEntity( const Bu::FString &name, const Bu::FString &value ) |
| 45 | { | ||
| 46 | htEntity[name] = value; | ||
| 30 | } | 47 | } |
| 31 | 48 | ||
| 32 | #define gcall( x ) if( x == false ) return false; | 49 | #define gcall( x ) if( x == false ) return false; |
| @@ -99,7 +116,7 @@ void XmlReader::entity() | |||
| 99 | { | 116 | { |
| 100 | usedChar( 2 ); | 117 | usedChar( 2 ); |
| 101 | ws(); | 118 | ws(); |
| 102 | std::string buf; | 119 | Bu::FString buf; |
| 103 | for(;;) | 120 | for(;;) |
| 104 | { | 121 | { |
| 105 | char chr = getChar(); | 122 | char chr = getChar(); |
| @@ -111,7 +128,7 @@ void XmlReader::entity() | |||
| 111 | if( strcmp( buf.c_str(), "ENTITY") == 0 ) | 128 | if( strcmp( buf.c_str(), "ENTITY") == 0 ) |
| 112 | { | 129 | { |
| 113 | ws(); | 130 | ws(); |
| 114 | std::string name; | 131 | Bu::FString name; |
| 115 | for(;;) | 132 | for(;;) |
| 116 | { | 133 | { |
| 117 | char chr = getChar(); | 134 | char chr = getChar(); |
| @@ -124,21 +141,19 @@ void XmlReader::entity() | |||
| 124 | usedChar(); | 141 | usedChar(); |
| 125 | if( quot != '\'' && quot != '\"' ) | 142 | if( quot != '\'' && quot != '\"' ) |
| 126 | { | 143 | { |
| 127 | throw XmlException( | 144 | throw Bu::XmlException( |
| 128 | "Only quoted entity values are supported." | 145 | "Only quoted entity values are supported." |
| 129 | ); | 146 | ); |
| 130 | } | 147 | } |
| 131 | std::string value; | 148 | Bu::FString value; |
| 132 | for(;;) | 149 | for(;;) |
| 133 | { | 150 | { |
| 134 | char chr = getChar(); | 151 | char chr = getChar(); |
| 135 | usedChar(); | 152 | usedChar(); |
| 136 | if( chr == '&' ) | 153 | if( chr == '&' ) |
| 137 | { | 154 | { |
| 138 | StaticString *tmp = getEscape(); | 155 | Bu::FString tmp = getEscape(); |
| 139 | if( tmp == NULL ) throw XmlException("Entity thing"); | 156 | value += tmp; |
| 140 | value += tmp->getString(); | ||
| 141 | delete tmp; | ||
| 142 | } | 157 | } |
| 143 | else if( chr == quot ) | 158 | else if( chr == quot ) |
| 144 | { | 159 | { |
| @@ -158,7 +173,7 @@ void XmlReader::entity() | |||
| 158 | } | 173 | } |
| 159 | else | 174 | else |
| 160 | { | 175 | { |
| 161 | throw XmlException( | 176 | throw Bu::XmlException( |
| 162 | "Malformed ENTITY: unexpected '%c' found.", | 177 | "Malformed ENTITY: unexpected '%c' found.", |
| 163 | getChar() | 178 | getChar() |
| 164 | ); | 179 | ); |
| @@ -166,7 +181,7 @@ void XmlReader::entity() | |||
| 166 | } | 181 | } |
| 167 | else | 182 | else |
| 168 | { | 183 | { |
| 169 | throw XmlException( | 184 | throw Bu::XmlException( |
| 170 | "Unsupported header symbol: %s", | 185 | "Unsupported header symbol: %s", |
| 171 | buf.c_str() | 186 | buf.c_str() |
| 172 | ); | 187 | ); |
| @@ -203,12 +218,12 @@ bool XmlReader::node() | |||
| 203 | } | 218 | } |
| 204 | else | 219 | else |
| 205 | { | 220 | { |
| 206 | throw XmlException("Close node in singleNode malformed!"); | 221 | throw Bu::XmlException("Close node in singleNode malformed!"); |
| 207 | } | 222 | } |
| 208 | } | 223 | } |
| 209 | else | 224 | else |
| 210 | { | 225 | { |
| 211 | throw XmlException("Close node expected, but not found."); | 226 | throw Bu::XmlException("Close node expected, but not found."); |
| 212 | return false; | 227 | return false; |
| 213 | } | 228 | } |
| 214 | 229 | ||
| @@ -224,7 +239,7 @@ bool XmlReader::startNode() | |||
| 224 | if( getChar() == '/' ) | 239 | if( getChar() == '/' ) |
| 225 | { | 240 | { |
| 226 | // Heh, it's actually a close node, go figure | 241 | // Heh, it's actually a close node, go figure |
| 227 | FlexBuf fbName; | 242 | Bu::FString sName; |
| 228 | usedChar(); | 243 | usedChar(); |
| 229 | gcall( ws() ); | 244 | gcall( ws() ); |
| 230 | 245 | ||
| @@ -235,19 +250,19 @@ bool XmlReader::startNode() | |||
| 235 | { | 250 | { |
| 236 | // Here we actually compare the name we got to the name | 251 | // Here we actually compare the name we got to the name |
| 237 | // we already set, they have to match exactly. | 252 | // we already set, they have to match exactly. |
| 238 | if( !strcasecmp( getCurrent()->getName(), fbName.getData() ) ) | 253 | if( getCurrent()->getName() == sName ) |
| 239 | { | 254 | { |
| 240 | closeNode(); | 255 | closeNode(); |
| 241 | break; | 256 | break; |
| 242 | } | 257 | } |
| 243 | else | 258 | else |
| 244 | { | 259 | { |
| 245 | throw XmlException("Got a mismatched node close tag."); | 260 | throw Bu::XmlException("Got a mismatched node close tag."); |
| 246 | } | 261 | } |
| 247 | } | 262 | } |
| 248 | else | 263 | else |
| 249 | { | 264 | { |
| 250 | fbName.appendData( chr ); | 265 | sName += chr; |
| 251 | usedChar(); | 266 | usedChar(); |
| 252 | } | 267 | } |
| 253 | } | 268 | } |
| @@ -260,13 +275,13 @@ bool XmlReader::startNode() | |||
| 260 | } | 275 | } |
| 261 | else | 276 | else |
| 262 | { | 277 | { |
| 263 | throw XmlException("Got extra junk data instead of node close tag."); | 278 | throw Bu::XmlException("Got extra junk data instead of node close tag."); |
| 264 | } | 279 | } |
| 265 | } | 280 | } |
| 266 | else | 281 | else |
| 267 | { | 282 | { |
| 268 | // We're good, format is consistant | 283 | // We're good, format is consistant |
| 269 | addNode(); | 284 | //addNode(); |
| 270 | 285 | ||
| 271 | // Skip extra whitespace | 286 | // Skip extra whitespace |
| 272 | gcall( ws() ); | 287 | gcall( ws() ); |
| @@ -278,7 +293,7 @@ bool XmlReader::startNode() | |||
| 278 | } | 293 | } |
| 279 | else | 294 | else |
| 280 | { | 295 | { |
| 281 | throw XmlException("Expected to find node opening char, '<'."); | 296 | throw Bu::XmlException("Expected to find node opening char, '<'."); |
| 282 | } | 297 | } |
| 283 | 298 | ||
| 284 | return true; | 299 | return true; |
| @@ -286,19 +301,19 @@ bool XmlReader::startNode() | |||
| 286 | 301 | ||
| 287 | bool XmlReader::name() | 302 | bool XmlReader::name() |
| 288 | { | 303 | { |
| 289 | FlexBuf fbName; | 304 | Bu::FString sName; |
| 290 | 305 | ||
| 291 | while( true ) | 306 | while( true ) |
| 292 | { | 307 | { |
| 293 | char chr = getChar(); | 308 | char chr = getChar(); |
| 294 | if( isws( chr ) || chr == '>' || chr == '/' ) | 309 | if( isws( chr ) || chr == '>' || chr == '/' ) |
| 295 | { | 310 | { |
| 296 | setName( fbName.getData() ); | 311 | addNode( sName ); |
| 297 | return true; | 312 | return true; |
| 298 | } | 313 | } |
| 299 | else | 314 | else |
| 300 | { | 315 | { |
| 301 | fbName.appendData( chr ); | 316 | sName += chr; |
| 302 | usedChar(); | 317 | usedChar(); |
| 303 | } | 318 | } |
| 304 | } | 319 | } |
| @@ -325,7 +340,7 @@ bool XmlReader::paramlist() | |||
| 325 | return true; | 340 | return true; |
| 326 | } | 341 | } |
| 327 | 342 | ||
| 328 | StaticString *XmlReader::getEscape() | 343 | Bu::FString XmlReader::getEscape() |
| 329 | { | 344 | { |
| 330 | if( getChar( 1 ) == '#' ) | 345 | if( getChar( 1 ) == '#' ) |
| 331 | { | 346 | { |
| @@ -349,12 +364,12 @@ StaticString *XmlReader::getEscape() | |||
| 349 | buf[0] = (char)strtol( buf, (char **)NULL, base ); | 364 | buf[0] = (char)strtol( buf, (char **)NULL, base ); |
| 350 | buf[1] = '\0'; | 365 | buf[1] = '\0'; |
| 351 | 366 | ||
| 352 | return new StaticString( buf ); | 367 | return buf; |
| 353 | } | 368 | } |
| 354 | else | 369 | else |
| 355 | { | 370 | { |
| 356 | // ...otherwise replace with the appropriate string... | 371 | // ...otherwise replace with the appropriate string... |
| 357 | std::string buf; | 372 | Bu::FString buf; |
| 358 | usedChar(); | 373 | usedChar(); |
| 359 | for(;;) | 374 | for(;;) |
| 360 | { | 375 | { |
| @@ -364,18 +379,14 @@ StaticString *XmlReader::getEscape() | |||
| 364 | buf += cbuf; | 379 | buf += cbuf; |
| 365 | } | 380 | } |
| 366 | 381 | ||
| 367 | StaticString *tmp = (StaticString *)htEntity[buf.c_str()]; | 382 | return htEntity[buf]; |
| 368 | if( tmp == NULL ) return NULL; | ||
| 369 | |||
| 370 | StaticString *ret = new StaticString( *tmp ); | ||
| 371 | return ret; | ||
| 372 | } | 383 | } |
| 373 | } | 384 | } |
| 374 | 385 | ||
| 375 | bool XmlReader::param() | 386 | bool XmlReader::param() |
| 376 | { | 387 | { |
| 377 | FlexBuf fbName; | 388 | Bu::FString sName; |
| 378 | FlexBuf fbValue; | 389 | Bu::FString sValue; |
| 379 | 390 | ||
| 380 | while( true ) | 391 | while( true ) |
| 381 | { | 392 | { |
| @@ -386,7 +397,7 @@ bool XmlReader::param() | |||
| 386 | } | 397 | } |
| 387 | else | 398 | else |
| 388 | { | 399 | { |
| 389 | fbName.appendData( chr ); | 400 | sName.append( chr ); |
| 390 | usedChar(); | 401 | usedChar(); |
| 391 | } | 402 | } |
| 392 | } | 403 | } |
| @@ -411,21 +422,18 @@ bool XmlReader::param() | |||
| 411 | if( chr == '"' ) | 422 | if( chr == '"' ) |
| 412 | { | 423 | { |
| 413 | usedChar(); | 424 | usedChar(); |
| 414 | addProperty( fbName.getData(), fbValue.getData() ); | 425 | addProperty( sName.getStr(), sValue.getStr() ); |
| 415 | return true; | 426 | return true; |
| 416 | } | 427 | } |
| 417 | else | 428 | else |
| 418 | { | 429 | { |
| 419 | if( chr == '&' ) | 430 | if( chr == '&' ) |
| 420 | { | 431 | { |
| 421 | StaticString *tmp = getEscape(); | 432 | sValue += getEscape(); |
| 422 | if( tmp == NULL ) return false; | ||
| 423 | fbValue.appendData( tmp->getString() ); | ||
| 424 | delete tmp; | ||
| 425 | } | 433 | } |
| 426 | else | 434 | else |
| 427 | { | 435 | { |
| 428 | fbValue.appendData( chr ); | 436 | sValue += chr; |
| 429 | usedChar(); | 437 | usedChar(); |
| 430 | } | 438 | } |
| 431 | } | 439 | } |
| @@ -439,21 +447,18 @@ bool XmlReader::param() | |||
| 439 | chr = getChar(); | 447 | chr = getChar(); |
| 440 | if( isws( chr ) || chr == '/' || chr == '>' ) | 448 | if( isws( chr ) || chr == '/' || chr == '>' ) |
| 441 | { | 449 | { |
| 442 | addProperty( fbName.getData(), fbValue.getData() ); | 450 | addProperty( sName.getStr(), sValue.getStr() ); |
| 443 | return true; | 451 | return true; |
| 444 | } | 452 | } |
| 445 | else | 453 | else |
| 446 | { | 454 | { |
| 447 | if( chr == '&' ) | 455 | if( chr == '&' ) |
| 448 | { | 456 | { |
| 449 | StaticString *tmp = getEscape(); | 457 | sValue += getEscape(); |
| 450 | if( tmp == NULL ) return false; | ||
| 451 | fbValue.appendData( tmp->getString() ); | ||
| 452 | delete tmp; | ||
| 453 | } | 458 | } |
| 454 | else | 459 | else |
| 455 | { | 460 | { |
| 456 | fbValue.appendData( chr ); | 461 | sValue += chr; |
| 457 | usedChar(); | 462 | usedChar(); |
| 458 | } | 463 | } |
| 459 | } | 464 | } |
| @@ -462,7 +467,7 @@ bool XmlReader::param() | |||
| 462 | } | 467 | } |
| 463 | else | 468 | else |
| 464 | { | 469 | { |
| 465 | throw XmlException("Expected an equals to seperate the params."); | 470 | throw Bu::XmlException("Expected an equals to seperate the params."); |
| 466 | return false; | 471 | return false; |
| 467 | } | 472 | } |
| 468 | 473 | ||
| @@ -471,7 +476,7 @@ bool XmlReader::param() | |||
| 471 | 476 | ||
| 472 | bool XmlReader::content() | 477 | bool XmlReader::content() |
| 473 | { | 478 | { |
| 474 | FlexBuf fbContent; | 479 | Bu::FString sContent; |
| 475 | 480 | ||
| 476 | if( bStrip ) gcall( ws() ); | 481 | if( bStrip ) gcall( ws() ); |
| 477 | 482 | ||
| @@ -482,37 +487,37 @@ bool XmlReader::content() | |||
| 482 | { | 487 | { |
| 483 | if( getChar(1) == '/' ) | 488 | if( getChar(1) == '/' ) |
| 484 | { | 489 | { |
| 485 | if( fbContent.getLength() > 0 ) | 490 | if( sContent.getSize() > 0 ) |
| 486 | { | 491 | { |
| 487 | if( bStrip ) | 492 | if( bStrip ) |
| 488 | { | 493 | { |
| 489 | int j; | 494 | int j; |
| 490 | for( j = fbContent.getLength()-1; isws(fbContent.getData()[j]); j-- ); | 495 | for( j = sContent.getSize()-1; isws(sContent[j]); j-- ); |
| 491 | ((char *)fbContent.getData())[j+1] = '\0'; | 496 | sContent[j+1] = '\0'; |
| 492 | } | 497 | } |
| 493 | setContent( fbContent.getData() ); | 498 | setContent( sContent.getStr() ); |
| 494 | } | 499 | } |
| 495 | usedChar( 2 ); | 500 | usedChar( 2 ); |
| 496 | gcall( ws() ); | 501 | gcall( ws() ); |
| 497 | FlexBuf fbName; | 502 | Bu::FString sName; |
| 498 | while( true ) | 503 | while( true ) |
| 499 | { | 504 | { |
| 500 | chr = getChar(); | 505 | chr = getChar(); |
| 501 | if( isws( chr ) || chr == '>' ) | 506 | if( isws( chr ) || chr == '>' ) |
| 502 | { | 507 | { |
| 503 | if( !strcasecmp( getCurrent()->getName(), fbName.getData() ) ) | 508 | if( !strcasecmp( getCurrent()->getName().getStr(), sName.getStr() ) ) |
| 504 | { | 509 | { |
| 505 | closeNode(); | 510 | closeNode(); |
| 506 | break; | 511 | break; |
| 507 | } | 512 | } |
| 508 | else | 513 | else |
| 509 | { | 514 | { |
| 510 | throw XmlException("Mismatched close tag found: <%s> to <%s>.", getCurrent()->getName(), fbName.getData() ); | 515 | throw Bu::XmlException("Mismatched close tag found: <%s> to <%s>.", getCurrent()->getName().getStr(), sName.getStr() ); |
| 511 | } | 516 | } |
| 512 | } | 517 | } |
| 513 | else | 518 | else |
| 514 | { | 519 | { |
| 515 | fbName.appendData( chr ); | 520 | sName += chr; |
| 516 | usedChar(); | 521 | usedChar(); |
| 517 | } | 522 | } |
| 518 | } | 523 | } |
| @@ -524,7 +529,7 @@ bool XmlReader::content() | |||
| 524 | } | 529 | } |
| 525 | else | 530 | else |
| 526 | { | 531 | { |
| 527 | throw XmlException("Malformed close tag."); | 532 | throw Bu::XmlException("Malformed close tag."); |
| 528 | } | 533 | } |
| 529 | } | 534 | } |
| 530 | else if( getChar(1) == '!' ) | 535 | else if( getChar(1) == '!' ) |
| @@ -534,7 +539,7 @@ bool XmlReader::content() | |||
| 534 | getChar(3) != '-' ) | 539 | getChar(3) != '-' ) |
| 535 | { | 540 | { |
| 536 | // Not a valid XML comment | 541 | // Not a valid XML comment |
| 537 | throw XmlException("Malformed comment start tag found."); | 542 | throw Bu::XmlException("Malformed comment start tag found."); |
| 538 | } | 543 | } |
| 539 | 544 | ||
| 540 | usedChar( 4 ); | 545 | usedChar( 4 ); |
| @@ -549,7 +554,7 @@ bool XmlReader::content() | |||
| 549 | // The next one has to be a '>' now | 554 | // The next one has to be a '>' now |
| 550 | if( getChar( 2 ) != '>' ) | 555 | if( getChar( 2 ) != '>' ) |
| 551 | { | 556 | { |
| 552 | throw XmlException("Malformed comment close tag found. You cannot have a '--' that isn't followed by a '>' in a comment."); | 557 | throw Bu::XmlException("Malformed comment close tag found. You cannot have a '--' that isn't followed by a '>' in a comment."); |
| 553 | } | 558 | } |
| 554 | usedChar( 3 ); | 559 | usedChar( 3 ); |
| 555 | break; | 560 | break; |
| @@ -569,16 +574,16 @@ bool XmlReader::content() | |||
| 569 | } | 574 | } |
| 570 | else | 575 | else |
| 571 | { | 576 | { |
| 572 | if( fbContent.getLength() > 0 ) | 577 | if( sContent.getSize() > 0 ) |
| 573 | { | 578 | { |
| 574 | if( bStrip ) | 579 | if( bStrip ) |
| 575 | { | 580 | { |
| 576 | int j; | 581 | int j; |
| 577 | for( j = fbContent.getLength()-1; isws(fbContent.getData()[j]); j-- ); | 582 | for( j = sContent.getSize()-1; isws(sContent[j]); j-- ); |
| 578 | ((char *)fbContent.getData())[j+1] = '\0'; | 583 | sContent[j+1] = '\0'; |
| 579 | } | 584 | } |
| 580 | setContent( fbContent.getData() ); | 585 | setContent( sContent.getStr() ); |
| 581 | fbContent.clearData(); | 586 | sContent.clear(); |
| 582 | } | 587 | } |
| 583 | gcall( node() ); | 588 | gcall( node() ); |
| 584 | } | 589 | } |
| @@ -587,14 +592,11 @@ bool XmlReader::content() | |||
| 587 | } | 592 | } |
| 588 | else if( chr == '&' ) | 593 | else if( chr == '&' ) |
| 589 | { | 594 | { |
| 590 | StaticString *tmp = getEscape(); | 595 | sContent += getEscape(); |
| 591 | if( tmp == NULL ) return false; | ||
| 592 | fbContent.appendData( tmp->getString() ); | ||
| 593 | delete tmp; | ||
| 594 | } | 596 | } |
| 595 | else | 597 | else |
| 596 | { | 598 | { |
| 597 | fbContent.appendData( chr ); | 599 | sContent += chr; |
| 598 | usedChar(); | 600 | usedChar(); |
| 599 | } | 601 | } |
| 600 | } | 602 | } |
diff --git a/src/xmlreader.h b/src/xmlreader.h index c8f7202..7c85ddb 100644 --- a/src/xmlreader.h +++ b/src/xmlreader.h | |||
| @@ -2,10 +2,10 @@ | |||
| 2 | #define XMLREADER | 2 | #define XMLREADER |
| 3 | 3 | ||
| 4 | #include <stdio.h> | 4 | #include <stdio.h> |
| 5 | #include "xmldocument.h" | 5 | #include "bu/xmldocument.h" |
| 6 | #include "flexbuf.h" | 6 | #include "bu/hash.h" |
| 7 | #include "hashtable.h" | 7 | #include "bu/fstring.h" |
| 8 | #include "staticstring.h" | 8 | #include "bu/stream.h" |
| 9 | 9 | ||
| 10 | /** | 10 | /** |
| 11 | * Takes care of reading in xml formatted data from a file. This could/should | 11 | * Takes care of reading in xml formatted data from a file. This could/should |
| @@ -32,7 +32,7 @@ public: | |||
| 32 | * in content, a-la html. | 32 | * in content, a-la html. |
| 33 | *@param bStrip Strip out leading and trailing whitespace? | 33 | *@param bStrip Strip out leading and trailing whitespace? |
| 34 | */ | 34 | */ |
| 35 | XmlReader( bool bStrip=false ); | 35 | XmlReader( Bu::Stream &sIn, bool bStrip=false ); |
| 36 | 36 | ||
| 37 | /** | 37 | /** |
| 38 | * Destroy this XmlReader. | 38 | * Destroy this XmlReader. |
| @@ -54,12 +54,12 @@ private: | |||
| 54 | *@returns A single character at the requested position, or 0 for end of | 54 | *@returns A single character at the requested position, or 0 for end of |
| 55 | * stream. | 55 | * stream. |
| 56 | */ | 56 | */ |
| 57 | virtual char getChar( int nIndex = 0 ) = 0; | 57 | virtual char getChar( int nIndex = 0 ); |
| 58 | 58 | ||
| 59 | /** | 59 | /** |
| 60 | * Called to increment the current stream position by a single character. | 60 | * Called to increment the current stream position by a single character. |
| 61 | */ | 61 | */ |
| 62 | virtual void usedChar( int nAmnt = 1) = 0; | 62 | virtual void usedChar( int nAmnt = 1 ); |
| 63 | 63 | ||
| 64 | /** | 64 | /** |
| 65 | * Automoton function: is whitespace. | 65 | * Automoton function: is whitespace. |
| @@ -108,9 +108,9 @@ private: | |||
| 108 | *@param name The name of the entity | 108 | *@param name The name of the entity |
| 109 | *@param value The value of the entity | 109 | *@param value The value of the entity |
| 110 | */ | 110 | */ |
| 111 | void addEntity( const char *name, const char *value ); | 111 | void addEntity( const Bu::FString &name, const Bu::FString &value ); |
| 112 | 112 | ||
| 113 | StaticString *getEscape(); | 113 | Bu::FString getEscape(); |
| 114 | 114 | ||
| 115 | /** | 115 | /** |
| 116 | * Automoton function: paramlist. Processes a list of node params. | 116 | * Automoton function: paramlist. Processes a list of node params. |
| @@ -130,12 +130,15 @@ private: | |||
| 130 | */ | 130 | */ |
| 131 | bool content(); | 131 | bool content(); |
| 132 | 132 | ||
| 133 | FlexBuf fbContent; /**< buffer for the current node's content. */ | 133 | Bu::FString sContent; /**< buffer for the current node's content. */ |
| 134 | FlexBuf fbParamName; /**< buffer for the current param's name. */ | 134 | Bu::FString sParamName; /**< buffer for the current param's name. */ |
| 135 | FlexBuf fbParamValue; /**< buffer for the current param's value. */ | 135 | Bu::FString sParamValue; /**< buffer for the current param's value. */ |
| 136 | bool bStrip; /**< Are we stripping whitespace? */ | 136 | Bu::Stream &sIn; |
| 137 | bool bStrip; /**< Are we stripping whitespace? */ | ||
| 137 | 138 | ||
| 138 | HashTable htEntity; /**< Entity type definitions. */ | 139 | Bu::Hash<Bu::FString,Bu::FString> htEntity; /**< Entity type definitions. */ |
| 140 | |||
| 141 | Bu::FString sBuf; | ||
| 139 | }; | 142 | }; |
| 140 | 143 | ||
| 141 | #endif | 144 | #endif |
diff --git a/src/xmlwriter.cpp b/src/xmlwriter.cpp index 56880b6..7dc6ca9 100644 --- a/src/xmlwriter.cpp +++ b/src/xmlwriter.cpp | |||
| @@ -2,17 +2,10 @@ | |||
| 2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
| 3 | #include "xmlwriter.h" | 3 | #include "xmlwriter.h" |
| 4 | 4 | ||
| 5 | XmlWriter::XmlWriter( const char *sIndent, XmlNode *pRoot ) : | 5 | XmlWriter::XmlWriter( const Bu::FString &sIndent, XmlNode *pRoot ) : |
| 6 | XmlDocument( pRoot ) | 6 | XmlDocument( pRoot ), |
| 7 | sIndent( sIndent ) | ||
| 7 | { | 8 | { |
| 8 | if( sIndent == NULL ) | ||
| 9 | { | ||
| 10 | this->sIndent = ""; | ||
| 11 | } | ||
| 12 | else | ||
| 13 | { | ||
| 14 | this->sIndent = sIndent; | ||
| 15 | } | ||
| 16 | } | 9 | } |
| 17 | 10 | ||
| 18 | XmlWriter::~XmlWriter() | 11 | XmlWriter::~XmlWriter() |
| @@ -24,7 +17,7 @@ void XmlWriter::write() | |||
| 24 | write( getRoot(), sIndent.c_str() ); | 17 | write( getRoot(), sIndent.c_str() ); |
| 25 | } | 18 | } |
| 26 | 19 | ||
| 27 | void XmlWriter::write( XmlNode *pRoot, const char *sIndent ) | 20 | void XmlWriter::write( XmlNode *pRoot, const Bu::FString &sIndent ) |
| 28 | { | 21 | { |
| 29 | writeNode( pRoot, 0, sIndent ); | 22 | writeNode( pRoot, 0, sIndent ); |
| 30 | } | 23 | } |
| @@ -39,7 +32,7 @@ void XmlWriter::closeNode() | |||
| 39 | } | 32 | } |
| 40 | } | 33 | } |
| 41 | 34 | ||
| 42 | void XmlWriter::writeIndent( int nIndent, const char *sIndent ) | 35 | void XmlWriter::writeIndent( int nIndent, const Bu::FString &sIndent ) |
| 43 | { | 36 | { |
| 44 | if( sIndent == NULL ) return; | 37 | if( sIndent == NULL ) return; |
| 45 | for( int j = 0; j < nIndent; j++ ) | 38 | for( int j = 0; j < nIndent; j++ ) |
| @@ -48,26 +41,27 @@ void XmlWriter::writeIndent( int nIndent, const char *sIndent ) | |||
| 48 | } | 41 | } |
| 49 | } | 42 | } |
| 50 | 43 | ||
| 51 | std::string XmlWriter::escape( std::string sIn ) | 44 | Bu::FString XmlWriter::escape( const Bu::FString &sIn ) |
| 52 | { | 45 | { |
| 53 | std::string sOut; | 46 | Bu::FString sOut; |
| 54 | 47 | ||
| 55 | std::string::const_iterator i; | 48 | int nMax = sIn.getSize(); |
| 56 | for( i = sIn.begin(); i != sIn.end(); i++ ) | 49 | for( int j = 0; j < nMax; j++ ) |
| 57 | { | 50 | { |
| 58 | if( ((*i >= ' ' && *i <= '9') || | 51 | char c = sIn[j]; |
| 59 | (*i >= 'a' && *i <= 'z') || | 52 | if( ((c >= ' ' && c <= '9') || |
| 60 | (*i >= 'A' && *i <= 'Z') ) && | 53 | (c >= 'a' && c <= 'z') || |
| 61 | (*i != '\"' && *i != '\'' && *i != '&') | 54 | (c >= 'A' && c <= 'Z') ) && |
| 55 | (c != '\"' && c != '\'' && c != '&') | ||
| 62 | ) | 56 | ) |
| 63 | { | 57 | { |
| 64 | sOut += *i; | 58 | sOut += c; |
| 65 | } | 59 | } |
| 66 | else | 60 | else |
| 67 | { | 61 | { |
| 68 | sOut += "&#"; | 62 | sOut += "&#"; |
| 69 | char buf[4]; | 63 | char buf[4]; |
| 70 | sprintf( buf, "%u", (unsigned char)*i ); | 64 | sprintf( buf, "%u", (unsigned char)c ); |
| 71 | sOut += buf; | 65 | sOut += buf; |
| 72 | sOut += ';'; | 66 | sOut += ';'; |
| 73 | } | 67 | } |
| @@ -76,19 +70,19 @@ std::string XmlWriter::escape( std::string sIn ) | |||
| 76 | return sOut; | 70 | return sOut; |
| 77 | } | 71 | } |
| 78 | 72 | ||
| 79 | void XmlWriter::writeNodeProps( XmlNode *pNode, int nIndent, const char *sIndent ) | 73 | void XmlWriter::writeNodeProps( XmlNode *pNode, int nIndent, const Bu::FString &sIndent ) |
| 80 | { | 74 | { |
| 81 | for( int j = 0; j < pNode->getNumProperties(); j++ ) | 75 | for( int j = 0; j < pNode->getNumProperties(); j++ ) |
| 82 | { | 76 | { |
| 83 | writeString(" "); | 77 | writeString(" "); |
| 84 | writeString( pNode->getPropertyName( j ) ); | 78 | //writeString( pNode->getPropertyName( j ) ); |
| 85 | writeString("=\""); | 79 | writeString("=\""); |
| 86 | writeString( escape( pNode->getProperty( j ) ).c_str() ); | 80 | //writeString( escape( pNode->getProperty( j ) ).c_str() ); |
| 87 | writeString("\""); | 81 | writeString("\""); |
| 88 | } | 82 | } |
| 89 | } | 83 | } |
| 90 | 84 | ||
| 91 | void XmlWriter::writeNode( XmlNode *pNode, int nIndent, const char *sIndent ) | 85 | void XmlWriter::writeNode( XmlNode *pNode, int nIndent, const Bu::FString &sIndent ) |
| 92 | { | 86 | { |
| 93 | if( pNode->hasChildren() ) | 87 | if( pNode->hasChildren() ) |
| 94 | { | 88 | { |
| @@ -96,15 +90,15 @@ void XmlWriter::writeNode( XmlNode *pNode, int nIndent, const char *sIndent ) | |||
| 96 | writeString("<"); | 90 | writeString("<"); |
| 97 | writeString( pNode->getName() ); | 91 | writeString( pNode->getName() ); |
| 98 | writeNodeProps( pNode, nIndent, sIndent ); | 92 | writeNodeProps( pNode, nIndent, sIndent ); |
| 99 | if( sIndent ) | 93 | if( sIndent != "" ) |
| 100 | writeString(">\n"); | 94 | writeString(">\n"); |
| 101 | else | 95 | else |
| 102 | writeString(">"); | 96 | writeString(">"); |
| 103 | 97 | /* | |
| 104 | if( pNode->getContent( 0 ) ) | 98 | if( pNode->getContent( 0 ) ) |
| 105 | { | 99 | { |
| 106 | writeIndent( nIndent+1, sIndent ); | 100 | writeIndent( nIndent+1, sIndent ); |
| 107 | if( sIndent ) | 101 | if( sIndent != "" ) |
| 108 | { | 102 | { |
| 109 | writeString( pNode->getContent( 0 ) ); | 103 | writeString( pNode->getContent( 0 ) ); |
| 110 | writeString("\n"); | 104 | writeString("\n"); |
| @@ -129,9 +123,9 @@ void XmlWriter::writeNode( XmlNode *pNode, int nIndent, const char *sIndent ) | |||
| 129 | writeString( pNode->getContent( j+1 ) ); | 123 | writeString( pNode->getContent( j+1 ) ); |
| 130 | } | 124 | } |
| 131 | } | 125 | } |
| 132 | 126 | */ | |
| 133 | writeIndent( nIndent, sIndent ); | 127 | writeIndent( nIndent, sIndent ); |
| 134 | if( sIndent ) | 128 | if( sIndent != "" ) |
| 135 | { | 129 | { |
| 136 | writeString("</"); | 130 | writeString("</"); |
| 137 | writeString( pNode->getName() ); | 131 | writeString( pNode->getName() ); |
| @@ -143,7 +137,7 @@ void XmlWriter::writeNode( XmlNode *pNode, int nIndent, const char *sIndent ) | |||
| 143 | writeString( pNode->getName() ); | 137 | writeString( pNode->getName() ); |
| 144 | writeString(">"); | 138 | writeString(">"); |
| 145 | } | 139 | } |
| 146 | } | 140 | }/* |
| 147 | else if( pNode->getContent() ) | 141 | else if( pNode->getContent() ) |
| 148 | { | 142 | { |
| 149 | writeIndent( nIndent, sIndent ); | 143 | writeIndent( nIndent, sIndent ); |
| @@ -157,14 +151,14 @@ void XmlWriter::writeNode( XmlNode *pNode, int nIndent, const char *sIndent ) | |||
| 157 | writeString(">"); | 151 | writeString(">"); |
| 158 | if( sIndent ) | 152 | if( sIndent ) |
| 159 | writeString("\n"); | 153 | writeString("\n"); |
| 160 | } | 154 | }*/ |
| 161 | else | 155 | else |
| 162 | { | 156 | { |
| 163 | writeIndent( nIndent, sIndent ); | 157 | writeIndent( nIndent, sIndent ); |
| 164 | writeString("<"); | 158 | writeString("<"); |
| 165 | writeString( pNode->getName() ); | 159 | writeString( pNode->getName() ); |
| 166 | writeNodeProps( pNode, nIndent, sIndent ); | 160 | writeNodeProps( pNode, nIndent, sIndent ); |
| 167 | if( sIndent ) | 161 | if( sIndent != "" ) |
| 168 | writeString("/>\n"); | 162 | writeString("/>\n"); |
| 169 | else | 163 | else |
| 170 | writeString("/>"); | 164 | writeString("/>"); |
diff --git a/src/xmlwriter.h b/src/xmlwriter.h index c48e810..7e3c876 100644 --- a/src/xmlwriter.h +++ b/src/xmlwriter.h | |||
| @@ -31,7 +31,7 @@ public: | |||
| 31 | * this to a tab or some spaces it will never effect the content of your | 31 | * this to a tab or some spaces it will never effect the content of your |
| 32 | * file. | 32 | * file. |
| 33 | */ | 33 | */ |
| 34 | XmlWriter( const char *sIndent=NULL, XmlNode *pRoot=NULL ); | 34 | XmlWriter( const Bu::FString &sIndent="", XmlNode *pRoot=NULL ); |
| 35 | 35 | ||
| 36 | /** | 36 | /** |
| 37 | * Destroy the writer. | 37 | * Destroy the writer. |
| @@ -49,16 +49,16 @@ public: | |||
| 49 | void write(); | 49 | void write(); |
| 50 | 50 | ||
| 51 | private: | 51 | private: |
| 52 | std::string sIndent; /**< The indent string */ | 52 | Bu::FString sIndent; /**< The indent string */ |
| 53 | 53 | ||
| 54 | std::string escape( std::string sIn ); | 54 | Bu::FString escape( const Bu::FString &sIn ); |
| 55 | 55 | ||
| 56 | /** | 56 | /** |
| 57 | * Write the file. | 57 | * Write the file. |
| 58 | *@param pNode The root node | 58 | *@param pNode The root node |
| 59 | *@param sIndent The indent text. | 59 | *@param sIndent The indent text. |
| 60 | */ | 60 | */ |
| 61 | void write( XmlNode *pNode, const char *sIndent=NULL ); | 61 | void write( XmlNode *pNode, const Bu::FString &sIndent ); |
| 62 | 62 | ||
| 63 | /** | 63 | /** |
| 64 | * Write a node in the file, including children. | 64 | * Write a node in the file, including children. |
| @@ -66,7 +66,7 @@ private: | |||
| 66 | *@param nIndent The indent level (the number of times to include sIndent) | 66 | *@param nIndent The indent level (the number of times to include sIndent) |
| 67 | *@param sIndent The indent text. | 67 | *@param sIndent The indent text. |
| 68 | */ | 68 | */ |
| 69 | void writeNode( XmlNode *pNode, int nIndent, const char *sIndent ); | 69 | void writeNode( XmlNode *pNode, int nIndent, const Bu::FString &sIndent ); |
| 70 | 70 | ||
| 71 | /** | 71 | /** |
| 72 | * Write the properties of a node. | 72 | * Write the properties of a node. |
| @@ -74,14 +74,14 @@ private: | |||
| 74 | *@param nIndent The indent level of the containing node | 74 | *@param nIndent The indent level of the containing node |
| 75 | *@param sIndent The indent text. | 75 | *@param sIndent The indent text. |
| 76 | */ | 76 | */ |
| 77 | void writeNodeProps( XmlNode *pNode, int nIndent, const char *sIndent ); | 77 | void writeNodeProps( XmlNode *pNode, int nIndent, const Bu::FString &sIndent ); |
| 78 | 78 | ||
| 79 | /** | 79 | /** |
| 80 | * Called to write the actual indent. | 80 | * Called to write the actual indent. |
| 81 | *@param nIndent The indent level. | 81 | *@param nIndent The indent level. |
| 82 | *@param sIndent The indent text. | 82 | *@param sIndent The indent text. |
| 83 | */ | 83 | */ |
| 84 | void writeIndent( int nIndent, const char *sIndent ); | 84 | void writeIndent( int nIndent, const Bu::FString &sIndent ); |
| 85 | 85 | ||
| 86 | /** | 86 | /** |
| 87 | * This is the function that must be overridden in order to use this class. | 87 | * This is the function that must be overridden in order to use this class. |
| @@ -90,7 +90,7 @@ private: | |||
| 90 | * will break the XML formatting. | 90 | * will break the XML formatting. |
| 91 | *@param sString The string data to write to the output. | 91 | *@param sString The string data to write to the output. |
| 92 | */ | 92 | */ |
| 93 | virtual void writeString( const char *sString ) = 0; | 93 | virtual void writeString( const Bu::FString &sString ) = 0; |
| 94 | }; | 94 | }; |
| 95 | 95 | ||
| 96 | #endif | 96 | #endif |
