Skip to content

Commit 357f507

Browse files
committed
Updated tinyxml
1 parent a41a32b commit 357f507

3 files changed

Lines changed: 168 additions & 37 deletions

File tree

externals/tinyxml/tinyxml2.cpp

Lines changed: 77 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -422,16 +422,19 @@ void XMLUtil::ToStr( bool v, char* buffer, int bufferSize )
422422
TIXML_SNPRINTF( buffer, bufferSize, "%d", v ? 1 : 0 );
423423
}
424424

425-
425+
/*
426+
ToStr() of a number is a very tricky topic.
427+
https://github.com/leethomason/tinyxml2/issues/106
428+
*/
426429
void XMLUtil::ToStr( float v, char* buffer, int bufferSize )
427430
{
428-
TIXML_SNPRINTF( buffer, bufferSize, "%f", v );
431+
TIXML_SNPRINTF( buffer, bufferSize, "%.8g", v );
429432
}
430433

431434

432435
void XMLUtil::ToStr( double v, char* buffer, int bufferSize )
433436
{
434-
TIXML_SNPRINTF( buffer, bufferSize, "%f", v );
437+
TIXML_SNPRINTF( buffer, bufferSize, "%.17g", v );
435438
}
436439

437440

@@ -497,12 +500,7 @@ char* XMLDocument::Identify( char* p, XMLNode** node )
497500
}
498501

499502
// What is this thing?
500-
// - Elements start with a letter or underscore, but xml is reserved.
501-
// - Comments: <!--
502-
// - Declaration: <?
503-
// - Everything else is unknown to tinyxml.
504-
//
505-
503+
// These strings define the matching patters:
506504
static const char* xmlHeader = { "<?" };
507505
static const char* commentHeader = { "<!--" };
508506
static const char* dtdHeader = { "<!" };
@@ -1262,6 +1260,57 @@ const char* XMLElement::GetText() const
12621260
}
12631261

12641262

1263+
void XMLElement::SetText( const char* inText )
1264+
{
1265+
if ( FirstChild() && FirstChild()->ToText() )
1266+
FirstChild()->SetValue( inText );
1267+
else {
1268+
XMLText* theText = GetDocument()->NewText( inText );
1269+
InsertFirstChild( theText );
1270+
}
1271+
}
1272+
1273+
1274+
void XMLElement::SetText( int v )
1275+
{
1276+
char buf[BUF_SIZE];
1277+
XMLUtil::ToStr( v, buf, BUF_SIZE );
1278+
SetText( buf );
1279+
}
1280+
1281+
1282+
void XMLElement::SetText( unsigned v )
1283+
{
1284+
char buf[BUF_SIZE];
1285+
XMLUtil::ToStr( v, buf, BUF_SIZE );
1286+
SetText( buf );
1287+
}
1288+
1289+
1290+
void XMLElement::SetText( bool v )
1291+
{
1292+
char buf[BUF_SIZE];
1293+
XMLUtil::ToStr( v, buf, BUF_SIZE );
1294+
SetText( buf );
1295+
}
1296+
1297+
1298+
void XMLElement::SetText( float v )
1299+
{
1300+
char buf[BUF_SIZE];
1301+
XMLUtil::ToStr( v, buf, BUF_SIZE );
1302+
SetText( buf );
1303+
}
1304+
1305+
1306+
void XMLElement::SetText( double v )
1307+
{
1308+
char buf[BUF_SIZE];
1309+
XMLUtil::ToStr( v, buf, BUF_SIZE );
1310+
SetText( buf );
1311+
}
1312+
1313+
12651314
XMLError XMLElement::QueryIntText( int* ival ) const
12661315
{
12671316
if ( FirstChild() && FirstChild()->ToText() ) {
@@ -1639,6 +1688,13 @@ XMLError XMLDocument::LoadFile( FILE* fp )
16391688
{
16401689
Clear();
16411690

1691+
fseek( fp, 0, SEEK_SET );
1692+
fgetc( fp );
1693+
if ( ferror( fp ) != 0 ) {
1694+
SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 );
1695+
return _errorID;
1696+
}
1697+
16421698
fseek( fp, 0, SEEK_END );
16431699
size_t size = ftell( fp );
16441700
fseek( fp, 0, SEEK_SET );
@@ -1702,7 +1758,7 @@ XMLError XMLDocument::Parse( const char* p, size_t len )
17021758
const char* start = p;
17031759
Clear();
17041760

1705-
if ( !p || !*p ) {
1761+
if ( len == 0 || !p || !*p ) {
17061762
SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 );
17071763
return _errorID;
17081764
}
@@ -1884,17 +1940,17 @@ void XMLPrinter::PushHeader( bool writeBOM, bool writeDec )
18841940
}
18851941

18861942

1887-
void XMLPrinter::OpenElement( const char* name )
1943+
void XMLPrinter::OpenElement( const char* name, bool compactMode )
18881944
{
18891945
if ( _elementJustOpened ) {
18901946
SealElement();
18911947
}
18921948
_stack.Push( name );
18931949

1894-
if ( _textDepth < 0 && !_firstElement && !_compactMode ) {
1950+
if ( _textDepth < 0 && !_firstElement && !compactMode ) {
18951951
Print( "\n" );
18961952
}
1897-
if ( !_compactMode ) {
1953+
if ( !compactMode ) {
18981954
PrintSpace( _depth );
18991955
}
19001956

@@ -1946,7 +2002,7 @@ void XMLPrinter::PushAttribute( const char* name, double v )
19462002
}
19472003

19482004

1949-
void XMLPrinter::CloseElement()
2005+
void XMLPrinter::CloseElement( bool compactMode )
19502006
{
19512007
--_depth;
19522008
const char* name = _stack.Pop();
@@ -1955,7 +2011,7 @@ void XMLPrinter::CloseElement()
19552011
Print( "/>" );
19562012
}
19572013
else {
1958-
if ( _textDepth < 0 && !_compactMode) {
2014+
if ( _textDepth < 0 && !compactMode) {
19592015
Print( "\n" );
19602016
PrintSpace( _depth );
19612017
}
@@ -1965,7 +2021,7 @@ void XMLPrinter::CloseElement()
19652021
if ( _textDepth == _depth ) {
19662022
_textDepth = -1;
19672023
}
1968-
if ( _depth == 0 && !_compactMode) {
2024+
if ( _depth == 0 && !compactMode) {
19692025
Print( "\n" );
19702026
}
19712027
_elementJustOpened = false;
@@ -2090,7 +2146,9 @@ bool XMLPrinter::VisitEnter( const XMLDocument& doc )
20902146

20912147
bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute )
20922148
{
2093-
OpenElement( element.Name() );
2149+
const XMLElement* parentElem = element.Parent()->ToElement();
2150+
bool compactMode = parentElem ? CompactMode(*parentElem) : _compactMode;
2151+
OpenElement( element.Name(), compactMode );
20942152
while ( attribute ) {
20952153
PushAttribute( attribute->Name(), attribute->Value() );
20962154
attribute = attribute->Next();
@@ -2099,9 +2157,9 @@ bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attr
20992157
}
21002158

21012159

2102-
bool XMLPrinter::VisitExit( const XMLElement& )
2160+
bool XMLPrinter::VisitExit( const XMLElement& element )
21032161
{
2104-
CloseElement();
2162+
CloseElement( CompactMode(element) );
21052163
return true;
21062164
}
21072165

externals/tinyxml/tinyxml2.h

Lines changed: 81 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,12 @@ inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... )
116116
#define TIXML_SSCANF sscanf
117117
#endif
118118

119-
static const int TIXML2_MAJOR_VERSION = 1;
119+
/* Versioning, past 1.0.14:
120+
http://semver.org/
121+
*/
122+
static const int TIXML2_MAJOR_VERSION = 2;
120123
static const int TIXML2_MINOR_VERSION = 0;
121-
static const int TIXML2_PATCH_VERSION = 12;
124+
static const int TIXML2_PATCH_VERSION = 0;
122125

123126
namespace tinyxml2
124127
{
@@ -216,6 +219,10 @@ class DynArray
216219
}
217220
}
218221

222+
void Clear() {
223+
_size = 0;
224+
}
225+
219226
void Push( T t ) {
220227
EnsureCapacity( _size+1 );
221228
_mem[_size++] = t;
@@ -1317,6 +1324,11 @@ class TINYXML2_LIB XMLElement : public XMLNode
13171324
XMLAttribute* a = FindOrCreateAttribute( name );
13181325
a->SetAttribute( value );
13191326
}
1327+
/// Sets the named attribute to value.
1328+
void SetAttribute( const char* name, float value ) {
1329+
XMLAttribute* a = FindOrCreateAttribute( name );
1330+
a->SetAttribute( value );
1331+
}
13201332

13211333
/**
13221334
Delete an attribute.
@@ -1360,6 +1372,52 @@ class TINYXML2_LIB XMLElement : public XMLNode
13601372
*/
13611373
const char* GetText() const;
13621374

1375+
/** Convenience function for easy access to the text inside an element. Although easy
1376+
and concise, SetText() is limited compared to creating an XMLText child
1377+
and mutating it directly.
1378+
1379+
If the first child of 'this' is a XMLText, SetText() sets its value to
1380+
the given string, otherwise it will create a first child that is an XMLText.
1381+
1382+
This is a convenient method for setting the text of simple contained text:
1383+
@verbatim
1384+
<foo>This is text</foo>
1385+
fooElement->SetText( "Hullaballoo!" );
1386+
<foo>Hullaballoo!</foo>
1387+
@endverbatim
1388+
1389+
Note that this function can be misleading. If the element foo was created from
1390+
this XML:
1391+
@verbatim
1392+
<foo><b>This is text</b></foo>
1393+
@endverbatim
1394+
1395+
then it will not change "This is text", but rather prefix it with a text element:
1396+
@verbatim
1397+
<foo>Hullaballoo!<b>This is text</b></foo>
1398+
@endverbatim
1399+
1400+
For this XML:
1401+
@verbatim
1402+
<foo />
1403+
@endverbatim
1404+
SetText() will generate
1405+
@verbatim
1406+
<foo>Hullaballoo!</foo>
1407+
@endverbatim
1408+
*/
1409+
void SetText( const char* inText );
1410+
/// Convenience method for setting text inside and element. See SetText() for important limitations.
1411+
void SetText( int value );
1412+
/// Convenience method for setting text inside and element. See SetText() for important limitations.
1413+
void SetText( unsigned value );
1414+
/// Convenience method for setting text inside and element. See SetText() for important limitations.
1415+
void SetText( bool value );
1416+
/// Convenience method for setting text inside and element. See SetText() for important limitations.
1417+
void SetText( double value );
1418+
/// Convenience method for setting text inside and element. See SetText() for important limitations.
1419+
void SetText( float value );
1420+
13631421
/**
13641422
Convenience method to query the value of a child text node. This is probably best
13651423
shown by example. Given you have a document is this form:
@@ -1420,6 +1478,7 @@ class TINYXML2_LIB XMLElement : public XMLNode
14201478
//void LinkAttribute( XMLAttribute* attrib );
14211479
char* ParseAttributes( char* p );
14221480

1481+
enum { BUF_SIZE = 200 };
14231482
int _closingType;
14241483
// The attribute list is ordered; there is no 'lastAttribute'
14251484
// because the list needs to be scanned for dupes before adding
@@ -1905,15 +1964,15 @@ class TINYXML2_LIB XMLPrinter : public XMLVisitor
19051964
/** If streaming, start writing an element.
19061965
The element must be closed with CloseElement()
19071966
*/
1908-
void OpenElement( const char* name );
1967+
void OpenElement( const char* name, bool compactMode );
19091968
/// If streaming, add an attribute to an open element.
19101969
void PushAttribute( const char* name, const char* value );
19111970
void PushAttribute( const char* name, int value );
19121971
void PushAttribute( const char* name, unsigned value );
19131972
void PushAttribute( const char* name, bool value );
19141973
void PushAttribute( const char* name, double value );
19151974
/// If streaming, close the Element.
1916-
virtual void CloseElement();
1975+
virtual void CloseElement( bool compactMode );
19171976

19181977
/// Add a text node.
19191978
void PushText( const char* text, bool cdata=false );
@@ -1962,23 +2021,37 @@ class TINYXML2_LIB XMLPrinter : public XMLVisitor
19622021
int CStrSize() const {
19632022
return _buffer.Size();
19642023
}
2024+
/**
2025+
If in print to memory mode, reset the buffer to the
2026+
beginning.
2027+
*/
2028+
void ClearBuffer() {
2029+
_buffer.Clear();
2030+
_buffer.Push(0);
2031+
}
19652032

19662033
protected:
1967-
void SealElement();
2034+
virtual bool CompactMode( const XMLElement& ) { return _compactMode; };
2035+
2036+
/** Prints out the space before an element. You may override to change
2037+
the space and tabs used. A PrintSpace() override should call Print().
2038+
*/
2039+
virtual void PrintSpace( int depth );
2040+
void Print( const char* format, ... );
2041+
2042+
void SealElement();
19682043
bool _elementJustOpened;
19692044
DynArray< const char*, 10 > _stack;
19702045

19712046
private:
1972-
void PrintSpace( int depth );
19732047
void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
1974-
void Print( const char* format, ... );
19752048

19762049
bool _firstElement;
19772050
FILE* _fp;
19782051
int _depth;
19792052
int _textDepth;
19802053
bool _processEntities;
1981-
bool _compactMode;
2054+
bool _compactMode;
19822055

19832056
enum {
19842057
ENTITY_RANGE = 64,

0 commit comments

Comments
 (0)