X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/999d9a9f795cfc745681989ae0f30e531cde059f..78d14f80e9a72041ede52c30d912ec5cef21b1b3:/src/xrc/xml.cpp diff --git a/src/xrc/xml.cpp b/src/xrc/xml.cpp new file mode 100644 index 0000000000..d6ba14d820 --- /dev/null +++ b/src/xrc/xml.cpp @@ -0,0 +1,441 @@ +///////////////////////////////////////////////////////////////////////////// +// 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/xrc/xml.h" +#include "wx/xrc/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); +} +