diff --git a/stepmania/src/XmlFile.cpp b/stepmania/src/XmlFile.cpp index 0ce876e7c4..f6d2e20d64 100644 --- a/stepmania/src/XmlFile.cpp +++ b/stepmania/src/XmlFile.cpp @@ -14,8 +14,7 @@ #include "Foreach.h" XNode::XNode( const XNode &cpy ): - m_sName( cpy.m_sName ), - m_sValue( cpy.m_sValue ), + m_Value( cpy.m_Value ), m_attrs( cpy.m_attrs ) { FOREACH_CONST_Child( &cpy, c ) @@ -35,37 +34,30 @@ void XNode::Clear() m_attrs.clear(); } -void XNode::GetValue( RString &out ) const { out = m_sValue; } -void XNode::GetValue( int &out ) const { out = atoi(m_sValue); } -void XNode::GetValue( float &out ) const { out = StringToFloat(m_sValue); } -void XNode::GetValue( bool &out ) const { out = atoi(m_sValue) != 0; } -void XNode::GetValue( unsigned &out ) const { out = strtoul(m_sValue,NULL,0); } -void XNode::GetValue( DateTime &out ) const { out.FromString( m_sValue ); } +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 ); } -bool XNode::GetAttrValue( const RString &sName, RString &out ) const { const RString* pAttr=GetAttr(sName); if(pAttr==NULL) return false; out = *pAttr; return true; } -bool XNode::GetAttrValue( const RString &sName, int &out ) const { const RString* pAttr=GetAttr(sName); if(pAttr==NULL) return false; out = atoi(*pAttr); return true; } -bool XNode::GetAttrValue( const RString &sName, float &out ) const { const RString* pAttr=GetAttr(sName); if(pAttr==NULL) return false; out = StringToFloat(*pAttr); return true; } -bool XNode::GetAttrValue( const RString &sName, bool &out ) const { const RString* pAttr=GetAttr(sName); if(pAttr==NULL) return false; out = atoi(*pAttr) != 0; return true; } -bool XNode::GetAttrValue( const RString &sName, unsigned &out ) const { const RString* pAttr=GetAttr(sName); if(pAttr==NULL) return false; out = 0; sscanf(*pAttr,"%u",&out); return true; } -bool XNode::GetAttrValue( const RString &sName, DateTime &out ) const { const RString* pAttr=GetAttr(sName); if(pAttr==NULL) return false; out.FromString( *pAttr ); return true; } +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(); } -void XNode::SetValue( const RString &v ) { m_sValue = v; } -void XNode::SetValue( int v ) { m_sValue = ssprintf("%d",v); } -void XNode::SetValue( float v ) { m_sValue = ssprintf("%f",v); } -void XNode::SetValue( unsigned v ) { m_sValue = ssprintf("%u",v); } -void XNode::SetValue( const DateTime &v ) { m_sValue = v.GetString(); } - -const RString *XNode::GetAttr( const RString &attrname ) const +const XNodeValue *XNode::GetAttr( const RString &attrname ) const { - map::const_iterator it = m_attrs.find( attrname ); + XAttrs::const_iterator it = m_attrs.find( attrname ); if( it != m_attrs.end() ) return &it->second; return NULL; } -RString *XNode::GetAttr( const RString &attrname ) +XNodeValue *XNode::GetAttr( const RString &attrname ) { - map::iterator it = m_attrs.find( attrname ); + XAttrs::iterator it = m_attrs.find( attrname ); if( it != m_attrs.end() ) return &it->second; return NULL; @@ -122,18 +114,18 @@ bool XNode::RemoveChild( XNode *node, bool bDelete ) // detach attribute bool XNode::RemoveAttr( const RString &sName ) { - return m_attrs.erase(sName) > 0; + 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; } -void XNode::AppendAttr( const RString &sName, const RString &sValue ) +void XNode::AppendAttr( const RString &sName, const XNodeValue &val ) { DEBUG_ASSERT( sName.size() ); - pair ret = m_attrs.insert( make_pair(sName,sValue) ); + pair ret = m_attrs.insert( make_pair(sName,val) ); if( !ret.second ) - ret.first->second = sValue; // already existed + ret.first->second = val; // already existed } - -void XNode::AppendAttr( const RString &sName, float value ) { AppendAttr(sName,ssprintf("%f",value)); } -void XNode::AppendAttr( const RString &sName, int value ) { AppendAttr(sName,ssprintf("%d",value)); } -void XNode::AppendAttr( const RString &sName, unsigned value ) { AppendAttr(sName,ssprintf("%u",value)); } - diff --git a/stepmania/src/XmlFile.h b/stepmania/src/XmlFile.h index e98a01d886..0f83057d77 100644 --- a/stepmania/src/XmlFile.h +++ b/stepmania/src/XmlFile.h @@ -7,7 +7,29 @@ struct DateTime; class RageFileBasic; -typedef map XAttrs; +class XNodeValue +{ +public: + RString m_sValue; + + void GetValue( RString &out ) const; + void GetValue( int &out ) const; + void GetValue( float &out ) const; + void GetValue( bool &out ) const; + void GetValue( unsigned &out ) const; + void GetValue( DateTime &out ) const; + + template + T GetValue() const { T val; GetValue(val); return val; } + + void SetValue( const RString &v ); + void SetValue( int v ); + void SetValue( float v ); + void SetValue( unsigned v ); + void SetValue( const DateTime &v ); +}; + +typedef map XAttrs; class XNode; typedef multimap XNodes; @@ -40,35 +62,24 @@ class XNode { public: RString m_sName; // a duplicate of the m_sName in the parent's map - RString m_sValue; + XNodeValue m_Value; XNodes m_childs; // child node XAttrs m_attrs; // attributes void SetName( const RString &sName ) { m_sName = sName; } - RString GetName() const { return m_sName; } - RString GetValue() const { return m_sValue; } + const RString &GetName() const { return m_sName; } + const RString &GetValue() const { return m_Value.m_sValue; } - void GetValue( RString &out ) const; - void GetValue( int &out ) const; - void GetValue( float &out ) const; - void GetValue( bool &out ) const; - void GetValue( unsigned &out ) const; - void GetValue( DateTime &out ) const; - void SetValue( const RString &v ); - void SetValue( int v ); - void SetValue( float v ); - void SetValue( unsigned v ); - void SetValue( const DateTime &v ); + template + void GetValue( T &out ) const { m_Value.GetValue(out); } + template + void SetValue( const T val ) { m_Value.SetValue(val); } // in own attribute list - const RString *GetAttr( const RString &sAttrName ) const; - RString *GetAttr( const RString &sAttrName ); - bool GetAttrValue( const RString &sName, RString &out ) const; - bool GetAttrValue( const RString &sName, int &out ) const; - bool GetAttrValue( const RString &sName, float &out ) const; - bool GetAttrValue( const RString &sName, bool &out ) const; - bool GetAttrValue( const RString &sName, unsigned &out ) const; - bool GetAttrValue( const RString &sName, DateTime &out ) const; + const XNodeValue *GetAttr( const RString &sAttrName ) const; + XNodeValue *GetAttr( const RString &sAttrName ); + template + bool GetAttrValue( const RString &sName, T &out ) const { const XNodeValue *pAttr=GetAttr(sName); if(pAttr==NULL) return false; pAttr->GetValue(out); return true; } // in one level child nodes const XNode *GetChild( const RString &sName ) const; @@ -83,11 +94,9 @@ public: XNode *AppendChild( XNode *node ); bool RemoveChild( XNode *node, bool bDelete = true ); - void AppendAttr( const RString &sName, const RString &sValue = RString() ); - void AppendAttr( const RString &sName, float value ); - void AppendAttr( const RString &sName, int value ); - void AppendAttr( const RString &sName, unsigned value ); - void AppendAttr( const RString &sName, const DateTime &value ); + void AppendAttr( const RString &sName, const XNodeValue &val ); + template + void AppendAttr( const RString &sName, T value ) { XNodeValue val; val.SetValue( value ); AppendAttr( sName, val ); } bool RemoveAttr( const RString &sName ); XNode() { }