Merge text values into attributes; use TEXT_ATTRIBUTE_NAME for

the text value.

This means that FOREACH_Attr will iterate over the text value.
Compare with TEXT_ATTRIBUTE_NAME if you explicitly don't want
that.

This is simpler; an XNode branches out in two places--attributes
and children--instead of three.

It also means that nodes without any text data actually don't
have any text data--the attribute simply doesn't exist.  The
*TextValue functions are also no longer needed, though some
are left in now for compatibility (and maybe convenience).
This commit is contained in:
Glenn Maynard
2007-02-11 07:27:29 +00:00
parent e294995d16
commit b0430161b9
3 changed files with 18 additions and 28 deletions
+3 -7
View File
@@ -14,21 +14,20 @@
#include "Foreach.h" #include "Foreach.h"
#include "LuaManager.h" #include "LuaManager.h"
const RString XNode::TEXT_ATTRIBUTE = "__TEXT__";
XNode::XNode() XNode::XNode()
{ {
m_pValue = new XNodeStringValue;
} }
XNode::XNode( const RString &sName ) XNode::XNode( const RString &sName )
{ {
m_sName = sName; m_sName = sName;
m_pValue = new XNodeStringValue;
} }
XNode::XNode( const XNode &cpy ): XNode::XNode( const XNode &cpy ):
m_sName( cpy.m_sName ) m_sName( cpy.m_sName )
{ {
m_pValue = cpy.m_pValue->Copy();
FOREACH_CONST_Attr( &cpy, pAttr ) FOREACH_CONST_Attr( &cpy, pAttr )
this->AppendAttrFrom( pAttr->first, pAttr->second->Copy() ); this->AppendAttrFrom( pAttr->first, pAttr->second->Copy() );
FOREACH_CONST_Child( &cpy, c ) FOREACH_CONST_Child( &cpy, c )
@@ -38,7 +37,6 @@ XNode::XNode( const XNode &cpy ):
void XNode::Clear() void XNode::Clear()
{ {
Free(); Free();
m_pValue = new XNodeStringValue;
} }
void XNode::Free() void XNode::Free()
@@ -49,8 +47,6 @@ void XNode::Free()
delete pAttr->second; delete pAttr->second;
m_childs.clear(); m_childs.clear();
m_attrs.clear(); m_attrs.clear();
SAFE_DELETE( m_pValue );
} }
void XNodeStringValue::GetValue( RString &out ) const { out = m_sValue; } void XNodeStringValue::GetValue( RString &out ) const { out = m_sValue; }
@@ -119,7 +115,7 @@ bool XNode::PushChildValue( lua_State *L, const RString &sName ) const
lua_pushnil( L ); lua_pushnil( L );
return false; return false;
} }
pChild->m_pValue->PushValue( L ); pChild->GetAttr(XNode::TEXT_ATTRIBUTE)->PushValue( L );
return true; return true;
} }
+3 -8
View File
@@ -80,26 +80,21 @@ typedef multimap<RString,XNode*> XNodes;
Var##Iter != (pNode)->m_childs.end(); \ Var##Iter != (pNode)->m_childs.end(); \
++Var##Iter ) ++Var##Iter )
// XMLNode structure
class XNode class XNode
{ {
public: public:
RString m_sName; // a duplicate of the m_sName in the parent's map RString m_sName; // a duplicate of the m_sName in the parent's map
XNodeValue *m_pValue;
XNodes m_childs; // child node XNodes m_childs; // child node
XAttrs m_attrs; // attributes XAttrs m_attrs; // attributes
void SetName( const RString &sName ) { m_sName = sName; } void SetName( const RString &sName ) { m_sName = sName; }
const RString &GetName() const { return m_sName; } const RString &GetName() const { return m_sName; }
const XNodeValue *GetTextValue() const { return m_pValue; } static const RString TEXT_ATTRIBUTE;
XNodeValue *GetTextValue() { return m_pValue; }
void SetTextValueFrom( XNodeValue *pValue ) { delete m_pValue; m_pValue = pValue; }
template <typename T> template <typename T>
void GetTextValue( T &out ) const { m_pValue->GetValue(out); } void GetTextValue( T &out ) const { GetAttrValue(TEXT_ATTRIBUTE, out); }
template <typename T> template <typename T>
void SetTextValue( const T val ) { m_pValue->SetValue(val); } void SetTextValue( const T val ) { AppendAttr(TEXT_ATTRIBUTE, val); }
// in own attribute list // in own attribute list
const XNodeValue *GetAttr( const RString &sAttrName ) const; const XNodeValue *GetAttr( const RString &sAttrName ) const;
+11 -12
View File
@@ -293,7 +293,7 @@ unsigned LoadInternal( XNode *pNode, const RString &xml, RString &sErrorOut, uns
// open/close tag <TAG ..> ... </TAG> // open/close tag <TAG ..> ... </TAG>
// ^- current pointer // ^- current pointer
if( XIsEmptyString(pNode->GetTextValue()->GetValue<RString>()) ) if( pNode->GetAttr(XNode::TEXT_ATTRIBUTE) == NULL )
{ {
// Text Value // Text Value
++iOffset; ++iOffset;
@@ -377,7 +377,7 @@ unsigned LoadInternal( XNode *pNode, const RString &xml, RString &sErrorOut, uns
} }
else // Alone child Tag Loaded else // Alone child Tag Loaded
{ {
if( XIsEmptyString(pNode->GetTextValue()->GetValue<RString>()) && iOffset < xml.size() && xml[iOffset] != chXMLTagOpen ) if( pNode->GetAttr(XNode::TEXT_ATTRIBUTE) == NULL && iOffset < xml.size() && xml[iOffset] != chXMLTagOpen )
{ {
// Text Value // Text Value
unsigned iEnd = xml.find( chXMLTagOpen, iOffset ); unsigned iEnd = xml.find( chXMLTagOpen, iOffset );
@@ -416,19 +416,20 @@ bool GetXMLInternal( const XNode *pNode, RageFileBasic &f, bool bWriteTabs, int
WRITE( pNode->GetName() ); WRITE( pNode->GetName() );
// <TAG Attr1="Val1" // <TAG Attr1="Val1"
if( !pNode->m_attrs.empty() )
WRITE( " " );
FOREACH_CONST_Attr( pNode, p ) FOREACH_CONST_Attr( pNode, p )
{ {
if( p->first == XNode::TEXT_ATTRIBUTE )
continue;
RString attr( p->second->GetValue<RString>() ); RString attr( p->second->GetValue<RString>() );
ReplaceEntityText( attr, g_mapCharsToEntities ); ReplaceEntityText( attr, g_mapCharsToEntities );
WRITE( " " );
WRITE( p->first ); WRITE( p->first );
WRITE( "='" ); WRITE( "='" );
WRITE( attr ); WRITE( attr );
WRITE( "'" ); WRITE( "'" );
} }
if( pNode->m_childs.empty() && pNode->GetTextValue()->GetValue<RString>().empty() ) if( pNode->m_childs.empty() && pNode->GetAttr(XNode::TEXT_ATTRIBUTE) == NULL )
{ {
// <TAG Attr1="Val1"/> alone tag // <TAG Attr1="Val1"/> alone tag
WRITE( "/>" ); WRITE( "/>" );
@@ -446,7 +447,8 @@ bool GetXMLInternal( const XNode *pNode, RageFileBasic &f, bool bWriteTabs, int
return false; return false;
// Text Value // Text Value
if( !pNode->GetTextValue()->GetValue<RString>().empty() ) const XNodeValue *pText = pNode->GetAttr( XNode::TEXT_ATTRIBUTE );
if( pText != NULL )
{ {
if( !pNode->m_childs.empty() ) if( !pNode->m_childs.empty() )
{ {
@@ -456,7 +458,7 @@ bool GetXMLInternal( const XNode *pNode, RageFileBasic &f, bool bWriteTabs, int
WRITE( "\t" ); WRITE( "\t" );
} }
RString s; RString s;
pNode->GetTextValue( s ); pText->GetValue( s );
ReplaceEntityText( s, g_mapCharsToEntities ); ReplaceEntityText( s, g_mapCharsToEntities );
WRITE( s ); WRITE( s );
} }
@@ -617,12 +619,9 @@ void XmlFileUtil::CompileXNodeTree( XNode *pNode, const RString &sFile )
FOREACH_Child( pNode, pChild ) FOREACH_Child( pNode, pChild )
aToCompile.push_back( pChild ); aToCompile.push_back( pChild );
XNodeValue *pValue = CompileXMLNodeValue( L, pNode->GetName(), pNode->GetTextValue(), sFile );
pNode->SetTextValueFrom( pValue );
FOREACH_Attr( pNode, pAttr ) FOREACH_Attr( pNode, pAttr )
{ {
pValue = CompileXMLNodeValue( L, pAttr->first, pAttr->second, sFile ); XNodeValue *pValue = CompileXMLNodeValue( L, pAttr->first, pAttr->second, sFile );
delete pAttr->second; delete pAttr->second;
pAttr->second = pValue; pAttr->second = pValue;
} }
@@ -642,7 +641,7 @@ namespace
XNodeLuaValue *pValue = new XNodeLuaValue; XNodeLuaValue *pValue = new XNodeLuaValue;
lua_pushvalue( L, -1 ); lua_pushvalue( L, -1 );
pValue->SetValueFromStack( L ); pValue->SetValueFromStack( L );
pNode->SetTextValueFrom( pValue ); pNode->AppendAttrFrom( XNode::TEXT_ATTRIBUTE, pValue );
} }
/* Iterate over the table, pulling out attributes and tables to process. */ /* Iterate over the table, pulling out attributes and tables to process. */