]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/xml/xml.cpp
added XML resources library
[wxWidgets.git] / contrib / src / xml / xml.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: xml.cpp
3 // Purpose: wxXmlDocument - XML parser & data holder class
4 // Author: Vaclav Slavik
5 // Created: 2000/03/05
6 // RCS-ID: $Id$
7 // Copyright: (c) 2000 Vaclav Slavik
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 #ifdef __GNUG__
12 #pragma implementation "xml.h"
13 #pragma implementation "xmlio.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23
24 #include "wx/wfstream.h"
25 #include "wx/datstrm.h"
26 #include "wx/zstream.h"
27 #include "wx/log.h"
28 #include "wx/intl.h"
29
30 #include "wx/xml/xml.h"
31 #include "wx/xml/xmlio.h"
32
33
34
35 wxXmlNode::wxXmlNode(wxXmlNode *parent,wxXmlNodeType type,
36 const wxString& name, const wxString& content,
37 wxXmlProperty *props, wxXmlNode *next)
38 : m_Type(type), m_Name(name), m_Content(content),
39 m_Properties(props), m_Parent(parent),
40 m_Children(NULL), m_Next(next)
41 {
42 if (m_Parent)
43 {
44 if (m_Parent->m_Children)
45 {
46 m_Next = m_Parent->m_Children;
47 m_Parent->m_Children = this;
48 }
49 else
50 m_Parent->m_Children = this;
51 }
52 }
53
54
55
56 wxXmlNode::wxXmlNode(wxXmlNodeType type, const wxString& name,
57 const wxString& content)
58 : m_Type(type), m_Name(name), m_Content(content),
59 m_Properties(NULL), m_Parent(NULL),
60 m_Children(NULL), m_Next(NULL)
61 {}
62
63
64
65 wxXmlNode::wxXmlNode(const wxXmlNode& node)
66 {
67 m_Next = NULL;
68 m_Parent = NULL;
69 DoCopy(node);
70 }
71
72
73
74 wxXmlNode& wxXmlNode::operator=(const wxXmlNode& node)
75 {
76 delete m_Properties;
77 delete m_Children;
78 DoCopy(node);
79 return *this;
80 }
81
82
83
84 void wxXmlNode::DoCopy(const wxXmlNode& node)
85 {
86 m_Type = node.m_Type;
87 m_Name = node.m_Name;
88 m_Content = node.m_Content;
89 m_Children = NULL;
90
91 wxXmlNode *n = node.m_Children;
92 while (n)
93 {
94 AddChild(new wxXmlNode(*n));
95 n = n->GetNext();
96 }
97
98 m_Properties = NULL;
99 wxXmlProperty *p = node.m_Properties;
100 while (p)
101 {
102 AddProperty(p->GetName(), p->GetValue());
103 p = p->GetNext();
104 }
105 }
106
107
108 bool wxXmlNode::HasProp(const wxString& propName) const
109 {
110 wxXmlProperty *prop = GetProperties();
111
112 while (prop)
113 {
114 if (prop->GetName() == propName) return TRUE;
115 prop = prop->GetNext();
116 }
117
118 return FALSE;
119 }
120
121
122
123 bool wxXmlNode::GetPropVal(const wxString& propName, wxString *value) const
124 {
125 wxXmlProperty *prop = GetProperties();
126
127 while (prop)
128 {
129 if (prop->GetName() == propName)
130 {
131 *value = prop->GetValue();
132 return TRUE;
133 }
134 prop = prop->GetNext();
135 }
136
137 return FALSE;
138 }
139
140
141
142 wxString wxXmlNode::GetPropVal(const wxString& propName, const wxString& defaultVal) const
143 {
144 wxString tmp;
145 if (GetPropVal(propName, &tmp))
146 return tmp;
147 else
148 return defaultVal;
149 }
150
151
152
153 void wxXmlNode::AddChild(wxXmlNode *child)
154 {
155 if (m_Children == NULL)
156 m_Children = child;
157 else
158 {
159 wxXmlNode *ch = m_Children;
160 while (ch->m_Next) ch = ch->m_Next;
161 ch->m_Next = child;
162 }
163 child->m_Next = NULL;
164 child->m_Parent = this;
165 }
166
167
168
169 void wxXmlNode::InsertChild(wxXmlNode *child, wxXmlNode *before_node)
170 {
171 wxASSERT_MSG(before_node->GetParent() == this, _T("wxXmlNode::InsertChild - the node has incorrect parent"));
172
173 if (m_Children == before_node)
174 m_Children = child;
175 else
176 {
177 wxXmlNode *ch = m_Children;
178 while (ch->m_Next != before_node) ch = ch->m_Next;
179 ch->m_Next = child;
180 }
181
182 child->m_Parent = this;
183 child->m_Next = before_node;
184 }
185
186
187
188 bool wxXmlNode::RemoveChild(wxXmlNode *child)
189 {
190 if (m_Children == NULL)
191 return FALSE;
192 else if (m_Children == child)
193 {
194 m_Children = child->m_Next;
195 child->m_Parent = NULL;
196 child->m_Next = NULL;
197 return TRUE;
198 }
199 else
200 {
201 wxXmlNode *ch = m_Children;
202 while (ch->m_Next)
203 {
204 if (ch->m_Next == child)
205 {
206 ch->m_Next = child->m_Next;
207 child->m_Parent = NULL;
208 child->m_Next = NULL;
209 return TRUE;
210 }
211 ch = ch->m_Next;
212 }
213 return FALSE;
214 }
215 }
216
217
218
219 void wxXmlNode::AddProperty(const wxString& name, const wxString& value)
220 {
221 AddProperty(new wxXmlProperty(name, value, NULL));
222 }
223
224 void wxXmlNode::AddProperty(wxXmlProperty *prop)
225 {
226 if (m_Properties == NULL)
227 m_Properties = prop;
228 else
229 {
230 wxXmlProperty *p = m_Properties;
231 while (p->GetNext()) p = p->GetNext();
232 p->SetNext(prop);
233 }
234 }
235
236
237
238 bool wxXmlNode::DeleteProperty(const wxString& name)
239 {
240 if (m_Properties == NULL)
241 return FALSE;
242
243 else if (m_Properties->GetName() == name)
244 {
245 wxXmlProperty *prop = m_Properties;
246 m_Properties = prop->GetNext();
247 prop->SetNext(NULL);
248 delete prop;
249 return TRUE;
250 }
251
252 else
253 {
254 wxXmlProperty *p = m_Properties;
255 while (p->GetNext())
256 {
257 if (p->GetNext()->GetName() == name)
258 {
259 wxXmlProperty *prop = p->GetNext();
260 p->SetNext(prop->GetNext());
261 prop->SetNext(NULL);
262 delete prop;
263 return TRUE;
264 }
265 p = p->GetNext();
266 }
267 return FALSE;
268 }
269 }
270
271
272
273
274
275
276
277
278
279
280 wxXmlDocument::wxXmlDocument(const wxString& filename, wxXmlIOType io_type)
281 : wxObject(), m_Root(NULL)
282 {
283 if (!Load(filename, io_type))
284 {
285 delete m_Root;
286 m_Root = NULL;
287 }
288 }
289
290
291
292 wxXmlDocument::wxXmlDocument(wxInputStream& stream, wxXmlIOType io_type)
293 : wxObject(), m_Root(NULL)
294 {
295 if (!Load(stream, io_type))
296 {
297 delete m_Root;
298 m_Root = NULL;
299 }
300 }
301
302
303
304 wxXmlDocument::wxXmlDocument(const wxXmlDocument& doc)
305 {
306 DoCopy(doc);
307 }
308
309
310
311 wxXmlDocument& wxXmlDocument::operator=(const wxXmlDocument& doc)
312 {
313 delete m_Root;
314 DoCopy(doc);
315 return *this;
316 }
317
318
319
320 void wxXmlDocument::DoCopy(const wxXmlDocument& doc)
321 {
322 m_Version = doc.m_Version;
323 m_Encoding = doc.m_Encoding;
324 m_Root = new wxXmlNode(*doc.m_Root);
325 }
326
327
328
329 bool wxXmlDocument::Load(const wxString& filename, wxXmlIOType io_type)
330 {
331 wxFileInputStream stream(filename);
332 return Load(stream, io_type);
333 }
334
335
336
337 bool wxXmlDocument::Load(wxInputStream& stream, wxXmlIOType io_type)
338 {
339 wxNode *n = sm_Handlers->GetFirst();
340 while (n)
341 {
342 wxXmlIOHandler *h = (wxXmlIOHandler*) n->GetData();
343
344 if ((io_type == wxXML_IO_AUTO || io_type == h->GetType()) &&
345 h->CanLoad(stream))
346 {
347 return h->Load(stream, *this);
348 }
349 n = n->GetNext();
350 }
351 wxLogError(_("Cannot find XML I/O handler capable of loading this format."));
352 return FALSE;
353 }
354
355
356
357 bool wxXmlDocument::Save(const wxString& filename, wxXmlIOType io_type) const
358 {
359 wxFileOutputStream stream(filename);
360 return Save(stream, io_type);
361 }
362
363
364
365 bool wxXmlDocument::Save(wxOutputStream& stream, wxXmlIOType io_type) const
366 {
367 wxNode *n = sm_Handlers->GetFirst();
368 while (n)
369 {
370 wxXmlIOHandler *h = (wxXmlIOHandler*) n->GetData();
371 if (io_type == h->GetType() && h->CanSave())
372 {
373 return h->Save(stream, *this);
374 }
375 n = n->GetNext();
376 }
377 wxLogError(_("Cannot find XML I/O handler capable of saving in this format."));
378 return FALSE;
379 }
380
381
382
383
384
385
386 wxList *wxXmlDocument::sm_Handlers = NULL;
387
388 void wxXmlDocument::AddHandler(wxXmlIOHandler *handler)
389 {
390 if (sm_Handlers == NULL)
391 {
392 sm_Handlers = new wxList;
393 sm_Handlers->DeleteContents(TRUE);
394 }
395 sm_Handlers->Append(handler);
396 }
397
398
399 void wxXmlDocument::CleanUpHandlers()
400 {
401 delete sm_Handlers;
402 sm_Handlers = NULL;
403 }
404
405
406 void wxXmlDocument::InitStandardHandlers()
407 {
408 AddHandler(new wxXmlIOHandlerBin);
409 AddHandler(new wxXmlIOHandlerLibxml);
410 }
411
412
413 #include "wx/module.h"
414
415 class wxXmlModule: public wxModule
416 {
417 DECLARE_DYNAMIC_CLASS(wxXmlModule)
418 public:
419 wxXmlModule() {}
420 bool OnInit() { wxXmlDocument::InitStandardHandlers(); return TRUE; };
421 void OnExit() { wxXmlDocument::CleanUpHandlers(); };
422 };
423
424 IMPLEMENT_DYNAMIC_CLASS(wxXmlModule, wxModule)