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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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. */
|
||||||
|
|||||||
Reference in New Issue
Block a user