2005-10-11 09:37:18 +00:00
|
|
|
// Adapted from http://www.codeproject.com/cpp/xmlite.asp.
|
|
|
|
|
// On 2004-02-09 Cho, Kyung-Min gave us permission to use and modify this
|
|
|
|
|
// library.
|
|
|
|
|
//
|
|
|
|
|
// XmlFile : XML Lite Parser Library
|
|
|
|
|
// by Cho, Kyung Min: bro@shinbiro.com 2002-10-30
|
|
|
|
|
|
2004-02-09 08:10:01 +00:00
|
|
|
#include "global.h"
|
|
|
|
|
#include "XmlFile.h"
|
2004-02-10 09:42:01 +00:00
|
|
|
#include "RageFile.h"
|
2004-04-02 05:06:32 +00:00
|
|
|
#include "RageLog.h"
|
2004-07-18 21:55:49 +00:00
|
|
|
#include "RageUtil.h"
|
|
|
|
|
#include "DateTime.h"
|
2005-01-07 09:09:23 +00:00
|
|
|
#include "Foreach.h"
|
2004-02-09 08:10:01 +00:00
|
|
|
|
2005-10-11 09:35:53 +00:00
|
|
|
XNode::XNode( const XNode &cpy ):
|
2006-10-02 22:47:16 +00:00
|
|
|
m_Value( cpy.m_Value ),
|
2005-10-11 10:34:27 +00:00
|
|
|
m_attrs( cpy.m_attrs )
|
2005-10-11 09:35:53 +00:00
|
|
|
{
|
|
|
|
|
FOREACH_CONST_Child( &cpy, c )
|
|
|
|
|
this->AppendChild( new XNode(*c) );
|
|
|
|
|
}
|
|
|
|
|
|
2004-04-18 10:41:54 +00:00
|
|
|
XNode::~XNode()
|
2004-02-09 08:10:01 +00:00
|
|
|
{
|
2005-01-07 14:28:00 +00:00
|
|
|
Clear();
|
2004-02-09 08:10:01 +00:00
|
|
|
}
|
|
|
|
|
|
2005-01-07 14:28:00 +00:00
|
|
|
void XNode::Clear()
|
2004-02-09 08:10:01 +00:00
|
|
|
{
|
2005-01-07 09:09:23 +00:00
|
|
|
FOREACH_Child( this, p )
|
|
|
|
|
SAFE_DELETE( p );
|
2005-01-07 14:28:00 +00:00
|
|
|
m_childs.clear();
|
|
|
|
|
m_attrs.clear();
|
2004-02-09 08:10:01 +00:00
|
|
|
}
|
|
|
|
|
|
2006-10-02 22:47:16 +00:00
|
|
|
void XNodeValue::GetValue( RString &out ) const { out = m_sValue; }
|
|
|
|
|
void XNodeValue::GetValue( int &out ) const { out = atoi(m_sValue); }
|
|
|
|
|
void XNodeValue::GetValue( float &out ) const { out = StringToFloat(m_sValue); }
|
|
|
|
|
void XNodeValue::GetValue( bool &out ) const { out = atoi(m_sValue) != 0; }
|
|
|
|
|
void XNodeValue::GetValue( unsigned &out ) const { out = strtoul(m_sValue,NULL,0); }
|
|
|
|
|
void XNodeValue::GetValue( DateTime &out ) const { out.FromString( m_sValue ); }
|
|
|
|
|
|
|
|
|
|
void XNodeValue::SetValue( const RString &v ) { m_sValue = v; }
|
|
|
|
|
void XNodeValue::SetValue( int v ) { m_sValue = ssprintf("%d",v); }
|
|
|
|
|
void XNodeValue::SetValue( float v ) { m_sValue = ssprintf("%f",v); }
|
|
|
|
|
void XNodeValue::SetValue( unsigned v ) { m_sValue = ssprintf("%u",v); }
|
|
|
|
|
void XNodeValue::SetValue( const DateTime &v ) { m_sValue = v.GetString(); }
|
|
|
|
|
|
|
|
|
|
const XNodeValue *XNode::GetAttr( const RString &attrname ) const
|
2004-02-22 05:12:23 +00:00
|
|
|
{
|
2006-10-02 22:47:16 +00:00
|
|
|
XAttrs::const_iterator it = m_attrs.find( attrname );
|
2005-01-07 14:28:00 +00:00
|
|
|
if( it != m_attrs.end() )
|
2005-10-11 10:24:07 +00:00
|
|
|
return &it->second;
|
2004-02-22 05:12:23 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2006-10-02 22:47:16 +00:00
|
|
|
XNodeValue *XNode::GetAttr( const RString &attrname )
|
2004-02-09 08:10:01 +00:00
|
|
|
{
|
2006-10-02 22:47:16 +00:00
|
|
|
XAttrs::iterator it = m_attrs.find( attrname );
|
2005-01-07 14:28:00 +00:00
|
|
|
if( it != m_attrs.end() )
|
2005-10-11 10:24:07 +00:00
|
|
|
return &it->second;
|
2004-02-09 08:10:01 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2005-12-27 23:43:49 +00:00
|
|
|
XNode *XNode::GetChild( const RString &sName )
|
2004-02-09 08:10:01 +00:00
|
|
|
{
|
2005-12-27 23:43:49 +00:00
|
|
|
multimap<RString, XNode*>::iterator it = m_childs.find( sName );
|
2005-01-07 14:28:00 +00:00
|
|
|
if( it != m_childs.end() )
|
|
|
|
|
{
|
2005-09-04 16:45:38 +00:00
|
|
|
DEBUG_ASSERT( sName == it->second->m_sName );
|
2005-01-07 09:09:23 +00:00
|
|
|
return it->second;
|
2005-01-07 14:28:00 +00:00
|
|
|
}
|
2004-02-09 08:10:01 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2005-12-27 23:43:49 +00:00
|
|
|
const XNode *XNode::GetChild( const RString &sName ) const
|
2004-02-19 03:19:41 +00:00
|
|
|
{
|
2005-12-27 23:43:49 +00:00
|
|
|
multimap<RString, XNode*>::const_iterator it = m_childs.find( sName );
|
2005-01-07 14:28:00 +00:00
|
|
|
if( it != m_childs.end() )
|
|
|
|
|
{
|
2005-09-04 16:45:38 +00:00
|
|
|
DEBUG_ASSERT( sName == it->second->m_sName );
|
2005-01-07 09:09:23 +00:00
|
|
|
return it->second;
|
2005-01-07 14:28:00 +00:00
|
|
|
}
|
2004-02-19 03:19:41 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2004-07-23 02:27:37 +00:00
|
|
|
XNode *XNode::AppendChild( XNode *node )
|
2004-02-09 08:10:01 +00:00
|
|
|
{
|
2005-01-07 14:28:00 +00:00
|
|
|
DEBUG_ASSERT( node->m_sName.size() );
|
2005-10-11 09:35:53 +00:00
|
|
|
|
|
|
|
|
/* Hinted insert: optimize for alphabetical inserts, for the copy ctor. */
|
2005-12-27 23:43:49 +00:00
|
|
|
m_childs.insert( m_childs.end(), pair<RString,XNode*>(node->m_sName,node) );
|
2004-02-09 08:10:01 +00:00
|
|
|
return node;
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-15 22:58:11 +00:00
|
|
|
// detach node and delete object
|
2006-10-02 06:36:07 +00:00
|
|
|
bool XNode::RemoveChild( XNode *node, bool bDelete )
|
2004-02-09 08:10:01 +00:00
|
|
|
{
|
2005-12-27 23:43:49 +00:00
|
|
|
FOREACHMM( RString, XNode*, m_childs, p )
|
2004-02-09 08:10:01 +00:00
|
|
|
{
|
2005-01-07 09:09:23 +00:00
|
|
|
if( p->second == node )
|
|
|
|
|
{
|
2006-10-02 06:36:07 +00:00
|
|
|
if( bDelete )
|
|
|
|
|
SAFE_DELETE( p->second );
|
2005-01-07 14:28:00 +00:00
|
|
|
m_childs.erase( p );
|
2005-01-07 09:09:23 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2004-02-09 08:10:01 +00:00
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-10-11 10:24:07 +00:00
|
|
|
// detach attribute
|
2005-12-27 23:43:49 +00:00
|
|
|
bool XNode::RemoveAttr( const RString &sName )
|
2004-02-09 08:10:01 +00:00
|
|
|
{
|
2006-10-02 22:47:16 +00:00
|
|
|
XAttrs::iterator begin = m_attrs.lower_bound( sName );
|
|
|
|
|
XAttrs::iterator end = m_attrs.upper_bound( sName );
|
|
|
|
|
if( begin == end )
|
|
|
|
|
return false;
|
|
|
|
|
m_attrs.erase( begin, end );
|
|
|
|
|
return true;
|
2004-02-09 08:10:01 +00:00
|
|
|
}
|
|
|
|
|
|
2006-10-02 22:47:16 +00:00
|
|
|
void XNode::AppendAttr( const RString &sName, const XNodeValue &val )
|
2004-02-09 08:10:01 +00:00
|
|
|
{
|
2006-10-01 14:22:15 +00:00
|
|
|
DEBUG_ASSERT( sName.size() );
|
2006-10-02 22:47:16 +00:00
|
|
|
pair<XAttrs::iterator,bool> ret = m_attrs.insert( make_pair(sName,val) );
|
2005-10-11 11:12:24 +00:00
|
|
|
if( !ret.second )
|
2006-10-02 22:47:16 +00:00
|
|
|
ret.first->second = val; // already existed
|
2004-02-09 08:10:01 +00:00
|
|
|
}
|