Merge remote-tracking branch 'origin/master'
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b58f9eb..12cac92 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,8 +10,8 @@
 ################################

 # set lib version here

 

-set(GENERIC_LIB_VERSION "1.0.12")

-set(GENERIC_LIB_SOVERSION "1")

+set(GENERIC_LIB_VERSION "1.0.14")
+set(GENERIC_LIB_SOVERSION "1")
 

 

 ################################

@@ -53,6 +53,7 @@
 endif(BUILD_STATIC_LIBS)

 add_library(tinyxml2 SHARED tinyxml2.cpp tinyxml2.h)

 set_target_properties(tinyxml2 PROPERTIES

+        COMPILE_DEFINITIONS "TINYXML2_EXPORT"

 	VERSION "${GENERIC_LIB_VERSION}"

 	SOVERSION "${GENERIC_LIB_SOVERSION}")

 

diff --git a/dox b/dox
index 7ab99ff..10878f4 100755
--- a/dox
+++ b/dox
@@ -32,7 +32,7 @@
 # This could be handy for archiving the generated documentation or

 # if some version control system is used.

 

-PROJECT_NUMBER = 1.0.12

+PROJECT_NUMBER = 1.0.14
 

 # 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

diff --git a/readme.md b/readme.md
index 7644f41..8ecd536 100644
--- a/readme.md
+++ b/readme.md
@@ -51,11 +51,10 @@
 
 TinyXML-2 doesn't parse or use DTDs (Document Type Definitions) or XSLs
 (eXtensible Stylesheet Language.) There are other parsers out there 
-that are much more fully
-featured. But they are also much bigger, take longer to set up in
-your project, have a higher learning curve, and often have a more
-restrictive license. If you are working with browsers or have more
-complete XML needs, TinyXML-2 is not the parser for you.
+that are much more fully featured. But they are also much bigger, 
+take longer to set up in your project, have a higher learning curve, 
+and often have a more restrictive license. If you are working with 
+browsers or have more complete XML needs, TinyXML-2 is not the parser for you.
 
 TinyXML-1 vs. TinyXML-2
 -----------------------
@@ -309,8 +308,9 @@
 Berquin and Andrew Ellerton who were key contributors.
 
 TinyXML-2 grew from that effort. Lee Thomason is the original author
-of TinyXML-2 (and TinyXML-1) but hopefully TinyXML-2 will be improved
+of TinyXML-2 (and TinyXML-1) but TinyXML-2 has been and is being improved
 by many contributors.
 
-Thanks to John Mackay for the TinyXML-2 logo.
+Thanks to John Mackay at http://john.mackay.rosalilastudio.com for the TinyXML-2 logo!
+
 
diff --git a/tinyxml2.cpp b/tinyxml2.cpp
index 3b665c4..4e79ef5 100755
--- a/tinyxml2.cpp
+++ b/tinyxml2.cpp
@@ -422,16 +422,19 @@
     TIXML_SNPRINTF( buffer, bufferSize, "%d", v ? 1 : 0 );

 }

 

-

+/*

+	ToStr() of a number is a very tricky topic.

+	https://github.com/leethomason/tinyxml2/issues/106

+*/

 void XMLUtil::ToStr( float v, char* buffer, int bufferSize )

 {

-    TIXML_SNPRINTF( buffer, bufferSize, "%f", v );

+    TIXML_SNPRINTF( buffer, bufferSize, "%.8g", v );

 }

 

 

 void XMLUtil::ToStr( double v, char* buffer, int bufferSize )

 {

-    TIXML_SNPRINTF( buffer, bufferSize, "%f", v );

+    TIXML_SNPRINTF( buffer, bufferSize, "%.17g", v );

 }

 

 

@@ -497,12 +500,7 @@
     }

 

     // What is this thing?

-    // - Elements start with a letter or underscore, but xml is reserved.

-    // - Comments: <!--

-    // - Declaration: <?

-    // - Everything else is unknown to tinyxml.

-    //

-

+	// These strings define the matching patters:

     static const char* xmlHeader		= { "<?" };

     static const char* commentHeader	= { "<!--" };

     static const char* dtdHeader		= { "<!" };

@@ -1262,6 +1260,57 @@
 }

 

 

+void	XMLElement::SetText( const char* inText )

+{

+	if ( FirstChild() && FirstChild()->ToText() )

+		FirstChild()->SetValue( inText );

+	else {

+		XMLText*	theText = GetDocument()->NewText( inText );

+		InsertFirstChild( theText );

+	}

+}

+

+

+void XMLElement::SetText( int v ) 

+{

+    char buf[BUF_SIZE];

+    XMLUtil::ToStr( v, buf, BUF_SIZE );

+    SetText( buf );

+}

+

+

+void XMLElement::SetText( unsigned v ) 

+{

+    char buf[BUF_SIZE];

+    XMLUtil::ToStr( v, buf, BUF_SIZE );

+    SetText( buf );

+}

+

+

+void XMLElement::SetText( bool v ) 

+{

+    char buf[BUF_SIZE];

+    XMLUtil::ToStr( v, buf, BUF_SIZE );

+    SetText( buf );

+}

+

+

+void XMLElement::SetText( float v ) 

+{

+    char buf[BUF_SIZE];

+    XMLUtil::ToStr( v, buf, BUF_SIZE );

+    SetText( buf );

+}

+

+

+void XMLElement::SetText( double v ) 

+{

+    char buf[BUF_SIZE];

+    XMLUtil::ToStr( v, buf, BUF_SIZE );

+    SetText( buf );

+}

+

+

 XMLError XMLElement::QueryIntText( int* ival ) const

 {

     if ( FirstChild() && FirstChild()->ToText() ) {

@@ -1639,6 +1688,13 @@
 {

     Clear();

 

+    fseek( fp, 0, SEEK_SET );

+    fgetc( fp );

+    if ( ferror( fp ) != 0 ) {

+        SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 );

+        return _errorID;

+    }

+

     fseek( fp, 0, SEEK_END );

     size_t size = ftell( fp );

     fseek( fp, 0, SEEK_SET );

diff --git a/tinyxml2.h b/tinyxml2.h
index ca3d90e..fc54320 100755
--- a/tinyxml2.h
+++ b/tinyxml2.h
@@ -116,9 +116,15 @@
 #define TIXML_SSCANF   sscanf

 #endif

 

+/* Versioning, past 1.0.14:

+

+	A backwards-incompatible change or API change bumps the major version.

+	An API addition or a backwards-compatible change, bumps the minor version.

+	Simple bug fixes bump the build number.

+*/

 static const int TIXML2_MAJOR_VERSION = 1;

-static const int TIXML2_MINOR_VERSION = 0;

-static const int TIXML2_PATCH_VERSION = 12;

+static const int TIXML2_MINOR_VERSION = 1;

+static const int TIXML2_PATCH_VERSION = 0;

 

 namespace tinyxml2

 {

@@ -216,6 +222,10 @@
         }

     }

 

+    void Clear() {

+        _size = 0;

+    }

+

     void Push( T t ) {

         EnsureCapacity( _size+1 );

         _mem[_size++] = t;

@@ -1317,6 +1327,11 @@
         XMLAttribute* a = FindOrCreateAttribute( name );

         a->SetAttribute( value );

     }

+    /// Sets the named attribute to value.

+    void SetAttribute( const char* name, float value )		{

+        XMLAttribute* a = FindOrCreateAttribute( name );

+        a->SetAttribute( value );

+    }

 

     /**

     	Delete an attribute.

@@ -1360,6 +1375,52 @@
     */

     const char* GetText() const;

 

+    /** Convenience function for easy access to the text inside an element. Although easy

+    	and concise, SetText() is limited compared to creating an XMLText child

+    	and mutating it directly.

+

+    	If the first child of 'this' is a XMLText, SetText() sets its value to

+		the given string, otherwise it will create a first child that is an XMLText.

+

+    	This is a convenient method for setting the text of simple contained text:

+    	@verbatim

+    	<foo>This is text</foo>

+    		fooElement->SetText( "Hullaballoo!" );

+     	<foo>Hullaballoo!</foo>

+		@endverbatim

+

+    	Note that this function can be misleading. If the element foo was created from

+    	this XML:

+    	@verbatim

+    		<foo><b>This is text</b></foo>

+    	@endverbatim

+

+    	then it will not change "This is text", but rather prefix it with a text element:

+    	@verbatim

+    		<foo>Hullaballoo!<b>This is text</b></foo>

+    	@endverbatim

+		

+		For this XML:

+    	@verbatim

+    		<foo />

+    	@endverbatim

+    	SetText() will generate

+    	@verbatim

+    		<foo>Hullaballoo!</foo>

+    	@endverbatim

+    */

+	void SetText( const char* inText );

+    /// Convenience method for setting text inside and element. See SetText() for important limitations.

+    void SetText( int value );

+    /// Convenience method for setting text inside and element. See SetText() for important limitations.

+    void SetText( unsigned value );  

+    /// Convenience method for setting text inside and element. See SetText() for important limitations.

+    void SetText( bool value );  

+    /// Convenience method for setting text inside and element. See SetText() for important limitations.

+    void SetText( double value );  

+    /// Convenience method for setting text inside and element. See SetText() for important limitations.

+    void SetText( float value );  

+

     /**

     	Convenience method to query the value of a child text node. This is probably best

     	shown by example. Given you have a document is this form:

@@ -1420,6 +1481,7 @@
     //void LinkAttribute( XMLAttribute* attrib );

     char* ParseAttributes( char* p );

 

+    enum { BUF_SIZE = 200 };

     int _closingType;

     // The attribute list is ordered; there is no 'lastAttribute'

     // because the list needs to be scanned for dupes before adding

@@ -1962,23 +2024,35 @@
     int CStrSize() const {

         return _buffer.Size();

     }

+    /**

+    	If in print to memory mode, reset the buffer to the

+    	beginning.

+    */

+    void ClearBuffer() {

+        _buffer.Clear();

+        _buffer.Push(0);

+    }

 

 protected:

-    void SealElement();

+	/** Prints out the space before an element. You may override to change

+	    the space and tabs used. A PrintSpace() override should call Print().

+	*/

+    virtual void PrintSpace( int depth );

+    void Print( const char* format, ... );

+

+	void SealElement();

     bool _elementJustOpened;

     DynArray< const char*, 10 > _stack;

 

 private:

-    void PrintSpace( int depth );

     void PrintString( const char*, bool restrictedEntitySet );	// prints out, after detecting entities.

-    void Print( const char* format, ... );

 

     bool _firstElement;

     FILE* _fp;

     int _depth;

     int _textDepth;

     bool _processEntities;

-    bool _compactMode;

+	bool _compactMode;

 

     enum {

         ENTITY_RANGE = 64,

diff --git a/xmltest.cpp b/xmltest.cpp
index 533bcba..6fdc162 100644
--- a/xmltest.cpp
+++ b/xmltest.cpp
@@ -617,6 +617,61 @@
 	}

 

 

+	// --------SetText()-----------

+	{

+		const char* str = "<foo></foo>";

+		XMLDocument doc;

+		doc.Parse( str );

+		XMLElement* element = doc.RootElement();

+

+		element->SetText("darkness.");

+		XMLTest( "SetText() normal use (open/close).", "darkness.", element->GetText() );

+

+		element->SetText("blue flame.");

+		XMLTest( "SetText() replace.", "blue flame.", element->GetText() );

+

+		str = "<foo/>";

+		doc.Parse( str );

+		element = doc.RootElement();

+

+		element->SetText("The driver");

+		XMLTest( "SetText() normal use. (self-closing)", "The driver", element->GetText() );

+

+		element->SetText("<b>horses</b>");

+		XMLTest( "SetText() replace with tag-like text.", "<b>horses</b>", element->GetText() );

+		//doc.Print();

+

+		str = "<foo><bar>Text in nested element</bar></foo>";

+		doc.Parse( str );

+		element = doc.RootElement();

+		

+		element->SetText("wolves");

+		XMLTest( "SetText() prefix to nested non-text children.", "wolves", element->GetText() );

+

+		str = "<foo/>";

+		doc.Parse( str );

+		element = doc.RootElement();

+		

+		element->SetText( "str" );

+		XMLTest( "SetText types", "str", element->GetText() );

+

+		element->SetText( 1 );

+		XMLTest( "SetText types", "1", element->GetText() );

+

+		element->SetText( 1U );

+		XMLTest( "SetText types", "1", element->GetText() );

+

+		element->SetText( true );

+		XMLTest( "SetText types", "1", element->GetText() ); // TODO: should be 'true'?

+

+		element->SetText( 1.5f );

+		XMLTest( "SetText types", "1.5", element->GetText() );

+

+		element->SetText( 1.5 );

+		XMLTest( "SetText types", "1.5", element->GetText() );

+	}

+

+

 	// ---------- CDATA ---------------

 	{

 		const char* str =	"<xmlElement>"

@@ -1139,18 +1194,6 @@
 		XMLTest( "Whitespace  all space", true, 0 == doc.FirstChildElement()->FirstChild() );

 	}

 

-#if 0		// the question being explored is what kind of print to use: 

-			// https://github.com/leethomason/tinyxml2/issues/63

-	{

-		const char* xml = "<element attrA='123456789.123456789' attrB='1.001e9'/>";

-		XMLDocument doc;

-		doc.Parse( xml );

-		doc.FirstChildElement()->SetAttribute( "attrA", 123456789.123456789 );

-		doc.FirstChildElement()->SetAttribute( "attrB", 1.001e9 );

-		doc.Print();

-	}

-#endif

-

 	{

 		// An assert should not fire.

 		const char* xml = "<element/>";

@@ -1240,39 +1283,85 @@
 			"</root>";

 

 		XMLDocument doc;

-		doc.Parse( xml );

+		doc.Parse(xml);

 		XMLElement* subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree");

 		XMLElement* two = doc.RootElement()->FirstChildElement("two");

 		two->InsertFirstChild(subtree);

-		XMLPrinter printer1( 0, true );

-		doc.Accept( &printer1 );

-		XMLTest( "Move node from within <one> to <two>", xmlInsideTwo, printer1.CStr());

+		XMLPrinter printer1(0, true);

+		doc.Accept(&printer1);

+		XMLTest("Move node from within <one> to <two>", xmlInsideTwo, printer1.CStr());

 

-		doc.Parse( xml );

+		doc.Parse(xml);

 		subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree");

 		two = doc.RootElement()->FirstChildElement("two");

 		doc.RootElement()->InsertAfterChild(two, subtree);

-		XMLPrinter printer2( 0, true );

-		doc.Accept( &printer2 );

-		XMLTest( "Move node from within <one> after <two>", xmlAfterTwo, printer2.CStr(), false );

+		XMLPrinter printer2(0, true);

+		doc.Accept(&printer2);

+		XMLTest("Move node from within <one> after <two>", xmlAfterTwo, printer2.CStr(), false);

 

-		doc.Parse( xml );

+		doc.Parse(xml);

 		XMLNode* one = doc.RootElement()->FirstChildElement("one");

 		subtree = one->FirstChildElement("subtree");

 		doc.RootElement()->InsertAfterChild(one, subtree);

-		XMLPrinter printer3( 0, true );

-		doc.Accept( &printer3 );

-		XMLTest( "Move node from within <one> after <one>", xmlAfterOne, printer3.CStr(), false );

+		XMLPrinter printer3(0, true);

+		doc.Accept(&printer3);

+		XMLTest("Move node from within <one> after <one>", xmlAfterOne, printer3.CStr(), false);

 

-		doc.Parse( xml );

+		doc.Parse(xml);

 		subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree");

 		two = doc.RootElement()->FirstChildElement("two");

 		doc.RootElement()->InsertEndChild(subtree);

-		XMLPrinter printer4( 0, true );

-		doc.Accept( &printer4 );

-		XMLTest( "Move node from within <one> after <two>", xmlAfterTwo, printer4.CStr(), false );

+		XMLPrinter printer4(0, true);

+		doc.Accept(&printer4);

+		XMLTest("Move node from within <one> after <two>", xmlAfterTwo, printer4.CStr(), false);

 	}

 

+	{

+		const char* xml = "<svg width = \"128\" height = \"128\">"

+			"	<text> </text>"

+			"</svg>";

+		XMLDocument doc;

+		doc.Parse(xml);

+		doc.Print();

+	}

+

+#if 1

+		// the question being explored is what kind of print to use: 

+		// https://github.com/leethomason/tinyxml2/issues/63

+	{

+		//const char* xml = "<element attrA='123456789.123456789' attrB='1.001e9' attrC='1.0e-10' attrD='1001000000.000000' attrE='0.1234567890123456789'/>";

+		const char* xml = "<element/>";

+		XMLDocument doc;

+		doc.Parse( xml );

+		doc.FirstChildElement()->SetAttribute( "attrA-f64", 123456789.123456789 );

+		doc.FirstChildElement()->SetAttribute( "attrB-f64", 1.001e9 );

+		doc.FirstChildElement()->SetAttribute( "attrC-f64", 1.0e9 );

+		doc.FirstChildElement()->SetAttribute( "attrC-f64", 1.0e20 );

+		doc.FirstChildElement()->SetAttribute( "attrD-f64", 1.0e-10 );

+		doc.FirstChildElement()->SetAttribute( "attrD-f64", 0.123456789 );

+

+		doc.FirstChildElement()->SetAttribute( "attrA-f32", 123456789.123456789f );

+		doc.FirstChildElement()->SetAttribute( "attrB-f32", 1.001e9f );

+		doc.FirstChildElement()->SetAttribute( "attrC-f32", 1.0e9f );

+		doc.FirstChildElement()->SetAttribute( "attrC-f32", 1.0e20f );

+		doc.FirstChildElement()->SetAttribute( "attrD-f32", 1.0e-10f );

+		doc.FirstChildElement()->SetAttribute( "attrD-f32", 0.123456789f );

+

+		doc.Print();

+

+		/* The result of this test is platform, compiler, and library version dependent. :("

+		XMLPrinter printer;

+		doc.Print( &printer );

+		XMLTest( "Float and double formatting.", 

+			"<element attrA-f64=\"123456789.12345679\" attrB-f64=\"1001000000\" attrC-f64=\"1e+20\" attrD-f64=\"0.123456789\" attrA-f32=\"1.2345679e+08\" attrB-f32=\"1.001e+09\" attrC-f32=\"1e+20\" attrD-f32=\"0.12345679\"/>\n",

+			printer.CStr(), 

+			true );

+		*/

+	}

+#endif

+

+

+

 	// ----------- Performance tracking --------------

 	{

 #if defined( _MSC_VER )