added XML resources library
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@7831 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
424
contrib/src/xml/xml.cpp
Normal file
424
contrib/src/xml/xml.cpp
Normal file
@@ -0,0 +1,424 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 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, _T("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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
wxList *wxXmlDocument::sm_Handlers = NULL;
|
||||
|
||||
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);
|
||||
AddHandler(new wxXmlIOHandlerLibxml);
|
||||
}
|
||||
|
||||
|
||||
#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)
|
Reference in New Issue
Block a user