use CString

This commit is contained in:
Glenn Maynard
2005-09-06 18:25:16 +00:00
parent 6670c55a07
commit 1c5ce3bf8b
2 changed files with 96 additions and 96 deletions
+95 -95
View File
@@ -57,12 +57,9 @@ struct RunInitEntities
} static g_RunInitEntities; } static g_RunInitEntities;
// skip spaces // skip spaces
static char* tcsskip( const char* psz ) static void tcsskip( const CString &s, unsigned &i )
{ {
while( psz && isspace(*psz) ) i = s.find_first_not_of( " \t\r\n", i );
++psz;
return (char*)psz;
} }
static bool XIsEmptyString( const CString &s ) static bool XIsEmptyString( const CString &s )
@@ -71,21 +68,21 @@ static bool XIsEmptyString( const CString &s )
} }
// put string of (psz~end) on ps string // put string of (psz~end) on ps string
static void SetString( const char* psz, const char* end, CString* ps, bool trim = false ) static void SetString( const CString &s, int iStart, int iEnd, CString* ps, bool trim = false )
{ {
if( trim ) if( trim )
{ {
while( psz < end && isspace(*psz) ) while( iStart < iEnd && isspace(s[iStart]) )
psz++; iStart++;
while( end-1 >= psz && isspace(end[-1]) ) while( iEnd-1 >= iStart && isspace(s[iEnd-1]) )
end--; iEnd--;
} }
int len = end - psz; int len = iEnd - iStart;
if( len <= 0 ) if( len <= 0 )
return; return;
ps->assign( psz, len ); ps->assign( s, iStart, len );
} }
XNode::~XNode() XNode::~XNode()
@@ -109,22 +106,23 @@ void XNode::Clear()
// Desc : loading attribute plain xml text // Desc : loading attribute plain xml text
// Param : pszAttrs - xml of attributes // Param : pszAttrs - xml of attributes
// pi = parser information // pi = parser information
// Return : advanced string pointer. (error return NULL) // Return : advanced string pointer. (error return npos)
const char* XNode::LoadAttributes( const char* xml, PARSEINFO *pi /*= &piDefault*/) unsigned XNode::LoadAttributes( const CString &xml, PARSEINFO *pi, unsigned iOffset )
{ {
while( xml && *xml ) while( iOffset < xml.size() )
{ {
xml = tcsskip( xml ); tcsskip( xml, iOffset );
if( !xml ) if( iOffset >= xml.size() )
continue; continue;
// close tag // close tag
if( *xml == chXMLTagClose || *xml == chXMLTagPre || *xml == chXMLQuestion || *xml == chXMLDash ) if( iOffset < xml.size() &&
return xml; // well-formed tag (xml[iOffset] == chXMLTagClose || xml[iOffset] == chXMLTagPre || xml[iOffset] == chXMLQuestion || xml[iOffset] == chXMLDash) )
return iOffset; // well-formed tag
// XML Attr Name // XML Attr Name
const char* pEnd = strpbrk( xml, " =" ); unsigned iEnd = xml.find_first_of( " =", iOffset );
if( pEnd == NULL ) if( iEnd == xml.npos )
{ {
// error // error
if( !pi->error_occur ) if( !pi->error_occur )
@@ -134,58 +132,59 @@ const char* XNode::LoadAttributes( const char* xml, PARSEINFO *pi /*= &piDefault
pi->error_code = PIE_ATTR_NO_VALUE; pi->error_code = PIE_ATTR_NO_VALUE;
pi->error_string = ssprintf( "<%s> attribute has error ", m_sName.c_str() ); pi->error_string = ssprintf( "<%s> attribute has error ", m_sName.c_str() );
} }
return NULL; return string.npos;
} }
XAttr *attr = new XAttr; XAttr *attr = new XAttr;
// XML Attr Name // XML Attr Name
SetString( xml, pEnd, &attr->m_sName ); SetString( xml, iOffset, iEnd, &attr->m_sName );
// add new attribute // add new attribute
DEBUG_ASSERT( attr->m_sName.size() ); DEBUG_ASSERT( attr->m_sName.size() );
m_attrs.insert( make_pair(attr->m_sName, attr) ); m_attrs.insert( make_pair(attr->m_sName, attr) );
xml = pEnd; iOffset = iEnd;
// XML Attr Value // XML Attr Value
xml = tcsskip( xml ); tcsskip( xml, iOffset );
if( !xml )
if( iOffset < xml.size() && xml[iOffset] == '=' )
{
++iOffset;
tcsskip( xml, iOffset );
if( iOffset >= xml.size() )
continue; continue;
//if( xml = strchr( xml, '=' ) )
if( *xml == '=' )
{
xml = tcsskip( ++xml );
if( !xml )
continue;
// if " or ' // if " or '
// or none quote // or none quote
int quote = *xml; char quote = xml[iOffset];
if( quote == '"' || quote == '\'' ) if( quote == '"' || quote == '\'' )
{ {
pEnd = strchr( ++xml, quote ); ++iOffset;
iEnd = xml.find( quote, iOffset );
} }
else else
{ {
//attr= value> //attr= value>
// none quote mode // none quote mode
pEnd = strpbrk( xml, " >" ); iEnd = xml.find_first_of( " >", iOffset );
} }
bool trim = pi->trim_value; bool trim = pi->trim_value;
SetString( xml, pEnd, &attr->m_sValue, trim ); SetString( xml, iOffset, iEnd, &attr->m_sValue, trim );
xml = pEnd; iOffset = iEnd;
// ATTRVALUE // ATTRVALUE
if( pi->entity_value ) if( pi->entity_value )
ReplaceEntityText( attr->m_sValue, g_mapEntitiesToChars ); ReplaceEntityText( attr->m_sValue, g_mapEntitiesToChars );
if( quote == '"' || quote == '\'' ) if( quote == '"' || quote == '\'' )
xml++; ++iOffset;
} }
} }
// not well-formed tag // not well-formed tag
return NULL; return string::npos;
} }
// <TAG attr1="value1" attr2='value2' attr3=value3 > // <TAG attr1="value1" attr2='value2' attr3=value3 >
@@ -196,28 +195,28 @@ const char* XNode::LoadAttributes( const char* xml, PARSEINFO *pi /*= &piDefault
// Desc : load xml plain text // Desc : load xml plain text
// Param : pszXml - plain xml text // Param : pszXml - plain xml text
// pi = parser information // pi = parser information
// Return : advanced string pointer (error return NULL) // Return : advanced string pointer (error return npos)
const char* XNode::Load( const char* xml, PARSEINFO *pi /*= &piDefault*/ ) unsigned XNode::Load( const CString &xml, PARSEINFO *pi, unsigned iOffset )
{ {
Clear(); Clear();
// < // <
xml = strchr( xml, chXMLTagOpen ); iOffset = xml.find( chXMLTagOpen, iOffset );
if( xml == NULL ) if( iOffset == string.npos )
return NULL; return string.npos;
// </ // </
if( xml[1] == chXMLTagPre ) if( xml[iOffset+1] == chXMLTagPre )
return xml; return iOffset;
/* <!-- */ /* <!-- */
if( !strncmp(xml+1, "!--", 3) ) if( !xml.compare(iOffset+1, 3, "!--") )
{ {
xml += 4; iOffset += 4;
/* Find the close tag. */ /* Find the close tag. */
char *pEnd = strstr( xml, "-->" ); unsigned iEnd = xml.find( "-->" );
if( pEnd == NULL ) if( iEnd == string.npos )
{ {
if( !pi->error_occur ) if( !pi->error_occur )
{ {
@@ -227,38 +226,38 @@ const char* XNode::Load( const char* xml, PARSEINFO *pi /*= &piDefault*/ )
pi->error_string = "Unterminated comment"; pi->error_string = "Unterminated comment";
} }
return NULL; return string.npos;
} }
// Skip -->. // Skip -->.
xml = pEnd + 3; iOffset = iEnd + 3;
return Load( xml, pi ); return Load( xml, pi, iOffset );
} }
// XML Node Tag Name Open // XML Node Tag Name Open
xml++; iOffset++;
const char* pTagEnd = strpbrk( xml, " \t\r\n/>" ); unsigned iTagEnd = xml.find_first_of( " \t\r\n/>", iOffset );
SetString( xml, pTagEnd, &m_sName ); SetString( xml, iOffset, iTagEnd, &m_sName );
iOffset = iTagEnd;
xml = pTagEnd;
// Generate XML Attributte List // Generate XML Attributte List
xml = LoadAttributes( xml, pi ); iOffset = LoadAttributes( xml, pi, iOffset );
if( xml == NULL ) if( iOffset == string.npos )
return NULL; return string.npos;
// alone tag <TAG ... /> or <?TAG ... ?> or <!-- ... --> // alone tag <TAG ... /> or <?TAG ... ?> or <!-- ... -->
// current pointer: ^ ^ ^ // current pointer: ^ ^ ^
if( *xml == chXMLTagPre || *xml == chXMLQuestion || *xml == chXMLDash ) if( iOffset < xml.size() && (xml[iOffset] == chXMLTagPre || xml[iOffset] == chXMLQuestion || xml[iOffset] == chXMLDash) )
{ {
xml++; iOffset++;
// skip over 2nd dash // skip over 2nd dash
if( *xml == chXMLDash ) if( iOffset < xml.size() && xml[iOffset] == chXMLDash )
xml++; iOffset++;
if( *xml != chXMLTagClose ) if( iOffset == xml.size() || xml[iOffset] != chXMLTagClose )
{ {
// error: <TAG ... / > // error: <TAG ... / >
if( !pi->error_occur ) if( !pi->error_occur )
@@ -270,19 +269,19 @@ const char* XNode::Load( const char* xml, PARSEINFO *pi /*= &piDefault*/ )
} }
// ill-formed tag // ill-formed tag
return NULL; return string.npos;
} }
// well-formed tag // well-formed tag
++xml; ++iOffset;
// UGLY: We want to ignore all XML meta tags. So, since the Node we // UGLY: We want to ignore all XML meta tags. So, since the Node we
// just loaded is a meta tag, then Load ourself again using the rest // just loaded is a meta tag, then Load ourself again using the rest
// of the file until we reach a non-meta tag. // of the file until we reach a non-meta tag.
if( !m_sName.empty() && (m_sName[0] == chXMLQuestion || m_sName[0] == chXMLExclamation) ) if( !m_sName.empty() && (m_sName[0] == chXMLQuestion || m_sName[0] == chXMLExclamation) )
xml = Load( xml, pi ); iOffset = Load( xml, pi, iOffset );
return xml; return iOffset;
} }
// open/close tag <TAG ..> ... </TAG> // open/close tag <TAG ..> ... </TAG>
@@ -290,8 +289,9 @@ const char* XNode::Load( const char* xml, PARSEINFO *pi /*= &piDefault*/ )
if( XIsEmptyString( m_sValue ) ) if( XIsEmptyString( m_sValue ) )
{ {
// Text Value // Text Value
const char* pEnd = strchr( ++xml, chXMLTagOpen ); ++iOffset;
if( pEnd == NULL ) unsigned iEnd = xml.find( chXMLTagOpen, iOffset );
if( iEnd == string.npos )
{ {
if( !pi->error_occur ) if( !pi->error_occur )
{ {
@@ -301,24 +301,24 @@ const char* XNode::Load( const char* xml, PARSEINFO *pi /*= &piDefault*/ )
pi->error_string = ssprintf( "%s must be closed with </%s>", m_sName.c_str(), m_sName.c_str() ); pi->error_string = ssprintf( "%s must be closed with </%s>", m_sName.c_str(), m_sName.c_str() );
} }
// error cos not exist CloseTag </TAG> // error cos not exist CloseTag </TAG>
return NULL; return string.npos;
} }
bool trim = pi->trim_value; bool trim = pi->trim_value;
SetString( xml, pEnd, &m_sValue, trim ); SetString( xml, iOffset, iEnd, &m_sValue, trim );
xml = pEnd; iOffset = iEnd;
// TEXTVALUE reference // TEXTVALUE reference
if( pi->entity_value ) if( pi->entity_value )
ReplaceEntityText( m_sValue, g_mapEntitiesToChars ); ReplaceEntityText( m_sValue, g_mapEntitiesToChars );
} }
// generate child nodes // generate child nodes
while( xml && *xml ) while( iOffset < xml.size() )
{ {
XNode *node = new XNode; XNode *node = new XNode;
xml = node->Load( xml,pi ); iOffset = node->Load( xml, pi, iOffset );
if( !node->m_sName.empty() ) if( !node->m_sName.empty() )
{ {
DEBUG_ASSERT( node->m_sName.size() ); DEBUG_ASSERT( node->m_sName.size() );
@@ -332,17 +332,17 @@ const char* XNode::Load( const char* xml, PARSEINFO *pi /*= &piDefault*/ )
// open/close tag <TAG ..> ... </TAG> // open/close tag <TAG ..> ... </TAG>
// ^- current pointer // ^- current pointer
// CloseTag case // CloseTag case
if( xml && xml[0] == chXMLTagOpen && xml[1] == chXMLTagPre ) if( iOffset+1 < xml.size() && xml[iOffset] == chXMLTagOpen && xml[iOffset+1] == chXMLTagPre )
{ {
// </Close> // </Close>
xml+=2; // C iOffset += 2; // C
xml = tcsskip( xml ); tcsskip( xml, iOffset );
if( xml == NULL ) if( iOffset >= xml.size() )
return NULL; continue;
const char* pEnd = strpbrk( xml, " >" ); unsigned iEnd = xml.find_first_of( " >", iOffset );
if( pEnd == NULL ) if( iEnd == string.npos )
{ {
if( !pi->error_occur ) if( !pi->error_occur )
{ {
@@ -352,17 +352,17 @@ const char* XNode::Load( const char* xml, PARSEINFO *pi /*= &piDefault*/ )
pi->error_string = ssprintf( "it must be closed with </%s>", m_sName.c_str() ); pi->error_string = ssprintf( "it must be closed with </%s>", m_sName.c_str() );
} }
// error // error
return NULL; return string.npos;
} }
CString closename; CString closename;
SetString( xml, pEnd, &closename ); SetString( xml, iOffset, iEnd, &closename );
xml = pEnd+1; iOffset = iEnd+1;
if( closename == this->m_sName ) if( closename == this->m_sName )
{ {
// wel-formed open/close // wel-formed open/close
// return '>' or ' ' after pointer // return '>' or ' ' after pointer
return xml; return iOffset;
} }
else else
{ {
@@ -374,16 +374,16 @@ const char* XNode::Load( const char* xml, PARSEINFO *pi /*= &piDefault*/ )
pi->error_code = PIE_NOT_NESTED; pi->error_code = PIE_NOT_NESTED;
pi->error_string = ssprintf( "'<%s> ... </%s>' is not well-formed.", m_sName.c_str(), closename.c_str() ); pi->error_string = ssprintf( "'<%s> ... </%s>' is not well-formed.", m_sName.c_str(), closename.c_str() );
} }
return NULL; return string.npos;
} }
} }
else // Alone child Tag Loaded else // Alone child Tag Loaded
{ {
if( xml && XIsEmptyString( m_sValue ) && *xml !=chXMLTagOpen ) if( XIsEmptyString( m_sValue ) && iOffset < xml.size() && xml[iOffset] != chXMLTagOpen )
{ {
// Text Value // Text Value
const char* pEnd = strchr( xml, chXMLTagOpen ); unsigned iEnd = xml.find( chXMLTagOpen, iOffset );
if( pEnd == NULL ) if( iEnd == string.npos )
{ {
// error cos not exist CloseTag </TAG> // error cos not exist CloseTag </TAG>
if( !pi->error_occur ) if( !pi->error_occur )
@@ -393,13 +393,13 @@ const char* XNode::Load( const char* xml, PARSEINFO *pi /*= &piDefault*/ )
pi->error_code = PIE_NOT_CLOSED; pi->error_code = PIE_NOT_CLOSED;
pi->error_string = ssprintf( "it must be closed with </%s>", m_sName.c_str() ); pi->error_string = ssprintf( "it must be closed with </%s>", m_sName.c_str() );
} }
return NULL; return string.npos;
} }
bool trim = pi->trim_value; bool trim = pi->trim_value;
SetString( xml, pEnd, &m_sValue, trim ); SetString( xml, iOffset, iEnd, &m_sValue, trim );
xml = pEnd; iOffset = iEnd;
//TEXTVALUE //TEXTVALUE
if( pi->entity_value ) if( pi->entity_value )
ReplaceEntityText( m_sValue, g_mapEntitiesToChars ); ReplaceEntityText( m_sValue, g_mapEntitiesToChars );
@@ -407,7 +407,7 @@ const char* XNode::Load( const char* xml, PARSEINFO *pi /*= &piDefault*/ )
} }
} }
return xml; return iOffset;
} }
// Desc : convert plain xml text from parsed xml attirbute // Desc : convert plain xml text from parsed xml attirbute
+2 -2
View File
@@ -137,8 +137,8 @@ struct XNode
void SetValue( const DateTime &v ); void SetValue( const DateTime &v );
// Load/Save XML // Load/Save XML
const char *Load( const char* pszXml, PARSEINFO *pi ); unsigned Load( const CString &sXml, PARSEINFO *pi, unsigned iOffset = 0 );
const char *LoadAttributes( const char* pszAttrs, PARSEINFO *pi ); unsigned LoadAttributes( const CString &sAttrs, PARSEINFO *pi, unsigned iOffset );
bool GetXML( RageFileBasic &f, DISP_OPT *opt ) const; bool GetXML( RageFileBasic &f, DISP_OPT *opt ) const;
CString GetXML() const; CString GetXML() const;