mirror of
https://github.com/AxioDL/tinyxml2.git
synced 2025-12-09 05:27:44 +00:00
Compare commits
51 Commits
2.0.2
...
mikemayer6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3cdfa6349 | ||
|
|
282285a069 | ||
|
|
f2496f5824 | ||
|
|
853de8169b | ||
|
|
869f1487e2 | ||
|
|
6d202ff20e | ||
|
|
72bb0ecc39 | ||
|
|
9de541f465 | ||
|
|
b0776aeead | ||
|
|
5ee1c6ef77 | ||
|
|
9fb2b0f42c | ||
|
|
5321a0e21f | ||
|
|
c755667aa0 | ||
|
|
331596e83c | ||
|
|
cd8550c29c | ||
|
|
9f52ad5289 | ||
|
|
003368429f | ||
|
|
8f5d3f8e80 | ||
|
|
bb5ffac22d | ||
|
|
fb732f97d4 | ||
|
|
3659fe1d33 | ||
|
|
cf6d886903 | ||
|
|
e3225b1c64 | ||
|
|
30152836da | ||
|
|
83a6d8c373 | ||
|
|
d526944e3c | ||
|
|
b6b4e82626 | ||
|
|
59b9aaea43 | ||
|
|
ec19a0e513 | ||
|
|
b6ea923f0f | ||
|
|
63f3de1a3c | ||
|
|
dc50a31758 | ||
|
|
67a5bb0ac1 | ||
|
|
0b26702ac9 | ||
|
|
01578db56b | ||
|
|
2af5679b26 | ||
|
|
5657176b61 | ||
|
|
73c822c201 | ||
|
|
acb9c9c260 | ||
|
|
fca00d0ebc | ||
|
|
08e7f7be59 | ||
|
|
84bd9624c6 | ||
|
|
91d34a0989 | ||
|
|
cf33e37d25 | ||
|
|
d740b64044 | ||
|
|
500fb6aa21 | ||
|
|
ca5d684a2b | ||
|
|
6ee53e7d49 | ||
|
|
256adb6371 | ||
|
|
98112fcdba | ||
|
|
433f1272d4 |
@@ -10,8 +10,8 @@ include(GNUInstallDirs)
|
||||
################################
|
||||
# set lib version here
|
||||
|
||||
set(GENERIC_LIB_VERSION "2.0.2")
|
||||
set(GENERIC_LIB_SOVERSION "2")
|
||||
set(GENERIC_LIB_VERSION "2.2.0")
|
||||
set(GENERIC_LIB_SOVERSION "2")
|
||||
|
||||
|
||||
################################
|
||||
|
||||
@@ -269,6 +269,14 @@ an XCode project, a Code::Blocks project, and a cmake CMakeLists.txt included to
|
||||
The top of tinyxml.h even has a simple g++ command line if you are are *nix and don't want
|
||||
to use a build system.
|
||||
|
||||
Versioning
|
||||
----------
|
||||
|
||||
TinyXML-2 uses semantic versioning. http://semver.org/ Releases are now tagged in github.
|
||||
|
||||
Note that the major version will (probably) change fairly rapidly. API changes are fairly
|
||||
common.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
|
||||
67
resources/dictionary.xml
Normal file
67
resources/dictionary.xml
Normal file
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE Dictionary [
|
||||
<!-- Test of the ability to parse internally defined DTD -->
|
||||
<!-- Test for comment nastiness: <]> -->
|
||||
<!ELEMENT Dictionary (Storage+) >
|
||||
<!ELEMENT Storage (WordFile+, WordList?) >
|
||||
<!ELEMENT Growth EMPTY >
|
||||
<!ELEMENT WordFile (Growth?) >
|
||||
<!ELEMENT WordList (Initialization?) >
|
||||
<!ELEMENT Initialization EMPTY >
|
||||
|
||||
<!ATTLIST Storage name CDATA #REQUIRED
|
||||
life (permanent|temporary) "permanent"
|
||||
tested (true|false) "true">
|
||||
|
||||
<!ATTLIST WordFile name CDATA #REQUIRED
|
||||
size CDATA "500M"
|
||||
recyled (true|false) "true"
|
||||
tracking (on|off) "off">
|
||||
|
||||
<!ATTLIST Growth next CDATA "500M"
|
||||
max CDATA "unlimited">
|
||||
|
||||
<!ATTLIST WordList method (local|dictionary) "local">
|
||||
|
||||
<!ATTLIST Initialization method (dynamic|static) "dynamic"
|
||||
size CDATA "1M" >
|
||||
|
||||
]>
|
||||
|
||||
<Dictionary>
|
||||
|
||||
<Storage name="APP_DATA" life="permanent" tested="true">
|
||||
<WordFile name="/data15/local/task_list01.dict" size="250M" recyled="true" tracking="off">
|
||||
</WordFile>
|
||||
<WordFile name="/data15/local/task_list02.dict" size="250M" recyled="true" tracking="on">
|
||||
<Growth next="500M" max="unlimited"/>
|
||||
</WordFile>
|
||||
<WordList method="local">
|
||||
<Initialization method="dynamic"/>
|
||||
</WordList>
|
||||
</Storage>
|
||||
|
||||
|
||||
<Storage name="APP_INDEX" life="permanent" tested="true">
|
||||
<WordFile name="/data20/local/site_list01.dict" size="250M" recyled="true" tracking="off">
|
||||
</WordFile>
|
||||
<WordFile name="/data20/local/site_list02.dict" size="250M" recyled="true" tracking="on">
|
||||
<Growth next="500M" max="unlimited"/>
|
||||
</WordFile>
|
||||
<WordList method="local">
|
||||
<Initialization method="dynamic"/>
|
||||
</WordList>
|
||||
</Storage>
|
||||
|
||||
|
||||
<Storage name="APP_TEMP" life="temporary" tested="false">
|
||||
<WordFile name="/data23/local/user_words01.dict" size="500M" recyled="true" tracking="on">
|
||||
<Growth next="500M" max="unlimited"/>
|
||||
</WordFile>
|
||||
<WordList method="local">
|
||||
<Initialization method="static" size="1M"/>
|
||||
</WordList>
|
||||
</Storage>
|
||||
|
||||
</Dictionary>
|
||||
@@ -116,4 +116,8 @@ print( "Release note:" )
|
||||
print( '1. Build. g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe' )
|
||||
print( '2. Commit. git commit -am"setting the version to ' + versionStr + '"' )
|
||||
print( '3. Tag. git tag ' + versionStr )
|
||||
print( ' OR git tag -a ' + versionStr + ' -m <tag message>' )
|
||||
print( ' OR git tag -a ' + versionStr + ' -m [tag message]' )
|
||||
print( 'Remember to "git push" both code and tag. For the tag:' )
|
||||
print( 'git push origin [tagname]')
|
||||
|
||||
|
||||
330
tinyxml2.cpp
330
tinyxml2.cpp
@@ -45,22 +45,6 @@ static const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
|
||||
static const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
|
||||
static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
|
||||
|
||||
|
||||
#define DELETE_NODE( node ) { \
|
||||
if ( node ) { \
|
||||
MemPool* pool = node->_memPool; \
|
||||
node->~XMLNode(); \
|
||||
pool->Free( node ); \
|
||||
} \
|
||||
}
|
||||
#define DELETE_ATTRIBUTE( attrib ) { \
|
||||
if ( attrib ) { \
|
||||
MemPool* pool = attrib->_memPool; \
|
||||
attrib->~XMLAttribute(); \
|
||||
pool->Free( attrib ); \
|
||||
} \
|
||||
}
|
||||
|
||||
namespace tinyxml2
|
||||
{
|
||||
|
||||
@@ -112,7 +96,7 @@ char* StrPair::ParseText( char* p, const char* endTag, int strFlags )
|
||||
{
|
||||
TIXMLASSERT( endTag && *endTag );
|
||||
|
||||
char* start = p; // fixme: hides a member
|
||||
char* start = p;
|
||||
char endChar = *endTag;
|
||||
size_t length = strlen( endTag );
|
||||
|
||||
@@ -130,12 +114,12 @@ char* StrPair::ParseText( char* p, const char* endTag, int strFlags )
|
||||
|
||||
char* StrPair::ParseName( char* p )
|
||||
{
|
||||
char* start = p;
|
||||
|
||||
if ( !start || !(*start) ) {
|
||||
if ( !p || !(*p) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* const start = p;
|
||||
|
||||
while( *p && ( p == start ? XMLUtil::IsNameStartChar( *p ) : XMLUtil::IsNameChar( *p ) )) {
|
||||
++p;
|
||||
}
|
||||
@@ -150,6 +134,8 @@ char* StrPair::ParseName( char* p )
|
||||
|
||||
void StrPair::CollapseWhitespace()
|
||||
{
|
||||
// Adjusting _start would cause undefined behavior on delete[]
|
||||
TIXMLASSERT( ( _flags & NEEDS_DELETE ) == 0 );
|
||||
// Trim leading space.
|
||||
_start = XMLUtil::SkipWhiteSpace( _start );
|
||||
|
||||
@@ -214,13 +200,14 @@ const char* StrPair::GetStr()
|
||||
// 中 or 中
|
||||
|
||||
if ( *(p+1) == '#' ) {
|
||||
char buf[10] = { 0 };
|
||||
int len;
|
||||
const int buflen = 10;
|
||||
char buf[buflen] = { 0 };
|
||||
int len = 0;
|
||||
p = const_cast<char*>( XMLUtil::GetCharacterRef( p, buf, &len ) );
|
||||
for( int i=0; i<len; ++i ) {
|
||||
*q++ = buf[i];
|
||||
}
|
||||
TIXMLASSERT( q <= p );
|
||||
TIXMLASSERT( 0 <= len && len <= buflen );
|
||||
TIXMLASSERT( q + len <= p );
|
||||
memcpy( q, buf, len );
|
||||
q += len;
|
||||
}
|
||||
else {
|
||||
int i=0;
|
||||
@@ -492,8 +479,7 @@ bool XMLUtil::ToDouble( const char* str, double* value )
|
||||
|
||||
char* XMLDocument::Identify( char* p, XMLNode** node )
|
||||
{
|
||||
XMLNode* returnNode = 0;
|
||||
char* start = p;
|
||||
char* const start = p;
|
||||
p = XMLUtil::SkipWhiteSpace( p );
|
||||
if( !p || !*p ) {
|
||||
return p;
|
||||
@@ -517,11 +503,13 @@ char* XMLDocument::Identify( char* p, XMLNode** node )
|
||||
#pragma warning ( push )
|
||||
#pragma warning ( disable : 4127 )
|
||||
#endif
|
||||
TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLUnknown ) ); // use same memory pool
|
||||
TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDtd ) ); // use same memory pool
|
||||
TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLUnknown ) ); // use same memory pool
|
||||
TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDeclaration ) ); // use same memory pool
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
XMLNode* returnNode = 0;
|
||||
if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) {
|
||||
returnNode = new (_commentPool.Alloc()) XMLDeclaration( this );
|
||||
returnNode->_memPool = &_commentPool;
|
||||
@@ -540,7 +528,7 @@ char* XMLDocument::Identify( char* p, XMLNode** node )
|
||||
text->SetCData( true );
|
||||
}
|
||||
else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) {
|
||||
returnNode = new (_commentPool.Alloc()) XMLUnknown( this );
|
||||
returnNode = new (_commentPool.Alloc()) XMLDtd( this );
|
||||
returnNode->_memPool = &_commentPool;
|
||||
p += dtdHeaderLen;
|
||||
}
|
||||
@@ -615,7 +603,7 @@ void XMLNode::DeleteChildren()
|
||||
XMLNode* node = _firstChild;
|
||||
Unlink( node );
|
||||
|
||||
DELETE_NODE( node );
|
||||
DeleteNode( node );
|
||||
}
|
||||
_firstChild = _lastChild = 0;
|
||||
}
|
||||
@@ -643,7 +631,7 @@ void XMLNode::Unlink( XMLNode* child )
|
||||
void XMLNode::DeleteChild( XMLNode* node )
|
||||
{
|
||||
TIXMLASSERT( node->_parent == this );
|
||||
DELETE_NODE( node );
|
||||
DeleteNode( node );
|
||||
}
|
||||
|
||||
|
||||
@@ -706,7 +694,7 @@ XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis )
|
||||
addThis->_next = 0;
|
||||
}
|
||||
addThis->_parent = this;
|
||||
return addThis;
|
||||
return addThis;
|
||||
}
|
||||
|
||||
|
||||
@@ -770,10 +758,11 @@ const XMLElement* XMLNode::LastChildElement( const char* value ) const
|
||||
|
||||
const XMLElement* XMLNode::NextSiblingElement( const char* value ) const
|
||||
{
|
||||
for( XMLNode* element=this->_next; element; element = element->_next ) {
|
||||
if ( element->ToElement()
|
||||
&& (!value || XMLUtil::StringEqual( value, element->Value() ))) {
|
||||
return element->ToElement();
|
||||
for( XMLNode* node=this->_next; node; node = node->_next ) {
|
||||
const XMLElement* element = node->ToElement();
|
||||
if ( element
|
||||
&& (!value || XMLUtil::StringEqual( value, node->Value() ))) {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -782,10 +771,11 @@ const XMLElement* XMLNode::NextSiblingElement( const char* value ) const
|
||||
|
||||
const XMLElement* XMLNode::PreviousSiblingElement( const char* value ) const
|
||||
{
|
||||
for( XMLNode* element=_prev; element; element = element->_prev ) {
|
||||
if ( element->ToElement()
|
||||
&& (!value || XMLUtil::StringEqual( value, element->Value() ))) {
|
||||
return element->ToElement();
|
||||
for( XMLNode* node=_prev; node; node = node->_prev ) {
|
||||
const XMLElement* element = node->ToElement();
|
||||
if ( element
|
||||
&& (!value || XMLUtil::StringEqual( value, node->Value() ))) {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -822,7 +812,7 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEnd )
|
||||
StrPair endTag;
|
||||
p = node->ParseDeep( p, &endTag );
|
||||
if ( !p ) {
|
||||
DELETE_NODE( node );
|
||||
DeleteNode( node );
|
||||
node = 0;
|
||||
if ( !_document->Error() ) {
|
||||
_document->SetError( XML_ERROR_PARSING, 0, 0 );
|
||||
@@ -830,37 +820,39 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEnd )
|
||||
break;
|
||||
}
|
||||
|
||||
XMLElement* ele = node->ToElement();
|
||||
// We read the end tag. Return it to the parent.
|
||||
if ( node->ToElement() && node->ToElement()->ClosingType() == XMLElement::CLOSING ) {
|
||||
if ( ele && ele->ClosingType() == XMLElement::CLOSING ) {
|
||||
if ( parentEnd ) {
|
||||
*parentEnd = static_cast<XMLElement*>(node)->_value;
|
||||
*parentEnd = ele->_value;
|
||||
}
|
||||
node->_memPool->SetTracked(); // created and then immediately deleted.
|
||||
DELETE_NODE( node );
|
||||
DeleteNode( node );
|
||||
return p;
|
||||
}
|
||||
|
||||
// Handle an end tag returned to this level.
|
||||
// And handle a bunch of annoying errors.
|
||||
XMLElement* ele = node->ToElement();
|
||||
if ( ele ) {
|
||||
bool mismatch = false;
|
||||
if ( endTag.Empty() && ele->ClosingType() == XMLElement::OPEN ) {
|
||||
_document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 );
|
||||
p = 0;
|
||||
mismatch = true;
|
||||
}
|
||||
else if ( !endTag.Empty() && ele->ClosingType() != XMLElement::OPEN ) {
|
||||
_document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 );
|
||||
p = 0;
|
||||
mismatch = true;
|
||||
}
|
||||
else if ( !endTag.Empty() ) {
|
||||
if ( !XMLUtil::StringEqual( endTag.GetStr(), node->Value() )) {
|
||||
_document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 );
|
||||
p = 0;
|
||||
mismatch = true;
|
||||
}
|
||||
}
|
||||
if ( mismatch ) {
|
||||
_document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 );
|
||||
p = 0;
|
||||
}
|
||||
}
|
||||
if ( p == 0 ) {
|
||||
DELETE_NODE( node );
|
||||
DeleteNode( node );
|
||||
node = 0;
|
||||
}
|
||||
if ( node ) {
|
||||
@@ -870,6 +862,16 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEnd )
|
||||
return 0;
|
||||
}
|
||||
|
||||
void XMLNode::DeleteNode( XMLNode* node )
|
||||
{
|
||||
if ( node == 0 ) {
|
||||
return;
|
||||
}
|
||||
MemPool* pool = node->_memPool;
|
||||
node->~XMLNode();
|
||||
pool->Free( node );
|
||||
}
|
||||
|
||||
// --------- XMLText ---------- //
|
||||
char* XMLText::ParseDeep( char* p, StrPair* )
|
||||
{
|
||||
@@ -912,7 +914,8 @@ XMLNode* XMLText::ShallowClone( XMLDocument* doc ) const
|
||||
|
||||
bool XMLText::ShallowEqual( const XMLNode* compare ) const
|
||||
{
|
||||
return ( compare->ToText() && XMLUtil::StringEqual( compare->ToText()->Value(), Value() ));
|
||||
const XMLText* text = compare->ToText();
|
||||
return ( text && XMLUtil::StringEqual( text->Value(), Value() ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -958,7 +961,8 @@ XMLNode* XMLComment::ShallowClone( XMLDocument* doc ) const
|
||||
|
||||
bool XMLComment::ShallowEqual( const XMLNode* compare ) const
|
||||
{
|
||||
return ( compare->ToComment() && XMLUtil::StringEqual( compare->ToComment()->Value(), Value() ));
|
||||
const XMLComment* comment = compare->ToComment();
|
||||
return ( comment && XMLUtil::StringEqual( comment->Value(), Value() ));
|
||||
}
|
||||
|
||||
|
||||
@@ -1005,7 +1009,8 @@ XMLNode* XMLDeclaration::ShallowClone( XMLDocument* doc ) const
|
||||
|
||||
bool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const
|
||||
{
|
||||
return ( compare->ToDeclaration() && XMLUtil::StringEqual( compare->ToDeclaration()->Value(), Value() ));
|
||||
const XMLDeclaration* declaration = compare->ToDeclaration();
|
||||
return ( declaration && XMLUtil::StringEqual( declaration->Value(), Value() ));
|
||||
}
|
||||
|
||||
|
||||
@@ -1015,6 +1020,87 @@ bool XMLDeclaration::Accept( XMLVisitor* visitor ) const
|
||||
return visitor->Visit( *this );
|
||||
}
|
||||
|
||||
// --------- XMLDtd ---------- //
|
||||
|
||||
XMLDtd::XMLDtd( XMLDocument* doc ) : XMLNode( doc )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
XMLDtd::~XMLDtd()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
char* XMLDtd::ParseDeep( char* p, StrPair* )
|
||||
{
|
||||
// Dtd parses as text.
|
||||
char* start = p;
|
||||
bool endFound = false;
|
||||
int brackets = 0; // trackes whether we are inside in inline DTD
|
||||
|
||||
while(*p) {
|
||||
// Skip over comments.
|
||||
if (strncmp(p, "<!--", 4) == 0) {
|
||||
p = strstr(p+4, "-->");
|
||||
if (p) {
|
||||
p += 3;
|
||||
}
|
||||
}
|
||||
if (!p) break;
|
||||
|
||||
// Skip over defs
|
||||
if (brackets && strncmp(p, "<!", 2) == 0 ) {
|
||||
p = strstr(p+2, ">");
|
||||
if (p) {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
if (!p) break;
|
||||
|
||||
if (brackets == 0 && *p == '>' ) {
|
||||
endFound = true;
|
||||
break;
|
||||
}
|
||||
if (*p == '[' )
|
||||
++brackets;
|
||||
if (*p == ']' )
|
||||
--brackets;
|
||||
++p;
|
||||
}
|
||||
|
||||
if (!endFound || !p || !*p) {
|
||||
_document->SetError( XML_ERROR_PARSING_DTD, start, 0 );
|
||||
}
|
||||
|
||||
_value.Set(start, p, StrPair::NEEDS_NEWLINE_NORMALIZATION );
|
||||
|
||||
return p+1;
|
||||
}
|
||||
|
||||
|
||||
XMLNode* XMLDtd::ShallowClone( XMLDocument* doc ) const
|
||||
{
|
||||
if ( !doc ) {
|
||||
doc = _document;
|
||||
}
|
||||
XMLDtd* text = doc->NewDtd( Value() ); // fixme: this will always allocate memory. Intern?
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
bool XMLDtd::ShallowEqual( const XMLNode* compare ) const
|
||||
{
|
||||
const XMLDtd* dtd = compare->ToDtd();
|
||||
return ( dtd && XMLUtil::StringEqual( dtd->Value(), Value() ));
|
||||
}
|
||||
|
||||
|
||||
bool XMLDtd::Accept( XMLVisitor* visitor ) const
|
||||
{
|
||||
return visitor->Visit( *this );
|
||||
}
|
||||
|
||||
// --------- XMLUnknown ---------- //
|
||||
|
||||
XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc )
|
||||
@@ -1052,7 +1138,8 @@ XMLNode* XMLUnknown::ShallowClone( XMLDocument* doc ) const
|
||||
|
||||
bool XMLUnknown::ShallowEqual( const XMLNode* compare ) const
|
||||
{
|
||||
return ( compare->ToUnknown() && XMLUtil::StringEqual( compare->ToUnknown()->Value(), Value() ));
|
||||
const XMLUnknown* unknown = compare->ToUnknown();
|
||||
return ( unknown && XMLUtil::StringEqual( unknown->Value(), Value() ));
|
||||
}
|
||||
|
||||
|
||||
@@ -1208,7 +1295,7 @@ XMLElement::~XMLElement()
|
||||
{
|
||||
while( _rootAttribute ) {
|
||||
XMLAttribute* next = _rootAttribute->_next;
|
||||
DELETE_ATTRIBUTE( _rootAttribute );
|
||||
DeleteAttribute( _rootAttribute );
|
||||
_rootAttribute = next;
|
||||
}
|
||||
}
|
||||
@@ -1216,8 +1303,7 @@ XMLElement::~XMLElement()
|
||||
|
||||
XMLAttribute* XMLElement::FindAttribute( const char* name )
|
||||
{
|
||||
XMLAttribute* a = 0;
|
||||
for( a=_rootAttribute; a; a = a->_next ) {
|
||||
for( XMLAttribute* a = _rootAttribute; a; a = a->_next ) {
|
||||
if ( XMLUtil::StringEqual( a->Name(), name ) ) {
|
||||
return a;
|
||||
}
|
||||
@@ -1228,8 +1314,7 @@ XMLAttribute* XMLElement::FindAttribute( const char* name )
|
||||
|
||||
const XMLAttribute* XMLElement::FindAttribute( const char* name ) const
|
||||
{
|
||||
XMLAttribute* a = 0;
|
||||
for( a=_rootAttribute; a; a = a->_next ) {
|
||||
for( XMLAttribute* a = _rootAttribute; a; a = a->_next ) {
|
||||
if ( XMLUtil::StringEqual( a->Name(), name ) ) {
|
||||
return a;
|
||||
}
|
||||
@@ -1415,7 +1500,7 @@ void XMLElement::DeleteAttribute( const char* name )
|
||||
else {
|
||||
_rootAttribute = a->_next;
|
||||
}
|
||||
DELETE_ATTRIBUTE( a );
|
||||
DeleteAttribute( a );
|
||||
break;
|
||||
}
|
||||
prev = a;
|
||||
@@ -1444,7 +1529,7 @@ char* XMLElement::ParseAttributes( char* p )
|
||||
|
||||
p = attrib->ParseDeep( p, _document->ProcessEntities() );
|
||||
if ( !p || Attribute( attrib->Name() ) ) {
|
||||
DELETE_ATTRIBUTE( attrib );
|
||||
DeleteAttribute( attrib );
|
||||
_document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p );
|
||||
return 0;
|
||||
}
|
||||
@@ -1479,6 +1564,15 @@ char* XMLElement::ParseAttributes( char* p )
|
||||
return p;
|
||||
}
|
||||
|
||||
void XMLElement::DeleteAttribute( XMLAttribute* attribute )
|
||||
{
|
||||
if ( attribute == 0 ) {
|
||||
return;
|
||||
}
|
||||
MemPool* pool = attribute->_memPool;
|
||||
attribute->~XMLAttribute();
|
||||
pool->Free( attribute );
|
||||
}
|
||||
|
||||
//
|
||||
// <ele></ele>
|
||||
@@ -1568,6 +1662,33 @@ bool XMLElement::Accept( XMLVisitor* visitor ) const
|
||||
|
||||
|
||||
// --------- XMLDocument ----------- //
|
||||
|
||||
// Warning: List must match 'enum XMLError'
|
||||
const char* XMLDocument::_errorNames[XML_ERROR_COUNT] = {
|
||||
"XML_SUCCESS",
|
||||
"XML_NO_ATTRIBUTE",
|
||||
"XML_WRONG_ATTRIBUTE_TYPE",
|
||||
"XML_ERROR_FILE_NOT_FOUND",
|
||||
"XML_ERROR_FILE_COULD_NOT_BE_OPENED",
|
||||
"XML_ERROR_FILE_READ_ERROR",
|
||||
"XML_ERROR_ELEMENT_MISMATCH",
|
||||
"XML_ERROR_PARSING_ELEMENT",
|
||||
"XML_ERROR_PARSING_ATTRIBUTE",
|
||||
"XML_ERROR_IDENTIFYING_TAG",
|
||||
"XML_ERROR_PARSING_TEXT",
|
||||
"XML_ERROR_PARSING_CDATA",
|
||||
"XML_ERROR_PARSING_COMMENT",
|
||||
"XML_ERROR_PARSING_DECLARATION",
|
||||
"XML_ERROR_PARSING_UNKNOWN",
|
||||
"XML_ERROR_PARSING_DTD",
|
||||
"XML_ERROR_EMPTY_DOCUMENT",
|
||||
"XML_ERROR_MISMATCHED_ELEMENT",
|
||||
"XML_ERROR_PARSING",
|
||||
"XML_CAN_NOT_CONVERT_TEXT",
|
||||
"XML_NO_TEXT_NODE"
|
||||
};
|
||||
|
||||
|
||||
XMLDocument::XMLDocument( bool processEntities, Whitespace whitespace ) :
|
||||
XMLNode( 0 ),
|
||||
_writeBOM( false ),
|
||||
@@ -1654,6 +1775,14 @@ XMLDeclaration* XMLDocument::NewDeclaration( const char* str )
|
||||
}
|
||||
|
||||
|
||||
XMLDtd* XMLDocument::NewDtd( const char* str )
|
||||
{
|
||||
XMLDtd* dtd = new (_commentPool.Alloc()) XMLDtd( this );
|
||||
dtd->_memPool = &_commentPool;
|
||||
dtd->SetValue( str );
|
||||
return dtd;
|
||||
}
|
||||
|
||||
XMLUnknown* XMLDocument::NewUnknown( const char* str )
|
||||
{
|
||||
XMLUnknown* unk = new (_commentPool.Alloc()) XMLUnknown( this );
|
||||
@@ -1662,19 +1791,25 @@ XMLUnknown* XMLDocument::NewUnknown( const char* str )
|
||||
return unk;
|
||||
}
|
||||
|
||||
static FILE* callfopen( const char* filepath, const char* mode )
|
||||
{
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)
|
||||
FILE* fp = 0;
|
||||
errno_t err = fopen_s( &fp, filepath, mode );
|
||||
if ( err ) {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
FILE* fp = fopen( filepath, mode );
|
||||
#endif
|
||||
return fp;
|
||||
}
|
||||
|
||||
XMLError XMLDocument::LoadFile( const char* filename )
|
||||
{
|
||||
Clear();
|
||||
FILE* fp = 0;
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
|
||||
errno_t err = fopen_s(&fp, filename, "rb" );
|
||||
if ( !fp || err) {
|
||||
#else
|
||||
fp = fopen( filename, "rb" );
|
||||
if ( !fp) {
|
||||
#endif
|
||||
FILE* fp = callfopen( filename, "rb" );
|
||||
if ( !fp ) {
|
||||
SetError( XML_ERROR_FILE_NOT_FOUND, filename, 0 );
|
||||
return _errorID;
|
||||
}
|
||||
@@ -1689,16 +1824,20 @@ XMLError XMLDocument::LoadFile( FILE* fp )
|
||||
Clear();
|
||||
|
||||
fseek( fp, 0, SEEK_SET );
|
||||
fgetc( fp );
|
||||
if ( ferror( fp ) != 0 ) {
|
||||
if ( fgetc( fp ) == EOF && ferror( fp ) != 0 ) {
|
||||
SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 );
|
||||
return _errorID;
|
||||
}
|
||||
|
||||
fseek( fp, 0, SEEK_END );
|
||||
size_t size = ftell( fp );
|
||||
const long filelength = ftell( fp );
|
||||
fseek( fp, 0, SEEK_SET );
|
||||
if ( filelength == -1L ) {
|
||||
SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 );
|
||||
return _errorID;
|
||||
}
|
||||
|
||||
const size_t size = filelength;
|
||||
if ( size == 0 ) {
|
||||
SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 );
|
||||
return _errorID;
|
||||
@@ -1728,14 +1867,8 @@ XMLError XMLDocument::LoadFile( FILE* fp )
|
||||
|
||||
XMLError XMLDocument::SaveFile( const char* filename, bool compact )
|
||||
{
|
||||
FILE* fp = 0;
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
|
||||
errno_t err = fopen_s(&fp, filename, "w" );
|
||||
if ( !fp || err) {
|
||||
#else
|
||||
fp = fopen( filename, "w" );
|
||||
if ( !fp) {
|
||||
#endif
|
||||
FILE* fp = callfopen( filename, "w" );
|
||||
if ( !fp ) {
|
||||
SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, filename, 0 );
|
||||
return _errorID;
|
||||
}
|
||||
@@ -1799,6 +1932,11 @@ void XMLDocument::SetError( XMLError error, const char* str1, const char* str2 )
|
||||
_errorStr2 = str2;
|
||||
}
|
||||
|
||||
const char* XMLDocument::ErrorName() const
|
||||
{
|
||||
TIXMLASSERT(_errorID >= 0 && _errorID < XML_ERROR_COUNT );
|
||||
return _errorNames[_errorID];
|
||||
}
|
||||
|
||||
void XMLDocument::PrintError() const
|
||||
{
|
||||
@@ -1814,8 +1952,8 @@ void XMLDocument::PrintError() const
|
||||
TIXML_SNPRINTF( buf2, LEN, "%s", _errorStr2 );
|
||||
}
|
||||
|
||||
printf( "XMLDocument error id=%d str1=%s str2=%s\n",
|
||||
_errorID, buf1, buf2 );
|
||||
printf( "XMLDocument error id=%d '%s' str1=%s str2=%s\n",
|
||||
_errorID, ErrorName(), buf1, buf2 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1856,7 +1994,17 @@ void XMLPrinter::Print( const char* format, ... )
|
||||
}
|
||||
else {
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
|
||||
#if defined(WINCE)
|
||||
int len = 512;
|
||||
do {
|
||||
len = len*2;
|
||||
char* str = new char[len]();
|
||||
len = _vsnprintf(str, len, format, va);
|
||||
delete[] str;
|
||||
}while (len < 0);
|
||||
#else
|
||||
int len = _vscprintf( format, va );
|
||||
#endif
|
||||
#else
|
||||
int len = vsnprintf( 0, 0, format, va );
|
||||
#endif
|
||||
@@ -1865,7 +2013,11 @@ void XMLPrinter::Print( const char* format, ... )
|
||||
va_start( va, format );
|
||||
char* p = _buffer.PushArr( len ) - 1; // back up over the null terminator.
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
|
||||
#if defined(WINCE)
|
||||
_vsnprintf( p, len+1, format, va );
|
||||
#else
|
||||
vsnprintf_s( p, len+1, _TRUNCATE, format, va );
|
||||
#endif
|
||||
#else
|
||||
vsnprintf( p, len+1, format, va );
|
||||
#endif
|
||||
@@ -2176,6 +2328,12 @@ bool XMLPrinter::Visit( const XMLDeclaration& declaration )
|
||||
}
|
||||
|
||||
|
||||
bool XMLPrinter::Visit( const XMLDtd& dtd )
|
||||
{
|
||||
PushUnknown( dtd.Value() );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool XMLPrinter::Visit( const XMLUnknown& unknown )
|
||||
{
|
||||
PushUnknown( unknown.Value() );
|
||||
|
||||
173
tinyxml2.h
173
tinyxml2.h
@@ -91,7 +91,7 @@ distribution.
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)
|
||||
// Microsoft visual studio, version 2005 and higher.
|
||||
/*int _snprintf_s(
|
||||
char *buffer,
|
||||
@@ -109,6 +109,9 @@ inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... )
|
||||
return result;
|
||||
}
|
||||
#define TIXML_SSCANF sscanf_s
|
||||
#elif defined WINCE
|
||||
#define TIXML_SNPRINTF _snprintf
|
||||
#define TIXML_SSCANF sscanf
|
||||
#else
|
||||
// GCC version 3 and higher
|
||||
//#warning( "Using sn* functions." )
|
||||
@@ -119,9 +122,9 @@ inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... )
|
||||
/* Versioning, past 1.0.14:
|
||||
http://semver.org/
|
||||
*/
|
||||
static const int TIXML2_MAJOR_VERSION = 2;
|
||||
static const int TIXML2_MINOR_VERSION = 0;
|
||||
static const int TIXML2_PATCH_VERSION = 2;
|
||||
static const int TIXML2_MAJOR_VERSION = 2;
|
||||
static const int TIXML2_MINOR_VERSION = 2;
|
||||
static const int TIXML2_PATCH_VERSION = 0;
|
||||
|
||||
namespace tinyxml2
|
||||
{
|
||||
@@ -132,6 +135,7 @@ class XMLComment;
|
||||
class XMLText;
|
||||
class XMLDeclaration;
|
||||
class XMLUnknown;
|
||||
class XMLDtd;
|
||||
class XMLPrinter;
|
||||
|
||||
/*
|
||||
@@ -367,7 +371,7 @@ public:
|
||||
return;
|
||||
}
|
||||
--_currentAllocs;
|
||||
Chunk* chunk = (Chunk*)mem;
|
||||
Chunk* chunk = static_cast<Chunk*>( mem );
|
||||
#ifdef DEBUG
|
||||
memset( chunk, 0xfe, sizeof(Chunk) );
|
||||
#endif
|
||||
@@ -471,12 +475,44 @@ public:
|
||||
virtual bool Visit( const XMLComment& /*comment*/ ) {
|
||||
return true;
|
||||
}
|
||||
/// Visit a DTD node.
|
||||
virtual bool Visit( const XMLDtd& /*unknown*/ ) {
|
||||
return true;
|
||||
}
|
||||
/// Visit an unknown node.
|
||||
virtual bool Visit( const XMLUnknown& /*unknown*/ ) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// WARNING: must match XMLDocument::_errorNames[]
|
||||
enum XMLError {
|
||||
XML_SUCCESS = 0,
|
||||
XML_NO_ERROR = 0,
|
||||
XML_NO_ATTRIBUTE,
|
||||
XML_WRONG_ATTRIBUTE_TYPE,
|
||||
XML_ERROR_FILE_NOT_FOUND,
|
||||
XML_ERROR_FILE_COULD_NOT_BE_OPENED,
|
||||
XML_ERROR_FILE_READ_ERROR,
|
||||
XML_ERROR_ELEMENT_MISMATCH,
|
||||
XML_ERROR_PARSING_ELEMENT,
|
||||
XML_ERROR_PARSING_ATTRIBUTE,
|
||||
XML_ERROR_IDENTIFYING_TAG,
|
||||
XML_ERROR_PARSING_TEXT,
|
||||
XML_ERROR_PARSING_CDATA,
|
||||
XML_ERROR_PARSING_COMMENT,
|
||||
XML_ERROR_PARSING_DECLARATION,
|
||||
XML_ERROR_PARSING_UNKNOWN,
|
||||
XML_ERROR_PARSING_DTD,
|
||||
XML_ERROR_EMPTY_DOCUMENT,
|
||||
XML_ERROR_MISMATCHED_ELEMENT,
|
||||
XML_ERROR_PARSING,
|
||||
XML_CAN_NOT_CONVERT_TEXT,
|
||||
XML_NO_TEXT_NODE,
|
||||
|
||||
XML_ERROR_COUNT
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Utility functionality.
|
||||
@@ -493,10 +529,7 @@ public:
|
||||
return p;
|
||||
}
|
||||
static char* SkipWhiteSpace( char* p ) {
|
||||
while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast<unsigned char*>(p) ) ) {
|
||||
++p;
|
||||
}
|
||||
return p;
|
||||
return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p) ) );
|
||||
}
|
||||
static bool IsWhiteSpace( char p ) {
|
||||
return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
|
||||
@@ -531,8 +564,8 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
inline static int IsUTF8Continuation( const char p ) {
|
||||
return p & 0x80;
|
||||
inline static bool IsUTF8Continuation( const char p ) {
|
||||
return ( p & 0x80 ) != 0;
|
||||
}
|
||||
|
||||
static const char* ReadBOM( const char* p, bool* hasBOM );
|
||||
@@ -617,6 +650,11 @@ public:
|
||||
virtual XMLDeclaration* ToDeclaration() {
|
||||
return 0;
|
||||
}
|
||||
/// Safely cast to an DTD, or null.
|
||||
virtual XMLDtd* ToDtd() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Safely cast to an Unknown, or null.
|
||||
virtual XMLUnknown* ToUnknown() {
|
||||
return 0;
|
||||
@@ -637,6 +675,10 @@ public:
|
||||
virtual const XMLDeclaration* ToDeclaration() const {
|
||||
return 0;
|
||||
}
|
||||
virtual const XMLDtd* ToDtd() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual const XMLUnknown* ToUnknown() const {
|
||||
return 0;
|
||||
}
|
||||
@@ -844,6 +886,7 @@ protected:
|
||||
private:
|
||||
MemPool* _memPool;
|
||||
void Unlink( XMLNode* child );
|
||||
static void DeleteNode( XMLNode* node );
|
||||
};
|
||||
|
||||
|
||||
@@ -961,12 +1004,44 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** The <!DOCTYPE> structure can contain internal definition that
|
||||
may contains other <!xxx ...> entities. (Otherwise, these could
|
||||
be handled as XMLUnknown nodes.)
|
||||
|
||||
TinyXML-2 does not interpret, enforce, or even parse the DTD.
|
||||
|
||||
The XMLDTD tag will be written back to the XML, unchanged,
|
||||
when the file is saved.
|
||||
*/
|
||||
|
||||
class TINYXML2_LIB XMLDtd : public XMLNode
|
||||
{
|
||||
friend class XMLDocument;
|
||||
public:
|
||||
virtual XMLDtd* ToDtd() {
|
||||
return this;
|
||||
}
|
||||
virtual const XMLDtd* ToDtd() const {
|
||||
return this;
|
||||
}
|
||||
|
||||
virtual bool Accept( XMLVisitor* visitor ) const;
|
||||
|
||||
char* ParseDeep( char*, StrPair* endTag );
|
||||
virtual XMLNode* ShallowClone( XMLDocument* document ) const;
|
||||
virtual bool ShallowEqual( const XMLNode* compare ) const;
|
||||
|
||||
protected:
|
||||
XMLDtd( XMLDocument* doc );
|
||||
virtual ~XMLDtd();
|
||||
XMLDtd( const XMLDtd& ); // not supported
|
||||
XMLDtd& operator=( const XMLDtd& ); // not supported
|
||||
};
|
||||
|
||||
/** Any tag that TinyXML-2 doesn't recognize is saved as an
|
||||
unknown. It is a tag of text, but should not be modified.
|
||||
It will be written back to the XML, unchanged, when the file
|
||||
is saved.
|
||||
|
||||
DTD tags get thrown into XMLUnknowns.
|
||||
*/
|
||||
class TINYXML2_LIB XMLUnknown : public XMLNode
|
||||
{
|
||||
@@ -993,33 +1068,6 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
enum XMLError {
|
||||
XML_NO_ERROR = 0,
|
||||
XML_SUCCESS = 0,
|
||||
|
||||
XML_NO_ATTRIBUTE,
|
||||
XML_WRONG_ATTRIBUTE_TYPE,
|
||||
|
||||
XML_ERROR_FILE_NOT_FOUND,
|
||||
XML_ERROR_FILE_COULD_NOT_BE_OPENED,
|
||||
XML_ERROR_FILE_READ_ERROR,
|
||||
XML_ERROR_ELEMENT_MISMATCH,
|
||||
XML_ERROR_PARSING_ELEMENT,
|
||||
XML_ERROR_PARSING_ATTRIBUTE,
|
||||
XML_ERROR_IDENTIFYING_TAG,
|
||||
XML_ERROR_PARSING_TEXT,
|
||||
XML_ERROR_PARSING_CDATA,
|
||||
XML_ERROR_PARSING_COMMENT,
|
||||
XML_ERROR_PARSING_DECLARATION,
|
||||
XML_ERROR_PARSING_UNKNOWN,
|
||||
XML_ERROR_EMPTY_DOCUMENT,
|
||||
XML_ERROR_MISMATCHED_ELEMENT,
|
||||
XML_ERROR_PARSING,
|
||||
|
||||
XML_CAN_NOT_CONVERT_TEXT,
|
||||
XML_NO_TEXT_NODE
|
||||
};
|
||||
|
||||
|
||||
/** An attribute is a name-value pair. Elements have an arbitrary
|
||||
number of attributes, each with a unique name.
|
||||
@@ -1477,6 +1525,7 @@ private:
|
||||
XMLAttribute* FindOrCreateAttribute( const char* name );
|
||||
//void LinkAttribute( XMLAttribute* attrib );
|
||||
char* ParseAttributes( char* p );
|
||||
static void DeleteAttribute( XMLAttribute* attribute );
|
||||
|
||||
enum { BUF_SIZE = 200 };
|
||||
int _closingType;
|
||||
@@ -1633,6 +1682,13 @@ public:
|
||||
@endverbatim
|
||||
*/
|
||||
XMLDeclaration* NewDeclaration( const char* text=0 );
|
||||
/**
|
||||
Create a new DTD associated with
|
||||
this Document. The memory for the object
|
||||
is managed by the Document.
|
||||
*/
|
||||
XMLDtd* NewDtd( const char* text );
|
||||
|
||||
/**
|
||||
Create a new Unknown associated with
|
||||
this Document. The memory for the object
|
||||
@@ -1658,6 +1714,8 @@ public:
|
||||
XMLError ErrorID() const {
|
||||
return _errorID;
|
||||
}
|
||||
const char* ErrorName() const;
|
||||
|
||||
/// Return a possibly helpful diagnostic location or string.
|
||||
const char* GetErrorStr1() const {
|
||||
return _errorStr1;
|
||||
@@ -1698,6 +1756,8 @@ private:
|
||||
MemPoolT< sizeof(XMLAttribute) > _attributePool;
|
||||
MemPoolT< sizeof(XMLText) > _textPool;
|
||||
MemPoolT< sizeof(XMLComment) > _commentPool;
|
||||
|
||||
static const char* _errorNames[XML_ERROR_COUNT];
|
||||
};
|
||||
|
||||
|
||||
@@ -1816,19 +1876,23 @@ public:
|
||||
}
|
||||
/// Safe cast to XMLElement. This can return null.
|
||||
XMLElement* ToElement() {
|
||||
return ( ( _node && _node->ToElement() ) ? _node->ToElement() : 0 );
|
||||
return ( ( _node == 0 ) ? 0 : _node->ToElement() );
|
||||
}
|
||||
/// Safe cast to XMLText. This can return null.
|
||||
XMLText* ToText() {
|
||||
return ( ( _node && _node->ToText() ) ? _node->ToText() : 0 );
|
||||
return ( ( _node == 0 ) ? 0 : _node->ToText() );
|
||||
}
|
||||
/// Safe cast to XMLDtd. This can return null.
|
||||
XMLDtd* ToDtd() {
|
||||
return ( ( _node == 0 ) ? 0 : _node->ToDtd() );
|
||||
}
|
||||
/// Safe cast to XMLUnknown. This can return null.
|
||||
XMLUnknown* ToUnknown() {
|
||||
return ( ( _node && _node->ToUnknown() ) ? _node->ToUnknown() : 0 );
|
||||
return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
|
||||
}
|
||||
/// Safe cast to XMLDeclaration. This can return null.
|
||||
XMLDeclaration* ToDeclaration() {
|
||||
return ( ( _node && _node->ToDeclaration() ) ? _node->ToDeclaration() : 0 );
|
||||
return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -1888,16 +1952,19 @@ public:
|
||||
return _node;
|
||||
}
|
||||
const XMLElement* ToElement() const {
|
||||
return ( ( _node && _node->ToElement() ) ? _node->ToElement() : 0 );
|
||||
return ( ( _node == 0 ) ? 0 : _node->ToElement() );
|
||||
}
|
||||
const XMLText* ToText() const {
|
||||
return ( ( _node && _node->ToText() ) ? _node->ToText() : 0 );
|
||||
return ( ( _node == 0 ) ? 0 : _node->ToText() );
|
||||
}
|
||||
const XMLDtd* ToDtd() const {
|
||||
return ( ( _node == 0 ) ? 0 : _node->ToDtd() );
|
||||
}
|
||||
const XMLUnknown* ToUnknown() const {
|
||||
return ( ( _node && _node->ToUnknown() ) ? _node->ToUnknown() : 0 );
|
||||
return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
|
||||
}
|
||||
const XMLDeclaration* ToDeclaration() const {
|
||||
return ( ( _node && _node->ToDeclaration() ) ? _node->ToDeclaration() : 0 );
|
||||
return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -1964,7 +2031,7 @@ public:
|
||||
/** If streaming, start writing an element.
|
||||
The element must be closed with CloseElement()
|
||||
*/
|
||||
void OpenElement( const char* name, bool compactMode );
|
||||
void OpenElement( const char* name, bool compactMode=false );
|
||||
/// If streaming, add an attribute to an open element.
|
||||
void PushAttribute( const char* name, const char* value );
|
||||
void PushAttribute( const char* name, int value );
|
||||
@@ -1972,7 +2039,7 @@ public:
|
||||
void PushAttribute( const char* name, bool value );
|
||||
void PushAttribute( const char* name, double value );
|
||||
/// If streaming, close the Element.
|
||||
virtual void CloseElement( bool compactMode );
|
||||
virtual void CloseElement( bool compactMode=false );
|
||||
|
||||
/// Add a text node.
|
||||
void PushText( const char* text, bool cdata=false );
|
||||
@@ -2004,6 +2071,7 @@ public:
|
||||
virtual bool Visit( const XMLText& text );
|
||||
virtual bool Visit( const XMLComment& comment );
|
||||
virtual bool Visit( const XMLDeclaration& declaration );
|
||||
virtual bool Visit( const XMLDtd& dtd);
|
||||
virtual bool Visit( const XMLUnknown& unknown );
|
||||
|
||||
/**
|
||||
@@ -2031,7 +2099,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual bool CompactMode( const XMLElement& ) { return _compactMode; };
|
||||
virtual bool CompactMode( const XMLElement& ) { return _compactMode; }
|
||||
|
||||
/** Prints out the space before an element. You may override to change
|
||||
the space and tabs used. A PrintSpace() override should call Print().
|
||||
@@ -2061,9 +2129,6 @@ private:
|
||||
bool _restrictedEntityFlag[ENTITY_RANGE];
|
||||
|
||||
DynArray< char, 20 > _buffer;
|
||||
#ifdef _MSC_VER
|
||||
DynArray< char, 20 > _accumulator;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
46
xmltest.cpp
46
xmltest.cpp
@@ -1,5 +1,7 @@
|
||||
#if defined( _MSC_VER )
|
||||
#define _CRT_SECURE_NO_WARNINGS // This test file is not intended to be secure.
|
||||
#if !defined( _CRT_SECURE_NO_WARNINGS )
|
||||
#define _CRT_SECURE_NO_WARNINGS // This test file is not intended to be secure.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "tinyxml2.h"
|
||||
@@ -88,10 +90,11 @@ void NullLineEndings( char* p )
|
||||
}
|
||||
|
||||
|
||||
int example_1()
|
||||
int example_1(const char *xml_file)
|
||||
{
|
||||
XMLDocument doc;
|
||||
doc.LoadFile( "resources/dream.xml" );
|
||||
|
||||
doc.LoadFile( xml_file );
|
||||
|
||||
return doc.ErrorID();
|
||||
}
|
||||
@@ -322,7 +325,8 @@ int main( int argc, const char ** argv )
|
||||
}
|
||||
fclose( fp );
|
||||
|
||||
XMLTest( "Example-1", 0, example_1() );
|
||||
XMLTest( "Example-1", 0, example_1("resources/dream.xml") );
|
||||
XMLTest( "Example-1", 0, example_1("resources/dictionary.xml") );
|
||||
XMLTest( "Example-2", 0, example_2() );
|
||||
XMLTest( "Example-3", 0, example_3() );
|
||||
XMLTest( "Example-4", true, example_4() );
|
||||
@@ -453,9 +457,9 @@ int main( int argc, const char ** argv )
|
||||
|
||||
XMLTest( "Dream", "xml version=\"1.0\"",
|
||||
doc.FirstChild()->ToDeclaration()->Value() );
|
||||
XMLTest( "Dream", true, doc.FirstChild()->NextSibling()->ToUnknown() ? true : false );
|
||||
XMLTest( "Dream", true, doc.FirstChild()->NextSibling()->ToDtd() ? true : false );
|
||||
XMLTest( "Dream", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
|
||||
doc.FirstChild()->NextSibling()->ToUnknown()->Value() );
|
||||
doc.FirstChild()->NextSibling()->ToDtd()->Value() );
|
||||
XMLTest( "Dream", "And Robin shall restore amends.",
|
||||
doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
|
||||
XMLTest( "Dream", "And Robin shall restore amends.",
|
||||
@@ -465,14 +469,36 @@ int main( int argc, const char ** argv )
|
||||
doc2.LoadFile( "resources/out/dreamout.xml" );
|
||||
XMLTest( "Dream-out", "xml version=\"1.0\"",
|
||||
doc2.FirstChild()->ToDeclaration()->Value() );
|
||||
XMLTest( "Dream-out", true, doc2.FirstChild()->NextSibling()->ToUnknown() ? true : false );
|
||||
XMLTest( "Dream-out", true, doc2.FirstChild()->NextSibling()->ToDtd() ? true : false );
|
||||
XMLTest( "Dream-out", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
|
||||
doc2.FirstChild()->NextSibling()->ToUnknown()->Value() );
|
||||
doc2.FirstChild()->NextSibling()->ToDtd()->Value() );
|
||||
XMLTest( "Dream-out", "And Robin shall restore amends.",
|
||||
doc2.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
|
||||
|
||||
//gNewTotal = gNew - newStart;
|
||||
}
|
||||
{
|
||||
// Test: Dictionary
|
||||
XMLDocument doc;
|
||||
doc.LoadFile( "resources/dictionary.xml" );
|
||||
|
||||
doc.SaveFile( "resources/out/dictionaryout.xml" );
|
||||
doc.PrintError();
|
||||
|
||||
XMLTest( "Dictionary", "xml version=\"1.0\" encoding=\"UTF-8\"",
|
||||
doc.FirstChild()->ToDeclaration()->Value() );
|
||||
XMLTest( "Dictionary", true, doc.FirstChild()->NextSibling()->ToDtd() ? true : false );
|
||||
XMLTest( "Dictionary", "500M",
|
||||
doc.LastChild()->LastChild()->FirstChild()->ToElement()->Attribute("size") );
|
||||
|
||||
XMLDocument doc2;
|
||||
doc2.LoadFile( "resources/out/dictionaryout.xml" );
|
||||
XMLTest( "Dictionary-out", "xml version=\"1.0\" encoding=\"UTF-8\"",
|
||||
doc2.FirstChild()->ToDeclaration()->Value() );
|
||||
XMLTest( "Dictionary-out", true, doc2.FirstChild()->NextSibling()->ToDtd() ? true : false );
|
||||
XMLTest( "Dictionary", "500M",
|
||||
doc2.LastChild()->LastChild()->FirstChild()->ToElement()->Attribute("size") );
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
@@ -820,7 +846,7 @@ int main( int argc, const char ** argv )
|
||||
doc.LoadFile( "resources/out/test7.xml" );
|
||||
doc.Print();
|
||||
|
||||
const XMLUnknown* decl = doc.FirstChild()->NextSibling()->ToUnknown();
|
||||
const XMLDtd* decl = doc.FirstChild()->NextSibling()->ToDtd();
|
||||
XMLTest( "Correct value of unknown.", "DOCTYPE PLAY SYSTEM 'play.dtd'", decl->Value() );
|
||||
|
||||
}
|
||||
@@ -1220,6 +1246,8 @@ int main( int argc, const char ** argv )
|
||||
XMLDocument doc;
|
||||
XMLError error = doc.LoadFile( "resources/empty.xml" );
|
||||
XMLTest( "Loading an empty file", XML_ERROR_EMPTY_DOCUMENT, error );
|
||||
XMLTest( "Loading an empty file and ErrorName as string", "XML_ERROR_EMPTY_DOCUMENT", doc.ErrorName() );
|
||||
doc.PrintError();
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user