mirror of https://github.com/AxioDL/tinyxml2.git
Dream test passing.
This commit is contained in:
parent
ae25a44d94
commit
bd0a8ac60c
203
tinyxml2.cpp
203
tinyxml2.cpp
|
@ -82,7 +82,7 @@ char* StrPair::ParseText( char* p, const char* endTag, int strFlags )
|
||||||
}
|
}
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
return p;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,17 +198,17 @@ char* XMLDocument::Identify( char* p, XMLNode** node )
|
||||||
// What is this thing?
|
// What is this thing?
|
||||||
// - Elements start with a letter or underscore, but xml is reserved.
|
// - Elements start with a letter or underscore, but xml is reserved.
|
||||||
// - Comments: <!--
|
// - Comments: <!--
|
||||||
// - Decleration: <?xml
|
// - Decleration: <?
|
||||||
// - Everthing else is unknown to tinyxml.
|
// - Everthing else is unknown to tinyxml.
|
||||||
//
|
//
|
||||||
|
|
||||||
static const char* xmlHeader = { "<?xml" };
|
static const char* xmlHeader = { "<?" };
|
||||||
static const char* commentHeader = { "<!--" };
|
static const char* commentHeader = { "<!--" };
|
||||||
static const char* dtdHeader = { "<!" };
|
static const char* dtdHeader = { "<!" };
|
||||||
static const char* cdataHeader = { "<![CDATA[" };
|
static const char* cdataHeader = { "<![CDATA[" };
|
||||||
static const char* elementHeader = { "<" }; // and a header for everything else; check last.
|
static const char* elementHeader = { "<" }; // and a header for everything else; check last.
|
||||||
|
|
||||||
static const int xmlHeaderLen = 5;
|
static const int xmlHeaderLen = 2;
|
||||||
static const int commentHeaderLen = 4;
|
static const int commentHeaderLen = 4;
|
||||||
static const int dtdHeaderLen = 2;
|
static const int dtdHeaderLen = 2;
|
||||||
static const int cdataHeaderLen = 9;
|
static const int cdataHeaderLen = 9;
|
||||||
|
@ -244,16 +244,11 @@ char* XMLDocument::Identify( char* p, XMLNode** node )
|
||||||
returnNode->memPool = &elementPool;
|
returnNode->memPool = &elementPool;
|
||||||
p += elementHeaderLen;
|
p += elementHeaderLen;
|
||||||
}
|
}
|
||||||
else if ( (*p != '<') && XMLUtil::IsAlphaNum( *p ) ) {
|
else {
|
||||||
returnNode = new (textPool.Alloc()) XMLText( this );
|
returnNode = new (textPool.Alloc()) XMLText( this );
|
||||||
returnNode->memPool = &textPool;
|
returnNode->memPool = &textPool;
|
||||||
p = start; // Back it up, all the text counts.
|
p = start; // Back it up, all the text counts.
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
this->SetError( ERROR_IDENTIFYING_TAG, p, 0 );
|
|
||||||
p = 0;
|
|
||||||
returnNode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
*node = returnNode;
|
*node = returnNode;
|
||||||
return p;
|
return p;
|
||||||
|
@ -457,13 +452,19 @@ char* XMLNode::ParseDeep( char* p )
|
||||||
// --------- XMLText ---------- //
|
// --------- XMLText ---------- //
|
||||||
char* XMLText::ParseDeep( char* p )
|
char* XMLText::ParseDeep( char* p )
|
||||||
{
|
{
|
||||||
|
const char* start = p;
|
||||||
if ( this->CData() ) {
|
if ( this->CData() ) {
|
||||||
p = value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION );
|
p = value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION );
|
||||||
|
if ( !p ) {
|
||||||
|
document->SetError( XMLDocument::ERROR_PARSING_CDATA, start, 0 );
|
||||||
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p = value.ParseText( p, "<", StrPair::TEXT_ELEMENT );
|
p = value.ParseText( p, "<", StrPair::TEXT_ELEMENT );
|
||||||
// consumes the end tag.
|
if ( !p ) {
|
||||||
|
document->SetError( XMLDocument::ERROR_PARSING_TEXT, start, 0 );
|
||||||
|
}
|
||||||
if ( p && *p ) {
|
if ( p && *p ) {
|
||||||
return p-1;
|
return p-1;
|
||||||
}
|
}
|
||||||
|
@ -494,7 +495,12 @@ XMLComment::~XMLComment()
|
||||||
char* XMLComment::ParseDeep( char* p )
|
char* XMLComment::ParseDeep( char* p )
|
||||||
{
|
{
|
||||||
// Comment parses as text.
|
// Comment parses as text.
|
||||||
return value.ParseText( p, "-->", StrPair::COMMENT );
|
const char* start = p;
|
||||||
|
p = value.ParseText( p, "-->", StrPair::COMMENT );
|
||||||
|
if ( p == 0 ) {
|
||||||
|
document->SetError( XMLDocument::ERROR_PARSING_COMMENT, start, 0 );
|
||||||
|
}
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -520,7 +526,12 @@ XMLDeclaration::~XMLDeclaration()
|
||||||
char* XMLDeclaration::ParseDeep( char* p )
|
char* XMLDeclaration::ParseDeep( char* p )
|
||||||
{
|
{
|
||||||
// Declaration parses as text.
|
// Declaration parses as text.
|
||||||
return value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION );
|
const char* start = p;
|
||||||
|
p = value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION );
|
||||||
|
if ( p == 0 ) {
|
||||||
|
document->SetError( XMLDocument::ERROR_PARSING_DECLARATION, start, 0 );
|
||||||
|
}
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -544,7 +555,13 @@ XMLUnknown::~XMLUnknown()
|
||||||
char* XMLUnknown::ParseDeep( char* p )
|
char* XMLUnknown::ParseDeep( char* p )
|
||||||
{
|
{
|
||||||
// Unknown parses as text.
|
// Unknown parses as text.
|
||||||
return value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION );
|
const char* start = p;
|
||||||
|
|
||||||
|
p = value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION );
|
||||||
|
if ( !p ) {
|
||||||
|
document->SetError( XMLDocument::ERROR_PARSING_UNKNOWN, start, 0 );
|
||||||
|
}
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -707,6 +724,16 @@ const XMLAttribute* XMLElement::FindAttribute( const char* name ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char* XMLElement::GetText() const
|
||||||
|
{
|
||||||
|
if ( FirstChild() && FirstChild()->ToText() ) {
|
||||||
|
return FirstChild()->ToText()->Value();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name )
|
XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name )
|
||||||
{
|
{
|
||||||
XMLAttribute* attrib = FindAttribute( name );
|
XMLAttribute* attrib = FindAttribute( name );
|
||||||
|
@ -916,6 +943,48 @@ XMLText* XMLDocument::NewText( const char* str )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int XMLDocument::Load( const char* filename )
|
||||||
|
{
|
||||||
|
ClearChildren();
|
||||||
|
InitDocument();
|
||||||
|
|
||||||
|
FILE* fp = fopen( filename, "rb" );
|
||||||
|
if ( !fp ) {
|
||||||
|
SetError( ERROR_FILE_NOT_FOUND, filename, 0 );
|
||||||
|
return errorID;
|
||||||
|
}
|
||||||
|
Load( fp );
|
||||||
|
fclose( fp );
|
||||||
|
return errorID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int XMLDocument::Load( FILE* fp )
|
||||||
|
{
|
||||||
|
ClearChildren();
|
||||||
|
InitDocument();
|
||||||
|
|
||||||
|
fseek( fp, 0, SEEK_END );
|
||||||
|
unsigned size = ftell( fp );
|
||||||
|
fseek( fp, 0, SEEK_SET );
|
||||||
|
|
||||||
|
charBuffer = new char[size+1];
|
||||||
|
fread( charBuffer, size, 1, fp );
|
||||||
|
charBuffer[size] = 0;
|
||||||
|
|
||||||
|
ParseDeep( charBuffer );
|
||||||
|
return errorID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLDocument::Save( const char* filename )
|
||||||
|
{
|
||||||
|
FILE* fp = fopen( filename, "w" );
|
||||||
|
XMLStreamer stream( fp );
|
||||||
|
Print( &stream );
|
||||||
|
fclose( fp );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int XMLDocument::Parse( const char* p )
|
int XMLDocument::Parse( const char* p )
|
||||||
{
|
{
|
||||||
|
@ -928,9 +997,8 @@ int XMLDocument::Parse( const char* p )
|
||||||
size_t len = strlen( p );
|
size_t len = strlen( p );
|
||||||
charBuffer = new char[ len+1 ];
|
charBuffer = new char[ len+1 ];
|
||||||
memcpy( charBuffer, p, len+1 );
|
memcpy( charBuffer, p, len+1 );
|
||||||
XMLNode* node = 0;
|
|
||||||
|
ParseDeep( charBuffer );
|
||||||
char* q = ParseDeep( charBuffer );
|
|
||||||
return errorID;
|
return errorID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -950,16 +1018,42 @@ void XMLDocument::Print( XMLStreamer* streamer )
|
||||||
void XMLDocument::SetError( int error, const char* str1, const char* str2 )
|
void XMLDocument::SetError( int error, const char* str1, const char* str2 )
|
||||||
{
|
{
|
||||||
errorID = error;
|
errorID = error;
|
||||||
printf( "ERROR: id=%d '%s' '%s'\n", error, str1, str2 ); // fixme: remove
|
|
||||||
errorStr1 = str1;
|
errorStr1 = str1;
|
||||||
errorStr2 = str2;
|
errorStr2 = str2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
XMLStreamer::XMLStreamer( FILE* file ) : fp( file ), depth( 0 ), elementJustOpened( false ), textDepth( -1 )
|
void XMLDocument::PrintError() const
|
||||||
|
{
|
||||||
|
if ( errorID ) {
|
||||||
|
char buf1[20] = { 0 };
|
||||||
|
char buf2[20] = { 0 };
|
||||||
|
|
||||||
|
if ( errorStr1 ) {
|
||||||
|
strncpy( buf1, errorStr1, 20 );
|
||||||
|
buf1[19] = 0;
|
||||||
|
}
|
||||||
|
if ( errorStr2 ) {
|
||||||
|
strncpy( buf2, errorStr2, 20 );
|
||||||
|
buf2[19] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf( "XMLDocument error id=%d str1=%s str2=%s\n",
|
||||||
|
errorID, buf1, buf2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
XMLStreamer::XMLStreamer( FILE* file ) :
|
||||||
|
elementJustOpened( false ),
|
||||||
|
firstElement( true ),
|
||||||
|
fp( file ),
|
||||||
|
depth( 0 ),
|
||||||
|
textDepth( -1 )
|
||||||
{
|
{
|
||||||
for( int i=0; i<ENTITY_RANGE; ++i ) {
|
for( int i=0; i<ENTITY_RANGE; ++i ) {
|
||||||
entityFlag[i] = false;
|
entityFlag[i] = false;
|
||||||
|
restrictedEntityFlag[i] = false;
|
||||||
}
|
}
|
||||||
for( int i=0; i<NUM_ENTITIES; ++i ) {
|
for( int i=0; i<NUM_ENTITIES; ++i ) {
|
||||||
TIXMLASSERT( entities[i].value < ENTITY_RANGE );
|
TIXMLASSERT( entities[i].value < ENTITY_RANGE );
|
||||||
|
@ -967,6 +1061,8 @@ XMLStreamer::XMLStreamer( FILE* file ) : fp( file ), depth( 0 ), elementJustOpen
|
||||||
entityFlag[ entities[i].value ] = true;
|
entityFlag[ entities[i].value ] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
restrictedEntityFlag['&'] = true;
|
||||||
|
restrictedEntityFlag['<'] = true;
|
||||||
buffer.Push( 0 );
|
buffer.Push( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -984,10 +1080,12 @@ void XMLStreamer::Print( const char* format, ... )
|
||||||
// way on windows.
|
// way on windows.
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
int len = -1;
|
int len = -1;
|
||||||
|
int expand = 1000;
|
||||||
while ( len < 0 ) {
|
while ( len < 0 ) {
|
||||||
len = vsnprintf_s( accumulator.Mem(), accumulator.Capacity(), accumulator.Capacity()-1, format, va );
|
len = vsnprintf_s( accumulator.Mem(), accumulator.Capacity(), accumulator.Capacity()-1, format, va );
|
||||||
if ( len < 0 ) {
|
if ( len < 0 ) {
|
||||||
accumulator.PushArr( 1000 );
|
accumulator.PushArr( expand );
|
||||||
|
expand *= 3/2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char* p = buffer.PushArr( len ) - 1;
|
char* p = buffer.PushArr( len ) - 1;
|
||||||
|
@ -1010,17 +1108,18 @@ void XMLStreamer::PrintSpace( int depth )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XMLStreamer::PrintString( const char* p )
|
void XMLStreamer::PrintString( const char* p, bool restricted )
|
||||||
{
|
{
|
||||||
// Look for runs of bytes between entities to print.
|
// Look for runs of bytes between entities to print.
|
||||||
const char* q = p;
|
const char* q = p;
|
||||||
|
const bool* flag = restricted ? restrictedEntityFlag : entityFlag;
|
||||||
|
|
||||||
while ( *q ) {
|
while ( *q ) {
|
||||||
if ( *q < ENTITY_RANGE ) {
|
if ( *q < ENTITY_RANGE ) {
|
||||||
// Check for entities. If one is found, flush
|
// Check for entities. If one is found, flush
|
||||||
// the stream up until the entity, write the
|
// the stream up until the entity, write the
|
||||||
// entity, and keep looking.
|
// entity, and keep looking.
|
||||||
if ( entityFlag[*q] ) {
|
if ( flag[*q] ) {
|
||||||
while ( p < q ) {
|
while ( p < q ) {
|
||||||
Print( "%c", *p );
|
Print( "%c", *p );
|
||||||
++p;
|
++p;
|
||||||
|
@ -1051,13 +1150,14 @@ void XMLStreamer::OpenElement( const char* name )
|
||||||
}
|
}
|
||||||
stack.Push( name );
|
stack.Push( name );
|
||||||
|
|
||||||
if ( textDepth < 0 && depth > 0) {
|
if ( textDepth < 0 && !firstElement ) {
|
||||||
Print( "\n" );
|
Print( "\n" );
|
||||||
PrintSpace( depth );
|
PrintSpace( depth );
|
||||||
}
|
}
|
||||||
|
|
||||||
Print( "<%s", name );
|
Print( "<%s", name );
|
||||||
elementJustOpened = true;
|
elementJustOpened = true;
|
||||||
|
firstElement = false;
|
||||||
++depth;
|
++depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1066,7 +1166,7 @@ void XMLStreamer::PushAttribute( const char* name, const char* value )
|
||||||
{
|
{
|
||||||
TIXMLASSERT( elementJustOpened );
|
TIXMLASSERT( elementJustOpened );
|
||||||
Print( " %s=\"", name );
|
Print( " %s=\"", name );
|
||||||
PrintString( value );
|
PrintString( value, false );
|
||||||
Print( "\"" );
|
Print( "\"" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1109,11 +1209,14 @@ void XMLStreamer::PushText( const char* text, bool cdata )
|
||||||
if ( elementJustOpened ) {
|
if ( elementJustOpened ) {
|
||||||
SealElement();
|
SealElement();
|
||||||
}
|
}
|
||||||
if ( cdata )
|
if ( cdata ) {
|
||||||
Print( "<![CDATA[" );
|
Print( "<![CDATA[" );
|
||||||
PrintString( text );
|
Print( "%s", text );
|
||||||
if ( cdata )
|
|
||||||
Print( "]]>" );
|
Print( "]]>" );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PrintString( text, true );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1122,14 +1225,43 @@ void XMLStreamer::PushComment( const char* comment )
|
||||||
if ( elementJustOpened ) {
|
if ( elementJustOpened ) {
|
||||||
SealElement();
|
SealElement();
|
||||||
}
|
}
|
||||||
if ( textDepth < 0 && depth > 0) {
|
if ( textDepth < 0 && !firstElement ) {
|
||||||
Print( "\n" );
|
Print( "\n" );
|
||||||
PrintSpace( depth );
|
PrintSpace( depth );
|
||||||
}
|
}
|
||||||
|
firstElement = false;
|
||||||
Print( "<!--%s-->", comment );
|
Print( "<!--%s-->", comment );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLStreamer::PushDeclaration( const char* value )
|
||||||
|
{
|
||||||
|
if ( elementJustOpened ) {
|
||||||
|
SealElement();
|
||||||
|
}
|
||||||
|
if ( textDepth < 0 && !firstElement) {
|
||||||
|
Print( "\n" );
|
||||||
|
PrintSpace( depth );
|
||||||
|
}
|
||||||
|
firstElement = false;
|
||||||
|
Print( "<?%s?>", value );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLStreamer::PushUnknown( const char* value )
|
||||||
|
{
|
||||||
|
if ( elementJustOpened ) {
|
||||||
|
SealElement();
|
||||||
|
}
|
||||||
|
if ( textDepth < 0 && !firstElement ) {
|
||||||
|
Print( "\n" );
|
||||||
|
PrintSpace( depth );
|
||||||
|
}
|
||||||
|
firstElement = false;
|
||||||
|
Print( "<!%s>", value );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool XMLStreamer::VisitEnter( const XMLElement& element, const XMLAttribute* attribute )
|
bool XMLStreamer::VisitEnter( const XMLElement& element, const XMLAttribute* attribute )
|
||||||
{
|
{
|
||||||
OpenElement( element.Name() );
|
OpenElement( element.Name() );
|
||||||
|
@ -1160,3 +1292,18 @@ bool XMLStreamer::Visit( const XMLComment& comment )
|
||||||
PushComment( comment.Value() );
|
PushComment( comment.Value() );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool XMLStreamer::Visit( const XMLDeclaration& declaration )
|
||||||
|
{
|
||||||
|
PushDeclaration( declaration.Value() );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool XMLStreamer::Visit( const XMLUnknown& unknown )
|
||||||
|
{
|
||||||
|
PushUnknown( unknown.Value() );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
30
tinyxml2.h
30
tinyxml2.h
|
@ -15,14 +15,15 @@
|
||||||
X UTF8 support: isAlpha, etc.
|
X UTF8 support: isAlpha, etc.
|
||||||
X string buffer for sets. (Grr.)
|
X string buffer for sets. (Grr.)
|
||||||
- MS BOM
|
- MS BOM
|
||||||
- print to memory buffer
|
X print to memory buffer
|
||||||
- tests from xml1
|
- tests from xml1
|
||||||
- xml1 tests especially UTF-8
|
- xml1 tests especially UTF-8
|
||||||
- perf test: xml1
|
- perf test: xml1
|
||||||
- perf test: xenowar
|
- perf test: xenowar
|
||||||
- test: load(char*)
|
- test: load(char*)
|
||||||
- test: load(FILE*)
|
- test: load(FILE*)
|
||||||
|
- rename declaration
|
||||||
|
- rename streamer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
@ -689,9 +690,10 @@ public:
|
||||||
virtual XMLDocument* ToDocument() { return this; }
|
virtual XMLDocument* ToDocument() { return this; }
|
||||||
virtual const XMLDocument* ToDocument() const { return this; }
|
virtual const XMLDocument* ToDocument() const { return this; }
|
||||||
|
|
||||||
int Parse( const char* );
|
int Parse( const char* xml );
|
||||||
int Load( const char* );
|
int Load( const char* filename );
|
||||||
int Load( FILE* );
|
int Load( FILE* );
|
||||||
|
void Save( const char* filename );
|
||||||
|
|
||||||
void Print( XMLStreamer* streamer=0 );
|
void Print( XMLStreamer* streamer=0 );
|
||||||
virtual bool Accept( XMLVisitor* visitor ) const;
|
virtual bool Accept( XMLVisitor* visitor ) const;
|
||||||
|
@ -716,10 +718,17 @@ public:
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NO_ERROR = 0,
|
NO_ERROR = 0,
|
||||||
|
ERROR_FILE_NOT_FOUND,
|
||||||
ERROR_ELEMENT_MISMATCH,
|
ERROR_ELEMENT_MISMATCH,
|
||||||
ERROR_PARSING_ELEMENT,
|
ERROR_PARSING_ELEMENT,
|
||||||
ERROR_PARSING_ATTRIBUTE,
|
ERROR_PARSING_ATTRIBUTE,
|
||||||
ERROR_IDENTIFYING_TAG
|
ERROR_IDENTIFYING_TAG,
|
||||||
|
ERROR_PARSING_TEXT,
|
||||||
|
ERROR_PARSING_CDATA,
|
||||||
|
ERROR_PARSING_COMMENT,
|
||||||
|
ERROR_PARSING_DECLARATION,
|
||||||
|
ERROR_PARSING_UNKNOWN
|
||||||
|
|
||||||
};
|
};
|
||||||
void SetError( int error, const char* str1, const char* str2 );
|
void SetError( int error, const char* str1, const char* str2 );
|
||||||
|
|
||||||
|
@ -727,6 +736,7 @@ public:
|
||||||
int GetErrorID() const { return errorID; }
|
int GetErrorID() const { return errorID; }
|
||||||
const char* GetErrorStr1() const { return errorStr1; }
|
const char* GetErrorStr1() const { return errorStr1; }
|
||||||
const char* GetErrorStr2() const { return errorStr2; }
|
const char* GetErrorStr2() const { return errorStr2; }
|
||||||
|
void PrintError() const;
|
||||||
|
|
||||||
char* Identify( char* p, XMLNode** node );
|
char* Identify( char* p, XMLNode** node );
|
||||||
|
|
||||||
|
@ -759,6 +769,8 @@ public:
|
||||||
|
|
||||||
void PushText( const char* text, bool cdata=false );
|
void PushText( const char* text, bool cdata=false );
|
||||||
void PushComment( const char* comment );
|
void PushComment( const char* comment );
|
||||||
|
void PushDeclaration( const char* value );
|
||||||
|
void PushUnknown( const char* value );
|
||||||
|
|
||||||
virtual bool VisitEnter( const XMLDocument& /*doc*/ ) { return true; }
|
virtual bool VisitEnter( const XMLDocument& /*doc*/ ) { return true; }
|
||||||
virtual bool VisitExit( const XMLDocument& /*doc*/ ) { return true; }
|
virtual bool VisitExit( const XMLDocument& /*doc*/ ) { return true; }
|
||||||
|
@ -768,24 +780,28 @@ 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 XMLUnknown& unknown );
|
||||||
|
|
||||||
const char* CStr() const { return buffer.Mem(); }
|
const char* CStr() const { return buffer.Mem(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SealElement();
|
void SealElement();
|
||||||
void PrintSpace( int depth );
|
void PrintSpace( int depth );
|
||||||
void PrintString( const char* ); // prints out, after detecting entities.
|
void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
|
||||||
void Print( const char* format, ... );
|
void Print( const char* format, ... );
|
||||||
|
|
||||||
|
bool elementJustOpened;
|
||||||
|
bool firstElement;
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
int depth;
|
int depth;
|
||||||
bool elementJustOpened;
|
|
||||||
int textDepth;
|
int textDepth;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ENTITY_RANGE = 64
|
ENTITY_RANGE = 64
|
||||||
};
|
};
|
||||||
bool entityFlag[ENTITY_RANGE];
|
bool entityFlag[ENTITY_RANGE];
|
||||||
|
bool restrictedEntityFlag[ENTITY_RANGE];
|
||||||
|
|
||||||
DynArray< const char*, 10 > stack;
|
DynArray< const char*, 10 > stack;
|
||||||
DynArray< char, 20 > buffer, accumulator;
|
DynArray< char, 20 > buffer, accumulator;
|
||||||
|
|
67
xmltest.cpp
67
xmltest.cpp
|
@ -14,6 +14,36 @@ using namespace tinyxml2;
|
||||||
int gPass = 0;
|
int gPass = 0;
|
||||||
int gFail = 0;
|
int gFail = 0;
|
||||||
|
|
||||||
|
//#define DREAM_ONLY
|
||||||
|
|
||||||
|
/*
|
||||||
|
int gNew = 0;
|
||||||
|
int gNewTotal = 0;
|
||||||
|
|
||||||
|
void* operator new( size_t size )
|
||||||
|
{
|
||||||
|
++gNew;
|
||||||
|
return malloc( size );
|
||||||
|
}
|
||||||
|
|
||||||
|
void* operator new[]( size_t size )
|
||||||
|
{
|
||||||
|
++gNew;
|
||||||
|
return malloc( size );
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete[]( void* mem )
|
||||||
|
{
|
||||||
|
free( mem );
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete( void* mem )
|
||||||
|
{
|
||||||
|
free( mem );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
bool XMLTest (const char* testString, const char* expected, const char* found, bool echo=true )
|
bool XMLTest (const char* testString, const char* expected, const char* found, bool echo=true )
|
||||||
{
|
{
|
||||||
bool pass = !strcmp( expected, found );
|
bool pass = !strcmp( expected, found );
|
||||||
|
@ -61,7 +91,7 @@ int main( int argc, const char* argv )
|
||||||
#if defined( WIN32 )
|
#if defined( WIN32 )
|
||||||
_CrtMemCheckpoint( &startMemState );
|
_CrtMemCheckpoint( &startMemState );
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef DREAM_ONLY
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
static const char* test = "<!--hello world\n"
|
static const char* test = "<!--hello world\n"
|
||||||
|
@ -169,6 +199,40 @@ int main( int argc, const char* argv )
|
||||||
|
|
||||||
delete doc;
|
delete doc;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// Test: Dream
|
||||||
|
// XML1 : 1,187,569 bytes in 31,209 allocations
|
||||||
|
// XML2 : 469,073 bytes in 323 allocations
|
||||||
|
//int newStart = gNew;
|
||||||
|
XMLDocument doc;
|
||||||
|
doc.Load( "dream.xml" );
|
||||||
|
|
||||||
|
doc.Save( "dreamout.xml" );
|
||||||
|
doc.PrintError();
|
||||||
|
|
||||||
|
XMLTest( "Dream", "xml version=\"1.0\"",
|
||||||
|
doc.FirstChild()->ToDeclaration()->Value() );
|
||||||
|
XMLTest( "Dream", true, doc.FirstChild()->NextSibling()->ToUnknown() ? true : false );
|
||||||
|
XMLTest( "Dream", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
|
||||||
|
doc.FirstChild()->NextSibling()->ToUnknown()->Value() );
|
||||||
|
XMLTest( "Dream", "And Robin shall restore amends.",
|
||||||
|
doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
|
||||||
|
XMLTest( "Dream", "And Robin shall restore amends.",
|
||||||
|
doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
|
||||||
|
|
||||||
|
XMLDocument doc2;
|
||||||
|
doc2.Load( "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", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
|
||||||
|
doc2.FirstChild()->NextSibling()->ToUnknown()->Value() );
|
||||||
|
XMLTest( "Dream-out", "And Robin shall restore amends.",
|
||||||
|
doc2.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
|
||||||
|
|
||||||
|
//gNewTotal = gNew - newStart;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined( WIN32 )
|
#if defined( WIN32 )
|
||||||
_CrtMemCheckpoint( &endMemState );
|
_CrtMemCheckpoint( &endMemState );
|
||||||
|
@ -177,6 +241,7 @@ int main( int argc, const char* argv )
|
||||||
_CrtMemState diffMemState;
|
_CrtMemState diffMemState;
|
||||||
_CrtMemDifference( &diffMemState, &startMemState, &endMemState );
|
_CrtMemDifference( &diffMemState, &startMemState, &endMemState );
|
||||||
_CrtMemDumpStatistics( &diffMemState );
|
_CrtMemDumpStatistics( &diffMemState );
|
||||||
|
//printf( "new total=%d\n", gNewTotal );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
printf ("\nPass %d, Fail %d\n", gPass, gFail);
|
printf ("\nPass %d, Fail %d\n", gPass, gFail);
|
||||||
|
|
Loading…
Reference in New Issue