summaryrefslogtreecommitdiff
authorsimon <simon>2002-03-20 21:08:03 (UTC)
committer simon <simon>2002-03-20 21:08:03 (UTC)
commit60b86269c6087dfb6674de6dc01d71a9a6d6d180 (patch) (unidiff)
treee53c76de63500dfe52b90c3da6c354b507cb4ba0
parent79d96ab3393af185b0f0d705e1b7ae74ee801241 (diff)
downloadopie-60b86269c6087dfb6674de6dc01d71a9a6d6d180.zip
opie-60b86269c6087dfb6674de6dc01d71a9a6d6d180.tar.gz
opie-60b86269c6087dfb6674de6dc01d71a9a6d6d180.tar.bz2
- speed up for attribute() and setAttribute()
- indentation fixlet (let's stay consistent :)
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/xmltree.cc17
-rw-r--r--libopie2/opiecore/xmltree.cc17
2 files changed, 20 insertions, 14 deletions
diff --git a/libopie/xmltree.cc b/libopie/xmltree.cc
index 3d03cc6..408e3c6 100644
--- a/libopie/xmltree.cc
+++ b/libopie/xmltree.cc
@@ -1,318 +1,321 @@
1/* This file is part of the KDE project 1/* This file is part of the KDE project
2 Copyright (C) 2001 Simon Hausmann <hausmann@kde.org> 2 Copyright (C) 2001 Simon Hausmann <hausmann@kde.org>
3 3
4 This library is free software; you can redistribute it and/or 4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public 5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either 6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version. 7 version 2 of the License, or (at your option) any later version.
8 8
9 This library is distributed in the hope that it will be useful, 9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details. 12 Library General Public License for more details.
13 13
14 You should have received a copy of the GNU Library General Public License 14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to 15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. 17 Boston, MA 02111-1307, USA.
18*/ 18*/
19 19
20#include <qpe/stringutil.h> 20#include <qpe/stringutil.h>
21#include <opie/xmltree.h> 21#include <opie/xmltree.h>
22 22
23#include <qxml.h> 23#include <qxml.h>
24 24
25#include <assert.h> 25#include <assert.h>
26 26
27 27
28XMLElement::XMLElement() 28XMLElement::XMLElement()
29 : m_parent( 0 ), m_next( 0 ), m_prev( 0 ), m_first( 0 ), m_last( 0 ) 29 : m_parent( 0 ), m_next( 0 ), m_prev( 0 ), m_first( 0 ), m_last( 0 )
30{ 30{
31} 31}
32 32
33XMLElement::~XMLElement() 33XMLElement::~XMLElement()
34{ 34{
35 XMLElement *n = m_first; 35 XMLElement *n = m_first;
36 36
37 while ( n ) 37 while ( n )
38 { 38 {
39 XMLElement *tmp = n; 39 XMLElement *tmp = n;
40 n = n->m_next; 40 n = n->m_next;
41 delete tmp; 41 delete tmp;
42 } 42 }
43} 43}
44 44
45void XMLElement::appendChild( XMLElement *child ) 45void XMLElement::appendChild( XMLElement *child )
46{ 46{
47 if ( child->m_parent ) 47 if ( child->m_parent )
48 child->m_parent->removeChild( child ); 48 child->m_parent->removeChild( child );
49 49
50 child->m_parent = this; 50 child->m_parent = this;
51 51
52 if ( m_last ) 52 if ( m_last )
53 m_last->m_next = child; 53 m_last->m_next = child;
54 54
55 child->m_prev = m_last; 55 child->m_prev = m_last;
56 56
57 if ( !m_first ) 57 if ( !m_first )
58 m_first = child; 58 m_first = child;
59 59
60 m_last = child; 60 m_last = child;
61} 61}
62 62
63void XMLElement::insertAfter( XMLElement *newChild, XMLElement *refChild ) 63void XMLElement::insertAfter( XMLElement *newChild, XMLElement *refChild )
64{ 64{
65 assert( newChild != refChild ); 65 assert( newChild != refChild );
66 66
67 if ( refChild == m_last ) 67 if ( refChild == m_last )
68 { 68 {
69 appendChild( newChild ); 69 appendChild( newChild );
70 return; 70 return;
71 } 71 }
72 72
73 assert( refChild ); 73 assert( refChild );
74 assert( refChild->m_parent ); 74 assert( refChild->m_parent );
75 assert( refChild->m_parent == this ); 75 assert( refChild->m_parent == this );
76 76
77 if ( newChild->m_parent && newChild != refChild ) 77 if ( newChild->m_parent && newChild != refChild )
78 newChild->m_parent->removeChild( newChild ); 78 newChild->m_parent->removeChild( newChild );
79 79
80 newChild->m_parent = this; 80 newChild->m_parent = this;
81 81
82 XMLElement *next = refChild->m_next; 82 XMLElement *next = refChild->m_next;
83 83
84 refChild->m_next = newChild; 84 refChild->m_next = newChild;
85 85
86 newChild->m_prev = refChild; 86 newChild->m_prev = refChild;
87 newChild->m_next = next; 87 newChild->m_next = next;
88 88
89 if ( next ) 89 if ( next )
90 next->m_prev = newChild; 90 next->m_prev = newChild;
91} 91}
92QString XMLElement::attribute(const QString &attr )const 92
93QString XMLElement::attribute( const QString &attr ) const
93{ 94{
94 if ( !m_attributes.contains( attr ) )
95 return QString::null;
96 AttributeMap::ConstIterator it = m_attributes.find( attr ); 95 AttributeMap::ConstIterator it = m_attributes.find( attr );
96 if ( it == m_attributes.end() )
97 return QString::null;
97 return it.data(); 98 return it.data();
98} 99}
99void XMLElement::setAttribute(const QString &attr, const QString &value ) 100
101void XMLElement::setAttribute( const QString &attr, const QString &value )
100{ 102{
101 m_attributes.remove( attr ); 103 m_attributes.replace( attr, value );
102 m_attributes.insert( attr, value );
103} 104}
105
104void XMLElement::insertBefore( XMLElement *newChild, XMLElement *refChild ) 106void XMLElement::insertBefore( XMLElement *newChild, XMLElement *refChild )
105{ 107{
106 assert( refChild ); 108 assert( refChild );
107 assert( refChild->m_parent ); 109 assert( refChild->m_parent );
108 assert( refChild->m_parent == this ); 110 assert( refChild->m_parent == this );
109 assert( newChild != refChild ); 111 assert( newChild != refChild );
110 112
111 if ( newChild->m_parent && newChild != refChild ) 113 if ( newChild->m_parent && newChild != refChild )
112 newChild->m_parent->removeChild( newChild ); 114 newChild->m_parent->removeChild( newChild );
113 115
114 newChild->m_parent = this; 116 newChild->m_parent = this;
115 117
116 XMLElement *prev = refChild->m_prev; 118 XMLElement *prev = refChild->m_prev;
117 119
118 refChild->m_prev = newChild; 120 refChild->m_prev = newChild;
119 121
120 newChild->m_prev = prev; 122 newChild->m_prev = prev;
121 newChild->m_next = refChild; 123 newChild->m_next = refChild;
122 124
123 if ( prev ) 125 if ( prev )
124 prev->m_next = newChild; 126 prev->m_next = newChild;
125 127
126 if ( refChild == m_first ) 128 if ( refChild == m_first )
127 m_first = newChild; 129 m_first = newChild;
128} 130}
129 131
130void XMLElement::removeChild( XMLElement *child ) 132void XMLElement::removeChild( XMLElement *child )
131{ 133{
132 if ( child->m_parent != this ) 134 if ( child->m_parent != this )
133 return; 135 return;
134 136
135 if ( m_first == child ) 137 if ( m_first == child )
136 m_first = child->m_next; 138 m_first = child->m_next;
137 139
138 if ( m_last == child ) 140 if ( m_last == child )
139 m_last = child->m_prev; 141 m_last = child->m_prev;
140 142
141 if ( child->m_prev ) 143 if ( child->m_prev )
142 child->m_prev->m_next = child->m_next; 144 child->m_prev->m_next = child->m_next;
143 145
144 if ( child->m_next ) 146 if ( child->m_next )
145 child->m_next->m_prev = child->m_prev; 147 child->m_next->m_prev = child->m_prev;
146 148
147 child->m_parent = 0; 149 child->m_parent = 0;
148 child->m_prev = 0; 150 child->m_prev = 0;
149 child->m_next = 0; 151 child->m_next = 0;
150} 152}
151 153
152void XMLElement::save( QTextStream &s, uint indent ) 154void XMLElement::save( QTextStream &s, uint indent )
153{ 155{
154 if ( !m_value.isEmpty() ) 156 if ( !m_value.isEmpty() )
155 { 157 {
156 s << Qtopia::escapeString( m_value ); 158 s << Qtopia::escapeString( m_value );
157 return; 159 return;
158 } 160 }
159 161
160 for ( uint i = 0; i < indent; ++i ) 162 for ( uint i = 0; i < indent; ++i )
161 s << " "; 163 s << " ";
162 164
163 s << "<" << m_tag; 165 s << "<" << m_tag;
164 166
165 if ( !m_attributes.isEmpty() ) 167 if ( !m_attributes.isEmpty() )
166 { 168 {
167 s << " "; 169 s << " ";
168 AttributeMap::ConstIterator it = m_attributes.begin(); 170 AttributeMap::ConstIterator it = m_attributes.begin();
169 AttributeMap::ConstIterator end = m_attributes.end(); 171 AttributeMap::ConstIterator end = m_attributes.end();
170 for (; it != end; ++it ) 172 for (; it != end; ++it )
171 { 173 {
172 s << it.key() << "=\"" << Qtopia::escapeString( it.data() ) << "\""; 174 s << it.key() << "=\"" << Qtopia::escapeString( it.data() ) << "\"";
173 s << " "; 175 s << " ";
174 } 176 }
175 } 177 }
176 178
177 if ( m_last ) 179 if ( m_last )
178 { 180 {
179 if ( ( m_first && !m_first->value().isEmpty() ) || !m_parent ) 181 if ( ( m_first && !m_first->value().isEmpty() ) || !m_parent )
180 s << ">"; 182 s << ">";
181 else 183 else
182 s << ">" << endl; 184 s << ">" << endl;
183 185
184 int newIndent = indent; 186 int newIndent = indent;
185 if ( m_parent ) 187 if ( m_parent )
186 newIndent++; 188 newIndent++;
187 189
188 XMLElement *n = m_first; 190 XMLElement *n = m_first;
189 while ( n ) 191 while ( n )
190 { 192 {
191 n->save( s, newIndent ); 193 n->save( s, newIndent );
192 n = n->nextChild(); 194 n = n->nextChild();
193 } 195 }
194 196
195 if ( m_last && m_last->value().isEmpty() && m_parent ) 197 if ( m_last && m_last->value().isEmpty() && m_parent )
196 for ( uint i = 0; i < indent; ++i ) 198 for ( uint i = 0; i < indent; ++i )
197 s << " "; 199 s << " ";
198 200
199 if ( m_parent ) 201 if ( m_parent )
200 s << "</" << m_tag << ">" << endl; 202 s << "</" << m_tag << ">" << endl;
201 } 203 }
202 else 204 else
203 s << "/>" << endl; 205 s << "/>" << endl;
204} 206}
205 207
206class Handler : public QXmlDefaultHandler 208class Handler : public QXmlDefaultHandler
207{ 209{
208public: 210public:
209 Handler() : m_node( 0 ), m_root( 0 ) {} 211 Handler() : m_node( 0 ), m_root( 0 ) {}
210 212
211 XMLElement *root() const { return m_root; } 213 XMLElement *root() const { return m_root; }
212 214
213 virtual bool startDocument(); 215 virtual bool startDocument();
214 virtual bool endDocument(); 216 virtual bool endDocument();
215 virtual bool startElement( const QString &ns, const QString &ln, const QString &qName, 217 virtual bool startElement( const QString &ns, const QString &ln, const QString &qName,
216 const QXmlAttributes &attr ); 218 const QXmlAttributes &attr );
217 virtual bool endElement( const QString &ns, const QString &ln, const QString &qName ); 219 virtual bool endElement( const QString &ns, const QString &ln, const QString &qName );
218 virtual bool characters( const QString &ch ); 220 virtual bool characters( const QString &ch );
219 221
220private: 222private:
221 XMLElement *m_node; 223 XMLElement *m_node;
222 XMLElement *m_root; 224 XMLElement *m_root;
223}; 225};
224 226
225bool Handler::startDocument() 227bool Handler::startDocument()
226{ 228{
227 m_root = m_node = new XMLElement; 229 m_root = m_node = new XMLElement;
228 230
229 return true; 231 return true;
230} 232}
231 233
232bool Handler::endDocument() 234bool Handler::endDocument()
233{ 235{
234 return m_root == m_node; 236 return m_root == m_node;
235} 237}
236 238
237bool Handler::startElement( const QString &, const QString &, const QString &qName, 239bool Handler::startElement( const QString &, const QString &, const QString &qName,
238 const QXmlAttributes &attr ) 240 const QXmlAttributes &attr )
239{ 241{
240 XMLElement *bm = new XMLElement; 242 XMLElement *bm = new XMLElement;
241 243
242 XMLElement::AttributeMap attributes; 244 XMLElement::AttributeMap attributes;
243 for ( int i = 0; i < attr.length(); ++i ) 245 for ( int i = 0; i < attr.length(); ++i )
244 attributes[ attr.qName( i ) ] = attr.value( i ); 246 attributes[ attr.qName( i ) ] = attr.value( i );
245 247
246 bm->setAttributes( attributes ); 248 bm->setAttributes( attributes );
247 249
248 bm->setTagName( qName ); 250 bm->setTagName( qName );
249 251
250 m_node->appendChild( bm ); 252 m_node->appendChild( bm );
251 m_node = bm; 253 m_node = bm;
252 254
253 return true; 255 return true;
254} 256}
255 257
256bool Handler::endElement( const QString &, const QString &, const QString & ) 258bool Handler::endElement( const QString &, const QString &, const QString & )
257{ 259{
258 if ( m_node == m_root ) 260 if ( m_node == m_root )
259 return false; 261 return false;
260 262
261 m_node = m_node->parent(); 263 m_node = m_node->parent();
262 return true; 264 return true;
263} 265}
264 266
265bool Handler::characters( const QString &ch ) 267bool Handler::characters( const QString &ch )
266{ 268{
267 XMLElement *textNode = new XMLElement; 269 XMLElement *textNode = new XMLElement;
268 textNode->setValue( ch ); 270 textNode->setValue( ch );
269 m_node->appendChild( textNode ); 271 m_node->appendChild( textNode );
270 return true; 272 return true;
271} 273}
272 274
273XMLElement *XMLElement::namedItem( const QString &name ) 275XMLElement *XMLElement::namedItem( const QString &name )
274{ 276{
275 XMLElement *e = m_first; 277 XMLElement *e = m_first;
276 278
277 for (; e; e = e->nextChild() ) 279 for (; e; e = e->nextChild() )
278 if ( e->tagName() == name ) 280 if ( e->tagName() == name )
279 return e; 281 return e;
280 282
281 return 0; 283 return 0;
282} 284}
283 285
284XMLElement *XMLElement::clone() const 286XMLElement *XMLElement::clone() const
285{ 287{
286 XMLElement *res = new XMLElement; 288 XMLElement *res = new XMLElement;
287 289
288 res->setTagName( m_tag ); 290 res->setTagName( m_tag );
289 res->setValue( m_value ); 291 res->setValue( m_value );
290 res->setAttributes( m_attributes ); 292 res->setAttributes( m_attributes );
291 293
292 XMLElement *e = m_first; 294 XMLElement *e = m_first;
293 for (; e; e = e->m_next ) 295 for (; e; e = e->m_next )
294 res->appendChild( e->clone() ); 296 res->appendChild( e->clone() );
295 297
296 return res; 298 return res;
297} 299}
298 300
299XMLElement *XMLElement::load( const QString &fileName ) 301XMLElement *XMLElement::load( const QString &fileName )
300{ 302{
301 QFile f( fileName ); 303 QFile f( fileName );
302 if ( !f.open( IO_ReadOnly ) ) 304 if ( !f.open( IO_ReadOnly ) )
303 return 0; 305 return 0;
304 306
305 QTextStream stream( &f ); 307 QTextStream stream( &f );
306 stream.setEncoding( QTextStream::UnicodeUTF8 ); 308 stream.setEncoding( QTextStream::UnicodeUTF8 );
307 QXmlInputSource src( stream ); 309 QXmlInputSource src( stream );
308 QXmlSimpleReader reader; 310 QXmlSimpleReader reader;
309 Handler handler; 311 Handler handler;
310 312
311 reader.setFeature( "http://trolltech.com/xml/features/report-whitespace-only-CharData", false ); 313 reader.setFeature( "http://trolltech.com/xml/features/report-whitespace-only-CharData", false );
312 reader.setContentHandler( &handler ); 314 reader.setContentHandler( &handler );
313 reader.parse( src ); 315 reader.parse( src );
314 316
315 return handler.root();; 317 return handler.root();;
316} 318}
317 319
318 320/* vim: et sw=4
321 */
diff --git a/libopie2/opiecore/xmltree.cc b/libopie2/opiecore/xmltree.cc
index 3d03cc6..408e3c6 100644
--- a/libopie2/opiecore/xmltree.cc
+++ b/libopie2/opiecore/xmltree.cc
@@ -1,318 +1,321 @@
1/* This file is part of the KDE project 1/* This file is part of the KDE project
2 Copyright (C) 2001 Simon Hausmann <hausmann@kde.org> 2 Copyright (C) 2001 Simon Hausmann <hausmann@kde.org>
3 3
4 This library is free software; you can redistribute it and/or 4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public 5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either 6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version. 7 version 2 of the License, or (at your option) any later version.
8 8
9 This library is distributed in the hope that it will be useful, 9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details. 12 Library General Public License for more details.
13 13
14 You should have received a copy of the GNU Library General Public License 14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to 15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. 17 Boston, MA 02111-1307, USA.
18*/ 18*/
19 19
20#include <qpe/stringutil.h> 20#include <qpe/stringutil.h>
21#include <opie/xmltree.h> 21#include <opie/xmltree.h>
22 22
23#include <qxml.h> 23#include <qxml.h>
24 24
25#include <assert.h> 25#include <assert.h>
26 26
27 27
28XMLElement::XMLElement() 28XMLElement::XMLElement()
29 : m_parent( 0 ), m_next( 0 ), m_prev( 0 ), m_first( 0 ), m_last( 0 ) 29 : m_parent( 0 ), m_next( 0 ), m_prev( 0 ), m_first( 0 ), m_last( 0 )
30{ 30{
31} 31}
32 32
33XMLElement::~XMLElement() 33XMLElement::~XMLElement()
34{ 34{
35 XMLElement *n = m_first; 35 XMLElement *n = m_first;
36 36
37 while ( n ) 37 while ( n )
38 { 38 {
39 XMLElement *tmp = n; 39 XMLElement *tmp = n;
40 n = n->m_next; 40 n = n->m_next;
41 delete tmp; 41 delete tmp;
42 } 42 }
43} 43}
44 44
45void XMLElement::appendChild( XMLElement *child ) 45void XMLElement::appendChild( XMLElement *child )
46{ 46{
47 if ( child->m_parent ) 47 if ( child->m_parent )
48 child->m_parent->removeChild( child ); 48 child->m_parent->removeChild( child );
49 49
50 child->m_parent = this; 50 child->m_parent = this;
51 51
52 if ( m_last ) 52 if ( m_last )
53 m_last->m_next = child; 53 m_last->m_next = child;
54 54
55 child->m_prev = m_last; 55 child->m_prev = m_last;
56 56
57 if ( !m_first ) 57 if ( !m_first )
58 m_first = child; 58 m_first = child;
59 59
60 m_last = child; 60 m_last = child;
61} 61}
62 62
63void XMLElement::insertAfter( XMLElement *newChild, XMLElement *refChild ) 63void XMLElement::insertAfter( XMLElement *newChild, XMLElement *refChild )
64{ 64{
65 assert( newChild != refChild ); 65 assert( newChild != refChild );
66 66
67 if ( refChild == m_last ) 67 if ( refChild == m_last )
68 { 68 {
69 appendChild( newChild ); 69 appendChild( newChild );
70 return; 70 return;
71 } 71 }
72 72
73 assert( refChild ); 73 assert( refChild );
74 assert( refChild->m_parent ); 74 assert( refChild->m_parent );
75 assert( refChild->m_parent == this ); 75 assert( refChild->m_parent == this );
76 76
77 if ( newChild->m_parent && newChild != refChild ) 77 if ( newChild->m_parent && newChild != refChild )
78 newChild->m_parent->removeChild( newChild ); 78 newChild->m_parent->removeChild( newChild );
79 79
80 newChild->m_parent = this; 80 newChild->m_parent = this;
81 81
82 XMLElement *next = refChild->m_next; 82 XMLElement *next = refChild->m_next;
83 83
84 refChild->m_next = newChild; 84 refChild->m_next = newChild;
85 85
86 newChild->m_prev = refChild; 86 newChild->m_prev = refChild;
87 newChild->m_next = next; 87 newChild->m_next = next;
88 88
89 if ( next ) 89 if ( next )
90 next->m_prev = newChild; 90 next->m_prev = newChild;
91} 91}
92QString XMLElement::attribute(const QString &attr )const 92
93QString XMLElement::attribute( const QString &attr ) const
93{ 94{
94 if ( !m_attributes.contains( attr ) )
95 return QString::null;
96 AttributeMap::ConstIterator it = m_attributes.find( attr ); 95 AttributeMap::ConstIterator it = m_attributes.find( attr );
96 if ( it == m_attributes.end() )
97 return QString::null;
97 return it.data(); 98 return it.data();
98} 99}
99void XMLElement::setAttribute(const QString &attr, const QString &value ) 100
101void XMLElement::setAttribute( const QString &attr, const QString &value )
100{ 102{
101 m_attributes.remove( attr ); 103 m_attributes.replace( attr, value );
102 m_attributes.insert( attr, value );
103} 104}
105
104void XMLElement::insertBefore( XMLElement *newChild, XMLElement *refChild ) 106void XMLElement::insertBefore( XMLElement *newChild, XMLElement *refChild )
105{ 107{
106 assert( refChild ); 108 assert( refChild );
107 assert( refChild->m_parent ); 109 assert( refChild->m_parent );
108 assert( refChild->m_parent == this ); 110 assert( refChild->m_parent == this );
109 assert( newChild != refChild ); 111 assert( newChild != refChild );
110 112
111 if ( newChild->m_parent && newChild != refChild ) 113 if ( newChild->m_parent && newChild != refChild )
112 newChild->m_parent->removeChild( newChild ); 114 newChild->m_parent->removeChild( newChild );
113 115
114 newChild->m_parent = this; 116 newChild->m_parent = this;
115 117
116 XMLElement *prev = refChild->m_prev; 118 XMLElement *prev = refChild->m_prev;
117 119
118 refChild->m_prev = newChild; 120 refChild->m_prev = newChild;
119 121
120 newChild->m_prev = prev; 122 newChild->m_prev = prev;
121 newChild->m_next = refChild; 123 newChild->m_next = refChild;
122 124
123 if ( prev ) 125 if ( prev )
124 prev->m_next = newChild; 126 prev->m_next = newChild;
125 127
126 if ( refChild == m_first ) 128 if ( refChild == m_first )
127 m_first = newChild; 129 m_first = newChild;
128} 130}
129 131
130void XMLElement::removeChild( XMLElement *child ) 132void XMLElement::removeChild( XMLElement *child )
131{ 133{
132 if ( child->m_parent != this ) 134 if ( child->m_parent != this )
133 return; 135 return;
134 136
135 if ( m_first == child ) 137 if ( m_first == child )
136 m_first = child->m_next; 138 m_first = child->m_next;
137 139
138 if ( m_last == child ) 140 if ( m_last == child )
139 m_last = child->m_prev; 141 m_last = child->m_prev;
140 142
141 if ( child->m_prev ) 143 if ( child->m_prev )
142 child->m_prev->m_next = child->m_next; 144 child->m_prev->m_next = child->m_next;
143 145
144 if ( child->m_next ) 146 if ( child->m_next )
145 child->m_next->m_prev = child->m_prev; 147 child->m_next->m_prev = child->m_prev;
146 148
147 child->m_parent = 0; 149 child->m_parent = 0;
148 child->m_prev = 0; 150 child->m_prev = 0;
149 child->m_next = 0; 151 child->m_next = 0;
150} 152}
151 153
152void XMLElement::save( QTextStream &s, uint indent ) 154void XMLElement::save( QTextStream &s, uint indent )
153{ 155{
154 if ( !m_value.isEmpty() ) 156 if ( !m_value.isEmpty() )
155 { 157 {
156 s << Qtopia::escapeString( m_value ); 158 s << Qtopia::escapeString( m_value );
157 return; 159 return;
158 } 160 }
159 161
160 for ( uint i = 0; i < indent; ++i ) 162 for ( uint i = 0; i < indent; ++i )
161 s << " "; 163 s << " ";
162 164
163 s << "<" << m_tag; 165 s << "<" << m_tag;
164 166
165 if ( !m_attributes.isEmpty() ) 167 if ( !m_attributes.isEmpty() )
166 { 168 {
167 s << " "; 169 s << " ";
168 AttributeMap::ConstIterator it = m_attributes.begin(); 170 AttributeMap::ConstIterator it = m_attributes.begin();
169 AttributeMap::ConstIterator end = m_attributes.end(); 171 AttributeMap::ConstIterator end = m_attributes.end();
170 for (; it != end; ++it ) 172 for (; it != end; ++it )
171 { 173 {
172 s << it.key() << "=\"" << Qtopia::escapeString( it.data() ) << "\""; 174 s << it.key() << "=\"" << Qtopia::escapeString( it.data() ) << "\"";
173 s << " "; 175 s << " ";
174 } 176 }
175 } 177 }
176 178
177 if ( m_last ) 179 if ( m_last )
178 { 180 {
179 if ( ( m_first && !m_first->value().isEmpty() ) || !m_parent ) 181 if ( ( m_first && !m_first->value().isEmpty() ) || !m_parent )
180 s << ">"; 182 s << ">";
181 else 183 else
182 s << ">" << endl; 184 s << ">" << endl;
183 185
184 int newIndent = indent; 186 int newIndent = indent;
185 if ( m_parent ) 187 if ( m_parent )
186 newIndent++; 188 newIndent++;
187 189
188 XMLElement *n = m_first; 190 XMLElement *n = m_first;
189 while ( n ) 191 while ( n )
190 { 192 {
191 n->save( s, newIndent ); 193 n->save( s, newIndent );
192 n = n->nextChild(); 194 n = n->nextChild();
193 } 195 }
194 196
195 if ( m_last && m_last->value().isEmpty() && m_parent ) 197 if ( m_last && m_last->value().isEmpty() && m_parent )
196 for ( uint i = 0; i < indent; ++i ) 198 for ( uint i = 0; i < indent; ++i )
197 s << " "; 199 s << " ";
198 200
199 if ( m_parent ) 201 if ( m_parent )
200 s << "</" << m_tag << ">" << endl; 202 s << "</" << m_tag << ">" << endl;
201 } 203 }
202 else 204 else
203 s << "/>" << endl; 205 s << "/>" << endl;
204} 206}
205 207
206class Handler : public QXmlDefaultHandler 208class Handler : public QXmlDefaultHandler
207{ 209{
208public: 210public:
209 Handler() : m_node( 0 ), m_root( 0 ) {} 211 Handler() : m_node( 0 ), m_root( 0 ) {}
210 212
211 XMLElement *root() const { return m_root; } 213 XMLElement *root() const { return m_root; }
212 214
213 virtual bool startDocument(); 215 virtual bool startDocument();
214 virtual bool endDocument(); 216 virtual bool endDocument();
215 virtual bool startElement( const QString &ns, const QString &ln, const QString &qName, 217 virtual bool startElement( const QString &ns, const QString &ln, const QString &qName,
216 const QXmlAttributes &attr ); 218 const QXmlAttributes &attr );
217 virtual bool endElement( const QString &ns, const QString &ln, const QString &qName ); 219 virtual bool endElement( const QString &ns, const QString &ln, const QString &qName );
218 virtual bool characters( const QString &ch ); 220 virtual bool characters( const QString &ch );
219 221
220private: 222private:
221 XMLElement *m_node; 223 XMLElement *m_node;
222 XMLElement *m_root; 224 XMLElement *m_root;
223}; 225};
224 226
225bool Handler::startDocument() 227bool Handler::startDocument()
226{ 228{
227 m_root = m_node = new XMLElement; 229 m_root = m_node = new XMLElement;
228 230
229 return true; 231 return true;
230} 232}
231 233
232bool Handler::endDocument() 234bool Handler::endDocument()
233{ 235{
234 return m_root == m_node; 236 return m_root == m_node;
235} 237}
236 238
237bool Handler::startElement( const QString &, const QString &, const QString &qName, 239bool Handler::startElement( const QString &, const QString &, const QString &qName,
238 const QXmlAttributes &attr ) 240 const QXmlAttributes &attr )
239{ 241{
240 XMLElement *bm = new XMLElement; 242 XMLElement *bm = new XMLElement;
241 243
242 XMLElement::AttributeMap attributes; 244 XMLElement::AttributeMap attributes;
243 for ( int i = 0; i < attr.length(); ++i ) 245 for ( int i = 0; i < attr.length(); ++i )
244 attributes[ attr.qName( i ) ] = attr.value( i ); 246 attributes[ attr.qName( i ) ] = attr.value( i );
245 247
246 bm->setAttributes( attributes ); 248 bm->setAttributes( attributes );
247 249
248 bm->setTagName( qName ); 250 bm->setTagName( qName );
249 251
250 m_node->appendChild( bm ); 252 m_node->appendChild( bm );
251 m_node = bm; 253 m_node = bm;
252 254
253 return true; 255 return true;
254} 256}
255 257
256bool Handler::endElement( const QString &, const QString &, const QString & ) 258bool Handler::endElement( const QString &, const QString &, const QString & )
257{ 259{
258 if ( m_node == m_root ) 260 if ( m_node == m_root )
259 return false; 261 return false;
260 262
261 m_node = m_node->parent(); 263 m_node = m_node->parent();
262 return true; 264 return true;
263} 265}
264 266
265bool Handler::characters( const QString &ch ) 267bool Handler::characters( const QString &ch )
266{ 268{
267 XMLElement *textNode = new XMLElement; 269 XMLElement *textNode = new XMLElement;
268 textNode->setValue( ch ); 270 textNode->setValue( ch );
269 m_node->appendChild( textNode ); 271 m_node->appendChild( textNode );
270 return true; 272 return true;
271} 273}
272 274
273XMLElement *XMLElement::namedItem( const QString &name ) 275XMLElement *XMLElement::namedItem( const QString &name )
274{ 276{
275 XMLElement *e = m_first; 277 XMLElement *e = m_first;
276 278
277 for (; e; e = e->nextChild() ) 279 for (; e; e = e->nextChild() )
278 if ( e->tagName() == name ) 280 if ( e->tagName() == name )
279 return e; 281 return e;
280 282
281 return 0; 283 return 0;
282} 284}
283 285
284XMLElement *XMLElement::clone() const 286XMLElement *XMLElement::clone() const
285{ 287{
286 XMLElement *res = new XMLElement; 288 XMLElement *res = new XMLElement;
287 289
288 res->setTagName( m_tag ); 290 res->setTagName( m_tag );
289 res->setValue( m_value ); 291 res->setValue( m_value );
290 res->setAttributes( m_attributes ); 292 res->setAttributes( m_attributes );
291 293
292 XMLElement *e = m_first; 294 XMLElement *e = m_first;
293 for (; e; e = e->m_next ) 295 for (; e; e = e->m_next )
294 res->appendChild( e->clone() ); 296 res->appendChild( e->clone() );
295 297
296 return res; 298 return res;
297} 299}
298 300
299XMLElement *XMLElement::load( const QString &fileName ) 301XMLElement *XMLElement::load( const QString &fileName )
300{ 302{
301 QFile f( fileName ); 303 QFile f( fileName );
302 if ( !f.open( IO_ReadOnly ) ) 304 if ( !f.open( IO_ReadOnly ) )
303 return 0; 305 return 0;
304 306
305 QTextStream stream( &f ); 307 QTextStream stream( &f );
306 stream.setEncoding( QTextStream::UnicodeUTF8 ); 308 stream.setEncoding( QTextStream::UnicodeUTF8 );
307 QXmlInputSource src( stream ); 309 QXmlInputSource src( stream );
308 QXmlSimpleReader reader; 310 QXmlSimpleReader reader;
309 Handler handler; 311 Handler handler;
310 312
311 reader.setFeature( "http://trolltech.com/xml/features/report-whitespace-only-CharData", false ); 313 reader.setFeature( "http://trolltech.com/xml/features/report-whitespace-only-CharData", false );
312 reader.setContentHandler( &handler ); 314 reader.setContentHandler( &handler );
313 reader.parse( src ); 315 reader.parse( src );
314 316
315 return handler.root();; 317 return handler.root();;
316} 318}
317 319
318 320/* vim: et sw=4
321 */