Merge remote-tracking branch 'origin/master'

This commit is contained in:
Lee Thomason 2014-02-21 22:47:21 -08:00
commit 7de26f7dc7
6 changed files with 273 additions and 53 deletions

View File

@ -10,7 +10,7 @@ include(GNUInstallDirs)
################################ ################################
# set lib version here # set lib version here
set(GENERIC_LIB_VERSION "1.0.12") set(GENERIC_LIB_VERSION "1.0.14")
set(GENERIC_LIB_SOVERSION "1") set(GENERIC_LIB_SOVERSION "1")
@ -53,6 +53,7 @@ if(BUILD_STATIC_LIBS)
endif(BUILD_STATIC_LIBS) endif(BUILD_STATIC_LIBS)
add_library(tinyxml2 SHARED tinyxml2.cpp tinyxml2.h) add_library(tinyxml2 SHARED tinyxml2.cpp tinyxml2.h)
set_target_properties(tinyxml2 PROPERTIES set_target_properties(tinyxml2 PROPERTIES
COMPILE_DEFINITIONS "TINYXML2_EXPORT"
VERSION "${GENERIC_LIB_VERSION}" VERSION "${GENERIC_LIB_VERSION}"
SOVERSION "${GENERIC_LIB_SOVERSION}") SOVERSION "${GENERIC_LIB_SOVERSION}")

2
dox
View File

@ -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 = 1.0.12 PROJECT_NUMBER = 1.0.14
# 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

View File

@ -51,11 +51,10 @@ What it doesn't do.
TinyXML-2 doesn't parse or use DTDs (Document Type Definitions) or XSLs TinyXML-2 doesn't parse or use DTDs (Document Type Definitions) or XSLs
(eXtensible Stylesheet Language.) There are other parsers out there (eXtensible Stylesheet Language.) There are other parsers out there
that are much more fully that are much more fully featured. But they are also much bigger,
featured. But they are also much bigger, take longer to set up in take longer to set up in your project, have a higher learning curve,
your project, have a higher learning curve, and often have a more and often have a more restrictive license. If you are working with
restrictive license. If you are working with browsers or have more browsers or have more complete XML needs, TinyXML-2 is not the parser for you.
complete XML needs, TinyXML-2 is not the parser for you.
TinyXML-1 vs. TinyXML-2 TinyXML-1 vs. TinyXML-2
----------------------- -----------------------
@ -309,8 +308,9 @@ in shaping what is a very successful library. Extra thanks to Yves
Berquin and Andrew Ellerton who were key contributors. Berquin and Andrew Ellerton who were key contributors.
TinyXML-2 grew from that effort. Lee Thomason is the original author 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. 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!

View File

@ -422,16 +422,19 @@ void XMLUtil::ToStr( bool v, char* buffer, int bufferSize )
TIXML_SNPRINTF( buffer, bufferSize, "%d", v ? 1 : 0 ); 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 ) 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 ) 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 @@ 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. // These strings define the matching patters:
// - Comments: <!--
// - Declaration: <?
// - Everything else is unknown to tinyxml.
//
static const char* xmlHeader = { "<?" }; static const char* xmlHeader = { "<?" };
static const char* commentHeader = { "<!--" }; static const char* commentHeader = { "<!--" };
static const char* dtdHeader = { "<!" }; static const char* dtdHeader = { "<!" };
@ -1262,6 +1260,57 @@ const char* XMLElement::GetText() const
} }
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 XMLError XMLElement::QueryIntText( int* ival ) const
{ {
if ( FirstChild() && FirstChild()->ToText() ) { if ( FirstChild() && FirstChild()->ToText() ) {
@ -1639,6 +1688,13 @@ XMLError XMLDocument::LoadFile( FILE* fp )
{ {
Clear(); 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 ); fseek( fp, 0, SEEK_END );
size_t size = ftell( fp ); size_t size = ftell( fp );
fseek( fp, 0, SEEK_SET ); fseek( fp, 0, SEEK_SET );

View File

@ -116,9 +116,15 @@ inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... )
#define TIXML_SSCANF sscanf #define TIXML_SSCANF sscanf
#endif #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_MAJOR_VERSION = 1;
static const int TIXML2_MINOR_VERSION = 0; static const int TIXML2_MINOR_VERSION = 1;
static const int TIXML2_PATCH_VERSION = 12; static const int TIXML2_PATCH_VERSION = 0;
namespace tinyxml2 namespace tinyxml2
{ {
@ -216,6 +222,10 @@ public:
} }
} }
void Clear() {
_size = 0;
}
void Push( T t ) { void Push( T t ) {
EnsureCapacity( _size+1 ); EnsureCapacity( _size+1 );
_mem[_size++] = t; _mem[_size++] = t;
@ -1317,6 +1327,11 @@ public:
XMLAttribute* a = FindOrCreateAttribute( name ); XMLAttribute* a = FindOrCreateAttribute( name );
a->SetAttribute( value ); 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. Delete an attribute.
@ -1360,6 +1375,52 @@ public:
*/ */
const char* GetText() const; 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 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: shown by example. Given you have a document is this form:
@ -1420,6 +1481,7 @@ private:
//void LinkAttribute( XMLAttribute* attrib ); //void LinkAttribute( XMLAttribute* attrib );
char* ParseAttributes( char* p ); char* ParseAttributes( char* p );
enum { BUF_SIZE = 200 };
int _closingType; int _closingType;
// The attribute list is ordered; there is no 'lastAttribute' // The attribute list is ordered; there is no 'lastAttribute'
// because the list needs to be scanned for dupes before adding // because the list needs to be scanned for dupes before adding
@ -1962,16 +2024,28 @@ public:
int CStrSize() const { int CStrSize() const {
return _buffer.Size(); return _buffer.Size();
} }
/**
If in print to memory mode, reset the buffer to the
beginning.
*/
void ClearBuffer() {
_buffer.Clear();
_buffer.Push(0);
}
protected: protected:
/** 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(); void SealElement();
bool _elementJustOpened; bool _elementJustOpened;
DynArray< const char*, 10 > _stack; DynArray< const char*, 10 > _stack;
private: private:
void PrintSpace( int depth );
void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities. void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
void Print( const char* format, ... );
bool _firstElement; bool _firstElement;
FILE* _fp; FILE* _fp;

View File

@ -617,6 +617,61 @@ int main( int argc, const char ** argv )
} }
// --------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 --------------- // ---------- CDATA ---------------
{ {
const char* str = "<xmlElement>" const char* str = "<xmlElement>"
@ -1139,18 +1194,6 @@ int main( int argc, const char ** argv )
XMLTest( "Whitespace all space", true, 0 == doc.FirstChildElement()->FirstChild() ); 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. // An assert should not fire.
const char* xml = "<element/>"; const char* xml = "<element/>";
@ -1273,6 +1316,52 @@ int main( int argc, const char ** argv )
XMLTest("Move node from within <one> after <two>", xmlAfterTwo, printer4.CStr(), false); 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 -------------- // ----------- Performance tracking --------------
{ {
#if defined( _MSC_VER ) #if defined( _MSC_VER )