-/////////////////////////////////////////////////////////////////////////////
-// Name: xml.cpp
-// Purpose: wxXmlDocument - XML parser & data holder class
-// Author: Vaclav Slavik
-// Created: 2000/03/05
-// RCS-ID: $Id$
-// Copyright: (c) 2000 Vaclav Slavik
-// Licence: wxWindows licence
-/////////////////////////////////////////////////////////////////////////////
-
-#ifdef __GNUG__
-#pragma implementation "xml.h"
-#pragma implementation "xmlio.h"
-#endif
-
-// For compilers that support precompilation, includes "wx.h".
-#include "wx/wxprec.h"
-
-#ifdef __BORLANDC__
- #pragma hdrstop
-#endif
-
-
-#include "wx/wfstream.h"
-#include "wx/datstrm.h"
-#include "wx/zstream.h"
-#include "wx/log.h"
-#include "wx/intl.h"
-
-#include "wx/xml/xml.h"
-#include "wx/xml/xmlio.h"
-
-
-
-wxXmlNode::wxXmlNode(wxXmlNode *parent,wxXmlNodeType type,
- const wxString& name, const wxString& content,
- wxXmlProperty *props, wxXmlNode *next)
- : m_type(type), m_name(name), m_content(content),
- m_properties(props), m_parent(parent),
- m_children(NULL), m_next(next)
-{
- if (m_parent)
- {
- if (m_parent->m_children)
- {
- m_next = m_parent->m_children;
- m_parent->m_children = this;
- }
- else
- m_parent->m_children = this;
- }
-}
-
-
-
-wxXmlNode::wxXmlNode(wxXmlNodeType type, const wxString& name,
- const wxString& content)
- : m_type(type), m_name(name), m_content(content),
- m_properties(NULL), m_parent(NULL),
- m_children(NULL), m_next(NULL)
-{}
-
-
-
-wxXmlNode::wxXmlNode(const wxXmlNode& node)
-{
- m_next = NULL;
- m_parent = NULL;
- DoCopy(node);
-}
-
-
-
-wxXmlNode& wxXmlNode::operator=(const wxXmlNode& node)
-{
- delete m_properties;
- delete m_children;
- DoCopy(node);
- return *this;
-}
-
-
-
-void wxXmlNode::DoCopy(const wxXmlNode& node)
-{
- m_type = node.m_type;
- m_name = node.m_name;
- m_content = node.m_content;
- m_children = NULL;
-
- wxXmlNode *n = node.m_children;
- while (n)
- {
- AddChild(new wxXmlNode(*n));
- n = n->GetNext();
- }
-
- m_properties = NULL;
- wxXmlProperty *p = node.m_properties;
- while (p)
- {
- AddProperty(p->GetName(), p->GetValue());
- p = p->GetNext();
- }
-}
-
-
-bool wxXmlNode::HasProp(const wxString& propName) const
-{
- wxXmlProperty *prop = GetProperties();
-
- while (prop)
- {
- if (prop->GetName() == propName) return TRUE;
- prop = prop->GetNext();
- }
-
- return FALSE;
-}
-
-
-
-bool wxXmlNode::GetPropVal(const wxString& propName, wxString *value) const
-{
- wxXmlProperty *prop = GetProperties();
-
- while (prop)
- {
- if (prop->GetName() == propName)
- {
- *value = prop->GetValue();
- return TRUE;
- }
- prop = prop->GetNext();
- }
-
- return FALSE;
-}
-
-
-
-wxString wxXmlNode::GetPropVal(const wxString& propName, const wxString& defaultVal) const
-{
- wxString tmp;
- if (GetPropVal(propName, &tmp))
- return tmp;
- else
- return defaultVal;
-}
-
-
-
-void wxXmlNode::AddChild(wxXmlNode *child)
-{
- if (m_children == NULL)
- m_children = child;
- else
- {
- wxXmlNode *ch = m_children;
- while (ch->m_next) ch = ch->m_next;
- ch->m_next = child;
- }
- child->m_next = NULL;
- child->m_parent = this;
-}
-
-
-
-void wxXmlNode::InsertChild(wxXmlNode *child, wxXmlNode *before_node)
-{
- wxASSERT_MSG(before_node->GetParent() == this, wxT("wxXmlNode::InsertChild - the node has incorrect parent"));
-
- if (m_children == before_node)
- m_children = child;
- else
- {
- wxXmlNode *ch = m_children;
- while (ch->m_next != before_node) ch = ch->m_next;
- ch->m_next = child;
- }
-
- child->m_parent = this;
- child->m_next = before_node;
-}
-
-
-
-bool wxXmlNode::RemoveChild(wxXmlNode *child)
-{
- if (m_children == NULL)
- return FALSE;
- else if (m_children == child)
- {
- m_children = child->m_next;
- child->m_parent = NULL;
- child->m_next = NULL;
- return TRUE;
- }
- else
- {
- wxXmlNode *ch = m_children;
- while (ch->m_next)
- {
- if (ch->m_next == child)
- {
- ch->m_next = child->m_next;
- child->m_parent = NULL;
- child->m_next = NULL;
- return TRUE;
- }
- ch = ch->m_next;
- }
- return FALSE;
- }
-}
-
-
-
-void wxXmlNode::AddProperty(const wxString& name, const wxString& value)
-{
- AddProperty(new wxXmlProperty(name, value, NULL));
-}
-
-void wxXmlNode::AddProperty(wxXmlProperty *prop)
-{
- if (m_properties == NULL)
- m_properties = prop;
- else
- {
- wxXmlProperty *p = m_properties;
- while (p->GetNext()) p = p->GetNext();
- p->SetNext(prop);
- }
-}
-
-
-
-bool wxXmlNode::DeleteProperty(const wxString& name)
-{
- if (m_properties == NULL)
- return FALSE;
-
- else if (m_properties->GetName() == name)
- {
- wxXmlProperty *prop = m_properties;
- m_properties = prop->GetNext();
- prop->SetNext(NULL);
- delete prop;
- return TRUE;
- }
-
- else
- {
- wxXmlProperty *p = m_properties;
- while (p->GetNext())
- {
- if (p->GetNext()->GetName() == name)
- {
- wxXmlProperty *prop = p->GetNext();
- p->SetNext(prop->GetNext());
- prop->SetNext(NULL);
- delete prop;
- return TRUE;
- }
- p = p->GetNext();
- }
- return FALSE;
- }
-}
-
-
-
-
-
-
-
-
-wxList *wxXmlDocument::sm_handlers = NULL;
-
-
-
-wxXmlDocument::wxXmlDocument(const wxString& filename, wxXmlIOType io_type)
- : wxObject(), m_root(NULL)
-{
- if (!Load(filename, io_type))
- {
- delete m_root;
- m_root = NULL;
- }
-}
-
-
-
-wxXmlDocument::wxXmlDocument(wxInputStream& stream, wxXmlIOType io_type)
- : wxObject(), m_root(NULL)
-{
- if (!Load(stream, io_type))
- {
- delete m_root;
- m_root = NULL;
- }
-}
-
-
-
-wxXmlDocument::wxXmlDocument(const wxXmlDocument& doc)
-{
- DoCopy(doc);
-}
-
-
-
-wxXmlDocument& wxXmlDocument::operator=(const wxXmlDocument& doc)
-{
- delete m_root;
- DoCopy(doc);
- return *this;
-}
-
-
-
-void wxXmlDocument::DoCopy(const wxXmlDocument& doc)
-{
- m_version = doc.m_version;
- m_encoding = doc.m_encoding;
- m_root = new wxXmlNode(*doc.m_root);
-}
-
-
-
-bool wxXmlDocument::Load(const wxString& filename, wxXmlIOType io_type)
-{
- wxFileInputStream stream(filename);
- return Load(stream, io_type);
-}
-
-
-
-bool wxXmlDocument::Load(wxInputStream& stream, wxXmlIOType io_type)
-{
- wxNode *n = sm_handlers->GetFirst();
- while (n)
- {
- wxXmlIOHandler *h = (wxXmlIOHandler*) n->GetData();
-
- if ((io_type == wxXML_IO_AUTO || io_type == h->GetType()) &&
- h->CanLoad(stream))
- {
- return h->Load(stream, *this);
- }
- n = n->GetNext();
- }
- wxLogError(_("Cannot find XML I/O handler capable of loading this format."));
- return FALSE;
-}
-
-
-
-bool wxXmlDocument::Save(const wxString& filename, wxXmlIOType io_type) const
-{
- wxFileOutputStream stream(filename);
- return Save(stream, io_type);
-}
-
-
-
-bool wxXmlDocument::Save(wxOutputStream& stream, wxXmlIOType io_type) const
-{
- wxNode *n = sm_handlers->GetFirst();
- while (n)
- {
- wxXmlIOHandler *h = (wxXmlIOHandler*) n->GetData();
- if (io_type == h->GetType() && h->CanSave())
- {
- return h->Save(stream, *this);
- }
- n = n->GetNext();
- }
- wxLogError(_("Cannot find XML I/O handler capable of saving in this format."));
- return FALSE;
-}
-
-
-
-
-
-
-void wxXmlDocument::AddHandler(wxXmlIOHandler *handler)
-{
- if (sm_handlers == NULL)
- {
- sm_handlers = new wxList;
- sm_handlers->DeleteContents(TRUE);
- }
- sm_handlers->Append(handler);
-}
-
-
-void wxXmlDocument::CleanUpHandlers()
-{
- delete sm_handlers;
- sm_handlers = NULL;
-}
-
-
-void wxXmlDocument::InitStandardHandlers()
-{
- AddHandler(new wxXmlIOHandlerBin);
-#if wxUSE_ZLIB
- AddHandler(new wxXmlIOHandlerBinZ);
-#endif
- AddHandler(new wxXmlIOHandlerExpat);
- AddHandler(new wxXmlIOHandlerWriter);
-}
-
-
-#include "wx/module.h"
-
-class wxXmlModule: public wxModule
-{
- DECLARE_DYNAMIC_CLASS(wxXmlModule)
- public:
- wxXmlModule() {}
- bool OnInit() { wxXmlDocument::InitStandardHandlers(); return TRUE; };
- void OnExit() { wxXmlDocument::CleanUpHandlers(); };
-};
-
-IMPLEMENT_DYNAMIC_CLASS(wxXmlModule, wxModule)
-
-
-
-
-// When wxXml is loaded dynamically after the application is already running
-// then the built-in module system won't pick this one up. Add it manually.
-void wxXmlInitXmlModule()
-{
- wxModule* module = new wxXmlModule;
- module->Init();
- wxModule::RegisterModule(module);
-}
-