Merge branch 'master' of https://github.com/mikemayer67/tinyxml2 into mikemayer67-master

This commit is contained in:
Lee Thomason 2014-09-27 16:03:15 -07:00
commit 282285a069
4 changed files with 234 additions and 12 deletions

66
resources/dictionary.xml Normal file
View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Dictionary [
<!-- Test of the ability to parse internally defined DTD -->
<!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>

View File

@ -503,7 +503,8 @@ char* XMLDocument::Identify( char* p, XMLNode** node )
#pragma warning ( push ) #pragma warning ( push )
#pragma warning ( disable : 4127 ) #pragma warning ( disable : 4127 )
#endif #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 TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDeclaration ) ); // use same memory pool
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning (pop) #pragma warning (pop)
@ -527,7 +528,7 @@ char* XMLDocument::Identify( char* p, XMLNode** node )
text->SetCData( true ); text->SetCData( true );
} }
else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) { else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) {
returnNode = new (_commentPool.Alloc()) XMLUnknown( this ); returnNode = new (_commentPool.Alloc()) XMLDtd( this );
returnNode->_memPool = &_commentPool; returnNode->_memPool = &_commentPool;
p += dtdHeaderLen; p += dtdHeaderLen;
} }
@ -1019,6 +1020,65 @@ bool XMLDeclaration::Accept( XMLVisitor* visitor ) const
return visitor->Visit( *this ); 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;
// Find closing '>', skipping over any local definition contained between '[' and ']'
while( *p && *p != '>' && *p != '[') ++p;
if ( *p == '[' )
{
while( *p && *p != ']' ) ++p;
while( *p && *p != '>' ) ++p;
}
if ( *p != '>' ) {
_document->SetError( XML_ERROR_PARSING_UNKNOWN, 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* unknown = compare->ToDtd();
return ( unknown && XMLUtil::StringEqual( unknown->Value(), Value() ));
}
bool XMLDtd::Accept( XMLVisitor* visitor ) const
{
return visitor->Visit( *this );
}
// --------- XMLUnknown ---------- // // --------- XMLUnknown ---------- //
XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc ) XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc )
@ -1692,6 +1752,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* XMLDocument::NewUnknown( const char* str )
{ {
XMLUnknown* unk = new (_commentPool.Alloc()) XMLUnknown( this ); XMLUnknown* unk = new (_commentPool.Alloc()) XMLUnknown( this );
@ -2237,6 +2305,12 @@ bool XMLPrinter::Visit( const XMLDeclaration& declaration )
} }
bool XMLPrinter::Visit( const XMLDtd& dtd )
{
PushUnknown( dtd.Value() );
return true;
}
bool XMLPrinter::Visit( const XMLUnknown& unknown ) bool XMLPrinter::Visit( const XMLUnknown& unknown )
{ {
PushUnknown( unknown.Value() ); PushUnknown( unknown.Value() );

View File

@ -135,6 +135,7 @@ class XMLComment;
class XMLText; class XMLText;
class XMLDeclaration; class XMLDeclaration;
class XMLUnknown; class XMLUnknown;
class XMLDtd;
class XMLPrinter; class XMLPrinter;
/* /*
@ -474,6 +475,10 @@ public:
virtual bool Visit( const XMLComment& /*comment*/ ) { virtual bool Visit( const XMLComment& /*comment*/ ) {
return true; return true;
} }
/// Visit a DTD node.
virtual bool Visit( const XMLDtd& /*unknown*/ ) {
return true;
}
/// Visit an unknown node. /// Visit an unknown node.
virtual bool Visit( const XMLUnknown& /*unknown*/ ) { virtual bool Visit( const XMLUnknown& /*unknown*/ ) {
return true; return true;
@ -644,6 +649,11 @@ public:
virtual XMLDeclaration* ToDeclaration() { virtual XMLDeclaration* ToDeclaration() {
return 0; return 0;
} }
/// Safely cast to an DTD, or null.
virtual XMLDtd* ToDtd() {
return 0;
}
/// Safely cast to an Unknown, or null. /// Safely cast to an Unknown, or null.
virtual XMLUnknown* ToUnknown() { virtual XMLUnknown* ToUnknown() {
return 0; return 0;
@ -664,6 +674,10 @@ public:
virtual const XMLDeclaration* ToDeclaration() const { virtual const XMLDeclaration* ToDeclaration() const {
return 0; return 0;
} }
virtual const XMLDtd* ToDtd() const {
return 0;
}
virtual const XMLUnknown* ToUnknown() const { virtual const XMLUnknown* ToUnknown() const {
return 0; return 0;
} }
@ -989,12 +1003,41 @@ protected:
}; };
/** The <!DOCTYPE> structure can contain internal definition that
may contains other <!xxx ...> entities. (Otherwise, these could
be handled as XMLUnknown nodes.)
It 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 /** Any tag that TinyXML-2 doesn't recognize is saved as an
unknown. It is a tag of text, but should not be modified. unknown. It is a tag of text, but should not be modified.
It will be written back to the XML, unchanged, when the file It will be written back to the XML, unchanged, when the file
is saved. is saved.
DTD tags get thrown into XMLUnknowns.
*/ */
class TINYXML2_LIB XMLUnknown : public XMLNode class TINYXML2_LIB XMLUnknown : public XMLNode
{ {
@ -1635,6 +1678,13 @@ public:
@endverbatim @endverbatim
*/ */
XMLDeclaration* NewDeclaration( const char* text=0 ); 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 Create a new Unknown associated with
this Document. The memory for the object this Document. The memory for the object
@ -1828,6 +1878,10 @@ public:
XMLText* ToText() { XMLText* ToText() {
return ( ( _node == 0 ) ? 0 : _node->ToText() ); 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. /// Safe cast to XMLUnknown. This can return null.
XMLUnknown* ToUnknown() { XMLUnknown* ToUnknown() {
return ( ( _node == 0 ) ? 0 : _node->ToUnknown() ); return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
@ -1899,6 +1953,9 @@ public:
const XMLText* ToText() const { const XMLText* ToText() const {
return ( ( _node == 0 ) ? 0 : _node->ToText() ); return ( ( _node == 0 ) ? 0 : _node->ToText() );
} }
const XMLDtd* ToDtd() const {
return ( ( _node == 0 ) ? 0 : _node->ToDtd() );
}
const XMLUnknown* ToUnknown() const { const XMLUnknown* ToUnknown() const {
return ( ( _node == 0 ) ? 0 : _node->ToUnknown() ); return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
} }
@ -2010,6 +2067,7 @@ public:
virtual bool Visit( const XMLText& text ); virtual bool Visit( const XMLText& text );
virtual bool Visit( const XMLComment& comment ); virtual bool Visit( const XMLComment& comment );
virtual bool Visit( const XMLDeclaration& declaration ); virtual bool Visit( const XMLDeclaration& declaration );
virtual bool Visit( const XMLDtd& dtd);
virtual bool Visit( const XMLUnknown& unknown ); virtual bool Visit( const XMLUnknown& unknown );
/** /**

View File

@ -90,10 +90,11 @@ void NullLineEndings( char* p )
} }
int example_1() int example_1(const char *xml_file)
{ {
XMLDocument doc; XMLDocument doc;
doc.LoadFile( "resources/dream.xml" );
doc.LoadFile( xml_file );
return doc.ErrorID(); return doc.ErrorID();
} }
@ -324,7 +325,8 @@ int main( int argc, const char ** argv )
} }
fclose( fp ); 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-2", 0, example_2() );
XMLTest( "Example-3", 0, example_3() ); XMLTest( "Example-3", 0, example_3() );
XMLTest( "Example-4", true, example_4() ); XMLTest( "Example-4", true, example_4() );
@ -455,9 +457,9 @@ int main( int argc, const char ** argv )
XMLTest( "Dream", "xml version=\"1.0\"", XMLTest( "Dream", "xml version=\"1.0\"",
doc.FirstChild()->ToDeclaration()->Value() ); 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\"", XMLTest( "Dream", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
doc.FirstChild()->NextSibling()->ToUnknown()->Value() ); doc.FirstChild()->NextSibling()->ToDtd()->Value() );
XMLTest( "Dream", "And Robin shall restore amends.", XMLTest( "Dream", "And Robin shall restore amends.",
doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() ); doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
XMLTest( "Dream", "And Robin shall restore amends.", XMLTest( "Dream", "And Robin shall restore amends.",
@ -467,14 +469,36 @@ int main( int argc, const char ** argv )
doc2.LoadFile( "resources/out/dreamout.xml" ); doc2.LoadFile( "resources/out/dreamout.xml" );
XMLTest( "Dream-out", "xml version=\"1.0\"", XMLTest( "Dream-out", "xml version=\"1.0\"",
doc2.FirstChild()->ToDeclaration()->Value() ); 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\"", 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.", XMLTest( "Dream-out", "And Robin shall restore amends.",
doc2.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() ); doc2.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
//gNewTotal = gNew - newStart; //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") );
}
{ {
@ -822,7 +846,7 @@ int main( int argc, const char ** argv )
doc.LoadFile( "resources/out/test7.xml" ); doc.LoadFile( "resources/out/test7.xml" );
doc.Print(); 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() ); XMLTest( "Correct value of unknown.", "DOCTYPE PLAY SYSTEM 'play.dtd'", decl->Value() );
} }