Explorar o código

removed the pointer-diff

Lee Thomason (grinliz) %!s(int64=14) %!d(string=hai) anos
pai
achega
7ca5558bca
Modificáronse 8 ficheiros con 238 adicións e 69 borrados
  1. 1 1
      dox
  2. 18 34
      readme.txt
  3. 79 0
      setversion.py
  4. 34 28
      tinyxml2.cpp
  5. 17 4
      tinyxml2.h
  6. 3 0
      tinyxml2/tinyxml2.vcxproj
  7. 5 0
      tinyxml2/tinyxml2.vcxproj.filters
  8. 81 2
      xmltest.cpp

+ 1 - 1
dox

@@ -32,7 +32,7 @@ PROJECT_NAME           = "TinyXML-2"
 # This could be handy for archiving the generated documentation or
 # This could be handy for archiving the generated documentation or
 # if some version control system is used.
 # if some version control system is used.
 
 
-PROJECT_NUMBER         =
+PROJECT_NUMBER = 0.9.0
 
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer
 # for a project that appears at the top of each page and should give viewer

+ 18 - 34
readme.txt

@@ -55,7 +55,7 @@ complete XML needs, TinyXML-2 is not the parser for you.
 Which should you use? TinyXML-2 uses a similar API to TinyXML-1 and the same
 Which should you use? TinyXML-2 uses a similar API to TinyXML-1 and the same
 rich test cases. But the implementation of the parser is completely re-written
 rich test cases. But the implementation of the parser is completely re-written
 to make it more appropriate for use in a game. It uses less memory, is faster,
 to make it more appropriate for use in a game. It uses less memory, is faster,
-and user far few memory allocations.
+and uses far few memory allocations.
 
 
 TinyXML-2 has no requirement for STL, but has also dropped all STL support. All
 TinyXML-2 has no requirement for STL, but has also dropped all STL support. All
 strings are query and set as 'const char*'. This allows the use of internal 
 strings are query and set as 'const char*'. This allows the use of internal 
@@ -71,7 +71,7 @@ Both parsers:
 Advantages of TinyXML-2
 Advantages of TinyXML-2
 <ol>
 <ol>
 	<li>The focus of all future dev.</li>	
 	<li>The focus of all future dev.</li>	
-	<li>Many fewer memory allocation (about 1/100th), uses less memory (about 40% of TinyXML-1), and faster.</li>
+	<li>Many fewer memory allocation (1/10th to 1/100th), uses less memory (about 40% of TinyXML-1), and faster.</li>
 	<li>No STL requirement.</li>
 	<li>No STL requirement.</li>
 	<li>More modern C++, including a proper namespace.</li>
 	<li>More modern C++, including a proper namespace.</li>
 	<li>Proper and useful handling of whitespace</li>
 	<li>Proper and useful handling of whitespace</li>
@@ -107,52 +107,41 @@ As a first step, all newlines / carriage-returns / line-feeds are normalized to
 line-feed character, as required by the XML spec.
 line-feed character, as required by the XML spec.
 
 
 White space in text is preserved. For example:
 White space in text is preserved. For example:
-@verbatim
+
 	<element> Hello,  World</element>
 	<element> Hello,  World</element>
-@endverbatim
 
 
 The leading space before the "Hello" and the double space after the comma are preserved.
 The leading space before the "Hello" and the double space after the comma are preserved.
 Line-feeds are preserved, as in this example:
 Line-feeds are preserved, as in this example:
 
 
-@verbatim
 	<element> Hello again,  
 	<element> Hello again,  
 	          World</element>
 	          World</element>
-@endverbatim
 
 
 However, white space between elements is *not* preserved. Although not strictly compliant,
 However, white space between elements is *not* preserved. Although not strictly compliant,
 tracking and reporting inta-element space is awkward, and not normally valuable. TinyXML-2 
 tracking and reporting inta-element space is awkward, and not normally valuable. TinyXML-2 
 sees these as the same XML:
 sees these as the same XML:
 
 
-@verbatim
-<document>
-<data>1</data>
-<data>2</data>
-<data>3</data>
-</document>
-@endverbatim
+	<document>
+	<data>1</data>
+	<data>2</data>
+	<data>3</data>
+	</document>
 
 
-@verbatim
-<document><data>1</data><data>2</data><data>3</data></document>
-@endverbatim
+	<document><data>1</data><data>2</data><data>3</data></document>
 
 
 <h3> Entities </h3>
 <h3> Entities </h3>
 TinyXML-2 recognizes the pre-defined "character entities", meaning special
 TinyXML-2 recognizes the pre-defined "character entities", meaning special
 characters. Namely:
 characters. Namely:
 
 
-@verbatim
 	&amp;	&
 	&amp;	&
 	&lt;	<
 	&lt;	<
 	&gt;	>
 	&gt;	>
 	&quot;	"
 	&quot;	"
 	&apos;	'
 	&apos;	'
-@endverbatim
 
 
 These are recognized when the XML document is read, and translated to there
 These are recognized when the XML document is read, and translated to there
 UTF-8 equivalents. For instance, text with the XML of:
 UTF-8 equivalents. For instance, text with the XML of:
 
 
-@verbatim
 	Far &amp; Away
 	Far &amp; Away
-@endverbatim
 
 
 will have the Value() of "Far & Away" when queried from the XMLText object,
 will have the Value() of "Far & Away" when queried from the XMLText object,
 and will be written back to the XML stream/file as an ampersand. 
 and will be written back to the XML stream/file as an ampersand. 
@@ -167,42 +156,37 @@ regular code point. The output is correct, but the entity syntax isn't preserved
 
 
 <h4> Print to file </h4>
 <h4> Print to file </h4>
 You can directly use the convenience function:
 You can directly use the convenience function:
-@verbatim
+
 	XMLDocument doc;
 	XMLDocument doc;
 	...
 	...
 	doc.Save( "foo.xml" );
 	doc.Save( "foo.xml" );
-@endverbatim
 
 
 Or the XMLPrinter class:
 Or the XMLPrinter class:
-@verbatim
+
 	XMLPrinter printer( fp );
 	XMLPrinter printer( fp );
 	doc.Print( &printer );
 	doc.Print( &printer );
-@endverbatim
 
 
 <h4> Print to memory </h4>
 <h4> Print to memory </h4>
 Printing to memory is supported by the XMLPrinter.
 Printing to memory is supported by the XMLPrinter.
-@verbatim
+
 	XMLPrinter printer;
 	XMLPrinter printer;
 	doc->Print( &printer );
 	doc->Print( &printer );
 	// printer.CStr() has a const char* to the XML
 	// printer.CStr() has a const char* to the XML
-@endverbatim
 
 
 <h4> Print without an XMLDocument </h4>
 <h4> Print without an XMLDocument </h4>
 
 
-	When loading, an XML parser is very useful. However, sometimes
-	when saving, it just gets in the way. The code is often set up
-	for streaming, and constructing the DOM is just overhead.
+When loading, an XML parser is very useful. However, sometimes
+when saving, it just gets in the way. The code is often set up
+for streaming, and constructing the DOM is just overhead.
 
 
-	The Printer supports the streaming case. The following code
-	prints out a trivially simple XML file without ever creating
-	an XML document.
+The Printer supports the streaming case. The following code
+prints out a trivially simple XML file without ever creating
+an XML document.
 
 
-@verbatim
 	XMLPrinter printer( fp );
 	XMLPrinter printer( fp );
 	printer.OpenElement( "foo" );
 	printer.OpenElement( "foo" );
 	printer.PushAttribute( "foo", "bar" );
 	printer.PushAttribute( "foo", "bar" );
 	printer.CloseElement();
 	printer.CloseElement();
-@endverbatim
 
 
 <h2> Using and Installing </h2>
 <h2> Using and Installing </h2>
 
 

+ 79 - 0
setversion.py

@@ -0,0 +1,79 @@
+# Python program to set the version.
+##############################################
+
+import re
+import sys
+
+def fileProcess( name, lineFunction ):
+	filestream = open( name, 'r' )
+	if filestream.closed:
+		print( "file " + name + " not open." )
+		return
+
+	output = ""
+	print( "--- Processing " + name + " ---------" )
+	while 1:
+		line = filestream.readline()
+		if not line: break
+		output += lineFunction( line )
+	filestream.close()
+	
+	if not output: return			# basic error checking
+	
+	print( "Writing file " + name )
+	filestream = open( name, "w" );
+	filestream.write( output );
+	filestream.close()
+	
+	
+def echoInput( line ):
+	return line
+
+major = input( "Major: " )
+minor = input( "Minor: " )
+build = input( "Build: " )
+
+print "Setting dox,tinyxml2.h"
+print "Version: " + `major` + "." + `minor` + "." + `build`
+
+#### Write the tinyxml.h ####
+
+def engineRule( line ):
+
+	matchMajor = "static const int TIXML2_MAJOR_VERSION"
+	matchMinor = "static const int TIXML2_MINOR_VERSION"
+	matchBuild = "static const int TIXML2_PATCH_VERSION"
+
+	if line[0:len(matchMajor)] == matchMajor:
+		print "1)tinyxml2.h Major found"
+		return matchMajor + " = " + `major` + ";\n"
+
+	elif line[0:len(matchMinor)] == matchMinor:
+		print "2)tinyxml2.h Minor found"
+		return matchMinor + " = " + `minor` + ";\n"
+
+	elif line[0:len(matchBuild)] == matchBuild:
+		print "3)tinyxml2.h Build found"
+		return matchBuild + " = " + `build` + ";\n"
+
+	else:
+		return line;
+
+fileProcess( "tinyxml2.h", engineRule )
+
+
+#### Write the dox ####
+
+def doxRule( line ):
+
+	match = "PROJECT_NUMBER"
+
+	if line[0:len( match )] == match:
+		print "dox project found"
+		return "PROJECT_NUMBER = " + `major` + "." + `minor` + "." + `build` + "\n"
+
+	else:
+		return line;
+
+fileProcess( "dox", doxRule )
+

+ 34 - 28
tinyxml2.cpp

@@ -312,7 +312,7 @@ const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length )
 	if ( *(p+1) == '#' && *(p+2) )
 	if ( *(p+1) == '#' && *(p+2) )
 	{
 	{
 		unsigned long ucs = 0;
 		unsigned long ucs = 0;
-		ptrdiff_t delta = 0;
+		int delta = 0;
 		unsigned mult = 1;
 		unsigned mult = 1;
 
 
 		if ( *(p+2) == 'x' )
 		if ( *(p+2) == 'x' )
@@ -325,7 +325,7 @@ const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length )
 
 
 			if ( !q || !*q ) return 0;
 			if ( !q || !*q ) return 0;
 
 
-			delta = q-p;
+			delta = (q-p);
 			--q;
 			--q;
 
 
 			while ( *q != 'x' )
 			while ( *q != 'x' )
@@ -740,7 +740,7 @@ char* XMLText::ParseDeep( char* p, StrPair* )
 		return p;
 		return p;
 	}
 	}
 	else {
 	else {
-		p = value.ParseText( p, "<", StrPair::TEXT_ELEMENT );
+		p = value.ParseText( p, "<", document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES );
 		if ( !p ) {
 		if ( !p ) {
 			document->SetError( ERROR_PARSING_TEXT, start, 0 );
 			document->SetError( ERROR_PARSING_TEXT, start, 0 );
 		}
 		}
@@ -916,14 +916,14 @@ bool XMLUnknown::Accept( XMLVisitor* visitor ) const
 }
 }
 
 
 // --------- XMLAttribute ---------- //
 // --------- XMLAttribute ---------- //
-char* XMLAttribute::ParseDeep( char* p )
+char* XMLAttribute::ParseDeep( char* p, bool processEntities )
 {
 {
 	p = name.ParseText( p, "=", StrPair::ATTRIBUTE_NAME );
 	p = name.ParseText( p, "=", StrPair::ATTRIBUTE_NAME );
 	if ( !p || !*p ) return 0;
 	if ( !p || !*p ) return 0;
 
 
 	char endTag[2] = { *p, 0 };
 	char endTag[2] = { *p, 0 };
 	++p;
 	++p;
-	p = value.ParseText( p, endTag, StrPair::ATTRIBUTE_VALUE );
+	p = value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES );
 	//if ( value.Empty() ) return 0;
 	//if ( value.Empty() ) return 0;
 	return p;
 	return p;
 }
 }
@@ -1141,7 +1141,7 @@ char* XMLElement::ParseAttributes( char* p )
 			XMLAttribute* attrib = new (document->attributePool.Alloc() ) XMLAttribute();
 			XMLAttribute* attrib = new (document->attributePool.Alloc() ) XMLAttribute();
 			attrib->memPool = &document->attributePool;
 			attrib->memPool = &document->attributePool;
 
 
-			p = attrib->ParseDeep( p );
+			p = attrib->ParseDeep( p, document->ProcessEntities() );
 			if ( !p || Attribute( attrib->Name() ) ) {
 			if ( !p || Attribute( attrib->Name() ) ) {
 				DELETE_ATTRIBUTE( attrib );
 				DELETE_ATTRIBUTE( attrib );
 				document->SetError( ERROR_PARSING_ATTRIBUTE, start, p );
 				document->SetError( ERROR_PARSING_ATTRIBUTE, start, p );
@@ -1250,9 +1250,13 @@ bool XMLElement::Accept( XMLVisitor* visitor ) const
 
 
 
 
 // --------- XMLDocument ----------- //
 // --------- XMLDocument ----------- //
-XMLDocument::XMLDocument() :
+XMLDocument::XMLDocument( bool _processEntities ) :
 	XMLNode( 0 ),
 	XMLNode( 0 ),
 	writeBOM( false ),
 	writeBOM( false ),
+	processEntities( _processEntities ),
+	errorID( 0 ),
+	errorStr1( 0 ),
+	errorStr2( 0 ),
 	charBuffer( 0 )
 	charBuffer( 0 )
 {
 {
 	document = this;	// avoid warning about 'this' in initializer list
 	document = this;	// avoid warning about 'this' in initializer list
@@ -1474,7 +1478,8 @@ XMLPrinter::XMLPrinter( FILE* file ) :
 	firstElement( true ),
 	firstElement( true ),
 	fp( file ), 
 	fp( file ), 
 	depth( 0 ), 
 	depth( 0 ), 
-	textDepth( -1 )
+	textDepth( -1 ),
+	processEntities( true )
 {
 {
 	for( int i=0; i<ENTITY_RANGE; ++i ) {
 	for( int i=0; i<ENTITY_RANGE; ++i ) {
 		entityFlag[i] = false;
 		entityFlag[i] = false;
@@ -1540,31 +1545,33 @@ void XMLPrinter::PrintString( const char* p, bool restricted )
 	const char* q = p;
 	const char* q = p;
 	const bool* flag = restricted ? restrictedEntityFlag : entityFlag;
 	const bool* flag = restricted ? restrictedEntityFlag : entityFlag;
 
 
-	while ( *q ) {
-		// Remember, char is sometimes signed. (How many times has that bitten me?)
-		if ( *q > 0 && *q < ENTITY_RANGE ) {
-			// Check for entities. If one is found, flush
-			// the stream up until the entity, write the 
-			// entity, and keep looking.
-			if ( flag[*q] ) {
-				while ( p < q ) {
-					Print( "%c", *p );
-					++p;
-				}
-				for( int i=0; i<NUM_ENTITIES; ++i ) {
-					if ( entities[i].value == *q ) {
-						Print( "&%s;", entities[i].pattern );
-						break;
+	if ( processEntities ) {
+		while ( *q ) {
+			// Remember, char is sometimes signed. (How many times has that bitten me?)
+			if ( *q > 0 && *q < ENTITY_RANGE ) {
+				// Check for entities. If one is found, flush
+				// the stream up until the entity, write the 
+				// entity, and keep looking.
+				if ( flag[*q] ) {
+					while ( p < q ) {
+						Print( "%c", *p );
+						++p;
 					}
 					}
+					for( int i=0; i<NUM_ENTITIES; ++i ) {
+						if ( entities[i].value == *q ) {
+							Print( "&%s;", entities[i].pattern );
+							break;
+						}
+					}
+					++p;
 				}
 				}
-				++p;
 			}
 			}
+			++q;
 		}
 		}
-		++q;
 	}
 	}
 	// Flush the remaining string. This will be the entire
 	// Flush the remaining string. This will be the entire
 	// string if an entity wasn't found.
 	// string if an entity wasn't found.
-	if ( q-p > 0 ) {
+	if ( !processEntities || (q-p > 0) ) {
 		Print( "%s", p );
 		Print( "%s", p );
 	}
 	}
 }
 }
@@ -1735,6 +1742,7 @@ void XMLPrinter::PushUnknown( const char* value )
 
 
 bool XMLPrinter::VisitEnter( const XMLDocument& doc )
 bool XMLPrinter::VisitEnter( const XMLDocument& doc )
 {
 {
+	processEntities = doc.ProcessEntities();
 	if ( doc.HasBOM() ) {
 	if ( doc.HasBOM() ) {
 		PushHeader( true, false );
 		PushHeader( true, false );
 	}
 	}
@@ -1785,5 +1793,3 @@ bool XMLPrinter::Visit( const XMLUnknown& unknown )
 	PushUnknown( unknown.Value() );
 	PushUnknown( unknown.Value() );
 	return true;
 	return true;
 }
 }
-
-

+ 17 - 4
tinyxml2.h

@@ -36,6 +36,7 @@ distribution.
 */
 */
 /*
 /*
 	gcc: g++ -Wall tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
 	gcc: g++ -Wall tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
+
 */
 */
 
 
 #if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
 #if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
@@ -84,6 +85,9 @@ distribution.
 	#define TIXML_SSCANF   sscanf
 	#define TIXML_SSCANF   sscanf
 #endif
 #endif
 
 
+static const int TIXML2_MAJOR_VERSION = 0;
+static const int TIXML2_MINOR_VERSION = 9;
+static const int TIXML2_PATCH_VERSION = 0;
 
 
 namespace tinyxml2
 namespace tinyxml2
 {
 {
@@ -112,8 +116,10 @@ public:
 		NEEDS_NEWLINE_NORMALIZATION		= 0x02,
 		NEEDS_NEWLINE_NORMALIZATION		= 0x02,
 
 
 		TEXT_ELEMENT		= NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
 		TEXT_ELEMENT		= NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
+		TEXT_ELEMENT_LEAVE_ENTITIES		= NEEDS_NEWLINE_NORMALIZATION,
 		ATTRIBUTE_NAME		= 0,
 		ATTRIBUTE_NAME		= 0,
 		ATTRIBUTE_VALUE		= NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
 		ATTRIBUTE_VALUE		= NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
+		ATTRIBUTE_VALUE_LEAVE_ENTITIES		= NEEDS_NEWLINE_NORMALIZATION,
 		COMMENT				= NEEDS_NEWLINE_NORMALIZATION,
 		COMMENT				= NEEDS_NEWLINE_NORMALIZATION,
 	};
 	};
 
 
@@ -801,7 +807,7 @@ private:
 	void operator=( const XMLAttribute& );	// not supported
 	void operator=( const XMLAttribute& );	// not supported
 	void SetName( const char* name );
 	void SetName( const char* name );
 
 
-	char* ParseDeep( char* p );
+	char* ParseDeep( char* p, bool processEntities );
 
 
 	mutable StrPair name;
 	mutable StrPair name;
 	mutable StrPair value;
 	mutable StrPair value;
@@ -959,7 +965,7 @@ class XMLDocument : public XMLNode
 	friend class XMLElement;
 	friend class XMLElement;
 public:
 public:
 	/// constructor
 	/// constructor
-	XMLDocument(); 
+	XMLDocument( bool processEntities = true ); 
 	~XMLDocument();
 	~XMLDocument();
 
 
 	virtual XMLDocument* ToDocument()				{ return this; }
 	virtual XMLDocument* ToDocument()				{ return this; }
@@ -990,6 +996,11 @@ public:
 	*/
 	*/
 	void SaveFile( const char* filename );
 	void SaveFile( const char* filename );
 
 
+	bool ProcessEntities() const						{ return processEntities; }
+
+	/**
+		Returns true if this document has a leading Byte Order Mark of UTF8.
+	*/
 	bool HasBOM() const { return writeBOM; }
 	bool HasBOM() const { return writeBOM; }
 
 
 	/** Return the root element of DOM. Equivalent to FirstChildElement().
 	/** Return the root element of DOM. Equivalent to FirstChildElement().
@@ -1068,8 +1079,8 @@ public:
 	// internal
 	// internal
 	char* Identify( char* p, XMLNode** node );
 	char* Identify( char* p, XMLNode** node );
 
 
-	virtual XMLNode* ShallowClone( XMLDocument* ) const	{ return 0; }
-	virtual bool ShallowEqual( const XMLNode* ) const	{ return false; }
+	virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const	{ return 0; }
+	virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const	{ return false; }
 
 
 private:
 private:
 	XMLDocument( const XMLDocument& );	// not supported
 	XMLDocument( const XMLDocument& );	// not supported
@@ -1077,6 +1088,7 @@ private:
 	void InitDocument();
 	void InitDocument();
 
 
 	bool writeBOM;
 	bool writeBOM;
+	bool processEntities;
 	int errorID;
 	int errorID;
 	const char* errorStr1;
 	const char* errorStr1;
 	const char* errorStr2;
 	const char* errorStr2;
@@ -1193,6 +1205,7 @@ private:
 	FILE* fp;
 	FILE* fp;
 	int depth;
 	int depth;
 	int textDepth;
 	int textDepth;
+	bool processEntities;
 
 
 	enum {
 	enum {
 		ENTITY_RANGE = 64,
 		ENTITY_RANGE = 64,

+ 3 - 0
tinyxml2/tinyxml2.vcxproj

@@ -80,6 +80,9 @@
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\tinyxml2.h" />
     <ClInclude Include="..\tinyxml2.h" />
   </ItemGroup>
   </ItemGroup>
+  <ItemGroup>
+    <None Include="..\readme.txt" />
+  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
   </ImportGroup>

+ 5 - 0
tinyxml2/tinyxml2.vcxproj.filters

@@ -19,4 +19,9 @@
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClInclude>
     </ClInclude>
   </ItemGroup>
   </ItemGroup>
+  <ItemGroup>
+    <None Include="..\readme.txt">
+      <Filter>Source Files</Filter>
+    </None>
+  </ItemGroup>
 </Project>
 </Project>

+ 81 - 2
xmltest.cpp

@@ -3,9 +3,12 @@
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
 #include <string.h>
+#include <time.h>
 
 
-#if defined( _MSC_VER ) && defined( DEBUG )
+#if defined( _MSC_VER )
 	#include <crtdbg.h>
 	#include <crtdbg.h>
+	#define WIN32_LEAN_AND_MEAN
+	#include <windows.h>
 	_CrtMemState startMemState;
 	_CrtMemState startMemState;
 	_CrtMemState endMemState;
 	_CrtMemState endMemState;
 #endif
 #endif
@@ -211,6 +214,8 @@ int main( int /*argc*/, const char* /*argv*/ )
 
 
 		//gNewTotal = gNew - newStart;
 		//gNewTotal = gNew - newStart;
 	}
 	}
+
+
 	{
 	{
 		const char* error =	"<?xml version=\"1.0\" standalone=\"no\" ?>\n"
 		const char* error =	"<?xml version=\"1.0\" standalone=\"no\" ?>\n"
 							"<passages count=\"006\" formatversion=\"20020620\">\n"
 							"<passages count=\"006\" formatversion=\"20020620\">\n"
@@ -458,6 +463,24 @@ int main( int /*argc*/, const char* /*argv*/ )
 		fclose( textfile );
 		fclose( textfile );
 	}
 	}
 
 
+	{
+		// Suppress entities.
+		const char* passages =
+			"<?xml version=\"1.0\" standalone=\"no\" ?>"
+			"<passages count=\"006\" formatversion=\"20020620\">"
+				"<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;.\">Crazy &ttk;</psg>"
+			"</passages>";
+		
+		XMLDocument doc( false );
+		doc.Parse( passages );
+
+		XMLTest( "No entity parsing.", doc.FirstChildElement()->FirstChildElement()->Attribute( "context" ), 
+				 "Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;." );
+		XMLTest( "No entity parsing.", doc.FirstChildElement()->FirstChildElement()->FirstChild()->Value(),
+				 "Crazy &ttk;" );
+		doc.Print();
+	}
+
 	{
 	{
         const char* test = "<?xml version='1.0'?><a.elem xmi.version='2.0'/>";
         const char* test = "<?xml version='1.0'?><a.elem xmi.version='2.0'/>";
 
 
@@ -654,7 +677,63 @@ int main( int /*argc*/, const char* /*argv*/ )
 		XMLTest( "Clone and Equal", 4, count );
 		XMLTest( "Clone and Equal", 4, count );
 	}
 	}
 
 
-	#if defined( _MSC_VER ) && defined( DEBUG )
+	// ----------- Performance tracking --------------
+	{
+#if defined( _MSC_VER )
+		__int64 start, end, freq;
+		QueryPerformanceFrequency( (LARGE_INTEGER*) &freq );
+#endif
+
+#if defined(_MSC_VER)
+#pragma warning ( push )
+#pragma warning ( disable : 4996 )		// Fail to see a compelling reason why this should be deprecated.
+#endif
+		FILE* fp  = fopen( "dream.xml", "r" );
+#if defined(_MSC_VER)
+#pragma warning ( pop )
+#endif
+		fseek( fp, 0, SEEK_END );
+		long size = ftell( fp );
+		fseek( fp, 0, SEEK_SET );
+
+		char* mem = new char[size+1];
+		fread( mem, size, 1, fp );
+		fclose( fp );
+		mem[size] = 0;
+
+#if defined( _MSC_VER )
+		QueryPerformanceCounter( (LARGE_INTEGER*) &start );
+#else
+		clock_t cstart = clock();
+#endif
+		static const int COUNT = 10;
+		for( int i=0; i<COUNT; ++i ) {
+			XMLDocument doc;
+			doc.Parse( mem );
+		}
+#if defined( _MSC_VER )
+		QueryPerformanceCounter( (LARGE_INTEGER*) &end );
+#else
+		clock_t cend = clock();
+#endif
+
+		delete [] mem;
+
+		static const char* note = 
+#ifdef DEBUG
+			"DEBUG";
+#else
+			"Release";
+#endif
+
+#if defined( _MSC_VER )
+		printf( "\nParsing %s of dream.xml: %.3f milli-seconds\n", note, 1000.0 * (double)(end-start) / ( (double)freq * (double)COUNT) );
+#else
+		printf( "\nParsing %s of dream.xml: %.3f milli-seconds\n", note, (double)(cend - cstart)/(double)COUNT );
+#endif
+	}
+
+	#if defined( _MSC_VER ) &&  defined( DEBUG )
 		_CrtMemCheckpoint( &endMemState );  
 		_CrtMemCheckpoint( &endMemState );  
 		//_CrtMemDumpStatistics( &endMemState );
 		//_CrtMemDumpStatistics( &endMemState );