From: JinWang An Date: Fri, 30 Oct 2020 05:29:39 +0000 (+0900) Subject: Imported Upstream version 4.0.0 X-Git-Tag: upstream/4.0.0^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b75675ffb825ef5d86ad0eafcc046fc8d04d82ea;p=platform%2Fupstream%2Ftinyxml2.git Imported Upstream version 4.0.0 --- diff --git a/.gitignore b/.gitignore index a765577..f5b7e99 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ tinyxml2/tinyxml2-cbp/obj/ *.opensdf *.user *.depend -*.layout \ No newline at end of file +*.layout +*.o diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..50e9a6f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,15 @@ +language: cpp + +os: + - linux + - osx + +compiler: + - g++ + - clang + +before_script: cmake . + +script: + - make -j3 + - ./xmltest diff --git a/CMakeLists.txt b/CMakeLists.txt index 16f2ccd..98d4c55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,10 @@ +IF(BIICODE) + ADD_BIICODE_TARGETS() + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/resources) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/resources DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + ENDIF() + RETURN() +ENDIF(BIICODE) cmake_minimum_required(VERSION 2.6 FATAL_ERROR) cmake_policy(VERSION 2.6) @@ -10,12 +17,12 @@ include(GNUInstallDirs) ################################ # set lib version here -set(GENERIC_LIB_VERSION "3.0.0") -set(GENERIC_LIB_SOVERSION "3") +set(GENERIC_LIB_VERSION "4.0.0") +set(GENERIC_LIB_SOVERSION "4") ################################ -# Add common source +# Add common source include_directories("${CMAKE_CURRENT_SOURCE_DIR}/.") @@ -23,19 +30,20 @@ include_directories("${CMAKE_CURRENT_SOURCE_DIR}/.") # Add custom target to copy all data set(TARGET_DATA_COPY DATA_COPY) -if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) - add_custom_target( - ${TARGET_DATA_COPY} - COMMAND ${CMAKE_COMMAND} -E echo "In source build") -else(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) - make_directory(${CMAKE_CURRENT_BINARY_DIR}/resources/) - add_custom_target( - ${TARGET_DATA_COPY} - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/resources/dream.xml ${CMAKE_CURRENT_BINARY_DIR}/resources/ - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/resources/empty.xml ${CMAKE_CURRENT_BINARY_DIR}/resources/ - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/resources/utf8test.xml ${CMAKE_CURRENT_BINARY_DIR}/resources/ - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/resources/utf8testverify.xml ${CMAKE_CURRENT_BINARY_DIR}/resources/) -endif(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) +set(DATA_COPY_FILES) +if(NOT ${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) + foreach(data dream.xml empty.xml utf8test.xml utf8testverify.xml) + set(DATA_COPY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/resources/${data}) + set(DATA_COPY_DEST ${CMAKE_CURRENT_BINARY_DIR}/resources/${data}) + add_custom_command( + OUTPUT ${DATA_COPY_DEST} + COMMAND ${CMAKE_COMMAND} + ARGS -E copy ${DATA_COPY_SRC} ${DATA_COPY_DEST} + DEPENDS ${DATA_COPY_SRC}) + list(APPEND DATA_COPY_FILES ${DATA_COPY_DEST}) + endforeach(data) +endif(NOT ${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) +add_custom_target(${TARGET_DATA_COPY} DEPENDS ${DATA_COPY_FILES}) ################################ # Add definitions @@ -44,25 +52,65 @@ if(MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) endif(MSVC) +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") + ################################ # Add targets -option(BUILD_SHARED_LIBS "build shared or static libraries" ON) -add_library(tinyxml2 tinyxml2.cpp tinyxml2.h) +# By Default shared libray is being built +# To build static libs also - Do cmake . -DBUILD_STATIC_LIBS:BOOL=ON +# User can choose not to build shared library by using cmake -BUILD_SHARED_LIBS:BOOL:OFF +# To build only static libs use cmake . -DBUILD_SHARED_LIBS:BOOL=OFF -DBUILD_STATIC_LIBS:BOOL=ON + +option(BUILD_SHARED_LIBS "build as shared library" ON) +option(BUILD_STATIC_LIBS "build as static library" OFF) + +if(BUILD_SHARED_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}") -add_executable(xmltest xmltest.cpp) -add_dependencies(xmltest tinyxml2) -add_dependencies(xmltest ${TARGET_DATA_COPY}) -target_link_libraries(xmltest tinyxml2) - +if(DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11") + target_include_directories(tinyxml2 INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/.") +endif() install(TARGETS tinyxml2 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + +if(BUILD_STATIC_LIBS) +add_library(tinyxml2_static STATIC tinyxml2.cpp tinyxml2.h) +set_target_properties(tinyxml2_static PROPERTIES + COMPILE_DEFINITONS "TINYXML2_EXPORT" + VERSION "${GENERIC_LIB_VERSION}" + SOVERSION "${GENERIC_LIB_SOVERSION}") +set_target_properties( tinyxml2_static PROPERTIES OUTPUT_NAME tinyxml2 ) + +if(DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11") + target_include_directories(tinyxml2_static INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/.") +endif() + +install(TARGETS tinyxml2_static + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + +add_executable(xmltest xmltest.cpp) +if(BUILD_SHARED_LIBS) + add_dependencies(xmltest tinyxml2) + add_dependencies(xmltest ${TARGET_DATA_COPY}) + target_link_libraries(xmltest tinyxml2) +else(BUILD_STATIC_LIBS) + add_dependencies(xmltest tinyxml2_static) + add_dependencies(xmltest ${TARGET_DATA_COPY}) + target_link_libraries(xmltest tinyxml2_static) +endif() +install(TARGETS DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES tinyxml2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) @@ -77,3 +125,12 @@ configure_file(tinyxml2.pc.in tinyxml2.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tinyxml2.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) #add_test(xmltest ${SAMPLE_NAME} COMMAND $) + +# uninstall target +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) + +add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) diff --git a/Makefile b/Makefile index aab6293..eba6fef 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,19 @@ -all: xmltest -xmltest: xmltest.cpp tinyxml2.cpp tinyxml2.h +all: xmltest staticlib + +rebuild: clean all + +xmltest: xmltest.cpp libtinyxml2.a + +clean: + $(RM) *.o xmltest libtinyxml2.a + test: clean xmltest ./xmltest -clean: - rm -f *.o xmltest + +staticlib: libtinyxml2.a + +libtinyxml2.a: tinyxml2.o + $(AR) $(ARFLAGS)s $@ $^ + +tinyxml2.o: tinyxml2.cpp tinyxml2.h + diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..aac8867 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,7 @@ +before_build: + - cmake . + +build_script: + - msbuild tinyxml2.sln /m /p:Configuration=Release /t:ALL_BUILD + - copy Release\xmltest.exe .\ && copy Release\tinyxml2.dll .\ + - xmltest.exe diff --git a/biicode.conf b/biicode.conf new file mode 100644 index 0000000..5dca6b1 --- /dev/null +++ b/biicode.conf @@ -0,0 +1,7 @@ +# Biicode configuration file + +[paths] + / + +[dependencies] + xmltest.cpp + resources/*.xml \ No newline at end of file diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in new file mode 100644 index 0000000..2c34c81 --- /dev/null +++ b/cmake_uninstall.cmake.in @@ -0,0 +1,21 @@ +if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") +endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif(NOT "${rm_retval}" STREQUAL 0) + else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") +endforeach(file) \ No newline at end of file diff --git a/contrib/html5-printer.cpp b/contrib/html5-printer.cpp index 3205ccd..7728b69 100644 --- a/contrib/html5-printer.cpp +++ b/contrib/html5-printer.cpp @@ -65,7 +65,7 @@ public: protected: virtual void CloseElement () { if (_elementJustOpened && !isVoidElement (_stack.PeekTop())) { - SealElement(); + SealElementIfJustOpened(); } XMLPrinter::CloseElement(); } diff --git a/dox b/dox index 7c3cd78..5ae0b21 100644 --- a/dox +++ b/dox @@ -38,7 +38,7 @@ PROJECT_NAME = "TinyXML-2" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 3.0.0 +PROJECT_NUMBER = 4.0.0 # 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 a diff --git a/readme.md b/readme.md index 485e00f..82c6ce9 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -TinyXML-2 +TinyXML-2 [![TravisCI Status](https://travis-ci.org/leethomason/tinyxml2.svg?branch=master)](https://travis-ci.org/leethomason/tinyxml2) [![AppVeyor Status](https://ci.appveyor.com/api/projects/status/github/leethomason/tinyxml2?branch=master&svg=true)](https://ci.appveyor.com/project/leethomason/tinyxml2) ========= ![TinyXML-2 Logo](http://www.grinninglizard.com/tinyxml2/TinyXML2_small.png) @@ -177,7 +177,7 @@ 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. Additionally, any character can be specified by its Unicode code point: -The syntax " " or " " are both to the non-breaking space characher. +The syntax ` ` or ` ` are both to the non-breaking space character. This is called a 'numeric character reference'. Any numeric character reference that isn't one of the special entities above, will be read, but written as a regular code point. The output is correct, but the entity syntax isn't preserved. @@ -264,8 +264,8 @@ There are 2 files in TinyXML-2: And additionally a test file: * xmltest.cpp -Simply compile and run. There is a visual studio 2010 project included, a simple Makefile, -an XCode project, a Code::Blocks project, and a cmake CMakeLists.txt included to help you. +Simply compile and run. There is a visual studio 2015 project included, a simple Makefile, +an Xcode project, a Code::Blocks project, and a cmake CMakeLists.txt included to help you. The top of tinyxml.h even has a simple g++ command line if you are are *nix and don't want to use a build system. diff --git a/tinyxml2.cpp b/tinyxml2.cpp index 6d8573b..d5d8ebb 100755 --- a/tinyxml2.cpp +++ b/tinyxml2.cpp @@ -24,12 +24,83 @@ distribution. #include "tinyxml2.h" #include // yes, this one new style header, is in the Android SDK. -#if defined(ANDROID_NDK) || defined(__QNXNTO__) +#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__) # include +# include #else # include +# include #endif +#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE) + // Microsoft Visual Studio, version 2005 and higher. Not WinCE. + /*int _snprintf_s( + char *buffer, + size_t sizeOfBuffer, + size_t count, + const char *format [, + argument] ... + );*/ + static inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) + { + va_list va; + va_start( va, format ); + int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); + va_end( va ); + return result; + } + + static inline int TIXML_VSNPRINTF( char* buffer, size_t size, const char* format, va_list va ) + { + int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); + return result; + } + + #define TIXML_VSCPRINTF _vscprintf + #define TIXML_SSCANF sscanf_s +#elif defined _MSC_VER + // Microsoft Visual Studio 2003 and earlier or WinCE + #define TIXML_SNPRINTF _snprintf + #define TIXML_VSNPRINTF _vsnprintf + #define TIXML_SSCANF sscanf + #if (_MSC_VER < 1400 ) && (!defined WINCE) + // Microsoft Visual Studio 2003 and not WinCE. + #define TIXML_VSCPRINTF _vscprintf // VS2003's C runtime has this, but VC6 C runtime or WinCE SDK doesn't have. + #else + // Microsoft Visual Studio 2003 and earlier or WinCE. + static inline int TIXML_VSCPRINTF( const char* format, va_list va ) + { + int len = 512; + for (;;) { + len = len*2; + char* str = new char[len](); + const int required = _vsnprintf(str, len, format, va); + delete[] str; + if ( required != -1 ) { + TIXMLASSERT( required >= 0 ); + len = required; + break; + } + } + TIXMLASSERT( len >= 0 ); + return len; + } + #endif +#else + // GCC version 3 and higher + //#warning( "Using sn* functions." ) + #define TIXML_SNPRINTF snprintf + #define TIXML_VSNPRINTF vsnprintf + static inline int TIXML_VSCPRINTF( const char* format, va_list va ) + { + int len = vsnprintf( 0, 0, format, va ); + TIXMLASSERT( len >= 0 ); + return len; + } + #define TIXML_SSCANF sscanf +#endif + + static const char LINE_FEED = (char)0x0a; // all line endings are normalized to LF static const char LF = LINE_FEED; static const char CARRIAGE_RETURN = (char)0x0d; // CR gets filtered out @@ -106,8 +177,10 @@ void StrPair::Reset() void StrPair::SetStr( const char* str, int flags ) { + TIXMLASSERT( str ); Reset(); size_t len = strlen( str ); + TIXMLASSERT( _start == 0 ); _start = new char[ len+1 ]; memcpy( _start, str, len+1 ); _end = _start + len; @@ -243,8 +316,8 @@ const char* StrPair::GetStr() } } else { - int i=0; - for(; i= 0 && digit < 16); const unsigned int digitScaled = mult * digit; TIXMLASSERT( ucs <= ULONG_MAX - digitScaled ); ucs += digitScaled; @@ -427,6 +501,7 @@ const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length ) while ( *q != '#' ) { if ( *q >= '0' && *q <= '9' ) { const unsigned int digit = *q - '0'; + TIXMLASSERT( digit < 10 ); TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit ); const unsigned int digitScaled = mult * digit; TIXMLASSERT( ucs <= ULONG_MAX - digitScaled ); @@ -481,6 +556,12 @@ void XMLUtil::ToStr( double v, char* buffer, int bufferSize ) } +void XMLUtil::ToStr(int64_t v, char* buffer, int bufferSize) +{ + TIXML_SNPRINTF(buffer, bufferSize, "%lld", v); +} + + bool XMLUtil::ToInt( const char* str, int* value ) { if ( TIXML_SSCANF( str, "%d", value ) == 1 ) { @@ -524,6 +605,7 @@ bool XMLUtil::ToFloat( const char* str, float* value ) return false; } + bool XMLUtil::ToDouble( const char* str, double* value ) { if ( TIXML_SSCANF( str, "%lf", value ) == 1 ) { @@ -533,6 +615,15 @@ bool XMLUtil::ToDouble( const char* str, double* value ) } +bool XMLUtil::ToInt64(const char* str, int64_t* value) +{ + if (TIXML_SSCANF(str, "%lld", value) == 1) { + return true; + } + return false; +} + + char* XMLDocument::Identify( char* p, XMLNode** node ) { TIXMLASSERT( node ); @@ -545,18 +636,17 @@ char* XMLDocument::Identify( char* p, XMLNode** node ) return p; } - // What is this thing? - // These strings define the matching patters: + // These strings define the matching patterns: static const char* xmlHeader = { "ToDocument() ) + return 0; return _value.GetStr(); } @@ -661,6 +755,7 @@ void XMLNode::SetValue( const char* str, bool staticMem ) void XMLNode::DeleteChildren() { while( _firstChild ) { + TIXMLASSERT( _lastChild ); TIXMLASSERT( _firstChild->_document == _document ); XMLNode* node = _firstChild; Unlink( node ); @@ -675,6 +770,7 @@ void XMLNode::Unlink( XMLNode* child ) { TIXMLASSERT( child ); TIXMLASSERT( child->_document == _document ); + TIXMLASSERT( child->_parent == this ); if ( child == _firstChild ) { _firstChild = _firstChild->_next; } @@ -697,6 +793,7 @@ void XMLNode::DeleteChild( XMLNode* node ) TIXMLASSERT( node ); TIXMLASSERT( node->_document == _document ); TIXMLASSERT( node->_parent == this ); + Unlink( node ); DeleteNode( node ); } @@ -793,12 +890,12 @@ XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ) -const XMLElement* XMLNode::FirstChildElement( const char* value ) const +const XMLElement* XMLNode::FirstChildElement( const char* name ) const { - for( XMLNode* node=_firstChild; node; node=node->_next ) { - XMLElement* element = node->ToElement(); + for( const XMLNode* node = _firstChild; node; node = node->_next ) { + const XMLElement* element = node->ToElement(); if ( element ) { - if ( !value || XMLUtil::StringEqual( element->Name(), value ) ) { + if ( !name || XMLUtil::StringEqual( element->Name(), name ) ) { return element; } } @@ -807,12 +904,12 @@ const XMLElement* XMLNode::FirstChildElement( const char* value ) const } -const XMLElement* XMLNode::LastChildElement( const char* value ) const +const XMLElement* XMLNode::LastChildElement( const char* name ) const { - for( XMLNode* node=_lastChild; node; node=node->_prev ) { - XMLElement* element = node->ToElement(); + for( const XMLNode* node = _lastChild; node; node = node->_prev ) { + const XMLElement* element = node->ToElement(); if ( element ) { - if ( !value || XMLUtil::StringEqual( element->Name(), value ) ) { + if ( !name || XMLUtil::StringEqual( element->Name(), name ) ) { return element; } } @@ -821,12 +918,12 @@ const XMLElement* XMLNode::LastChildElement( const char* value ) const } -const XMLElement* XMLNode::NextSiblingElement( const char* value ) const +const XMLElement* XMLNode::NextSiblingElement( const char* name ) const { - for( XMLNode* node=this->_next; node; node = node->_next ) { + for( const XMLNode* node = _next; node; node = node->_next ) { const XMLElement* element = node->ToElement(); if ( element - && (!value || XMLUtil::StringEqual( value, node->Value() ))) { + && (!name || XMLUtil::StringEqual( name, element->Name() ))) { return element; } } @@ -834,12 +931,12 @@ const XMLElement* XMLNode::NextSiblingElement( const char* value ) const } -const XMLElement* XMLNode::PreviousSiblingElement( const char* value ) const +const XMLElement* XMLNode::PreviousSiblingElement( const char* name ) const { - for( XMLNode* node=_prev; node; node = node->_prev ) { + for( const XMLNode* node = _prev; node; node = node->_prev ) { const XMLElement* element = node->ToElement(); if ( element - && (!value || XMLUtil::StringEqual( value, node->Value() ))) { + && (!name || XMLUtil::StringEqual( name, element->Name() ))) { return element; } } @@ -884,6 +981,17 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEnd ) break; } + XMLDeclaration* decl = node->ToDeclaration(); + if ( decl ) { + // A declaration can only be the first child of a document. + // Set error, if document already has children. + if ( !_document->NoChildren() ) { + _document->SetError( XML_ERROR_PARSING_DECLARATION, decl->Value(), 0); + DeleteNode( decl ); + break; + } + } + XMLElement* ele = node->ToElement(); if ( ele ) { // We read the end tag. Return it to the parent. @@ -908,12 +1016,12 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEnd ) if ( ele->ClosingType() != XMLElement::OPEN ) { mismatch = true; } - else if ( !XMLUtil::StringEqual( endTag.GetStr(), node->Value() ) ) { + else if ( !XMLUtil::StringEqual( endTag.GetStr(), ele->Name() ) ) { mismatch = true; } } if ( mismatch ) { - _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); + _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, ele->Name(), 0 ); DeleteNode( node ); break; } @@ -958,7 +1066,7 @@ char* XMLText::ParseDeep( char* p, StrPair* ) else { int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES; if ( _document->WhitespaceMode() == COLLAPSE_WHITESPACE ) { - flags |= StrPair::COLLAPSE_WHITESPACE; + flags |= StrPair::NEEDS_WHITESPACE_COLLAPSING; } p = _value.ParseText( p, "<", flags ); @@ -1195,7 +1303,7 @@ void XMLAttribute::SetName( const char* n ) XMLError XMLAttribute::QueryIntValue( int* value ) const { if ( XMLUtil::ToInt( Value(), value )) { - return XML_NO_ERROR; + return XML_SUCCESS; } return XML_WRONG_ATTRIBUTE_TYPE; } @@ -1204,16 +1312,25 @@ XMLError XMLAttribute::QueryIntValue( int* value ) const XMLError XMLAttribute::QueryUnsignedValue( unsigned int* value ) const { if ( XMLUtil::ToUnsigned( Value(), value )) { - return XML_NO_ERROR; + return XML_SUCCESS; } return XML_WRONG_ATTRIBUTE_TYPE; } +XMLError XMLAttribute::QueryInt64Value(int64_t* value) const +{ + if (XMLUtil::ToInt64(Value(), value)) { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + XMLError XMLAttribute::QueryBoolValue( bool* value ) const { if ( XMLUtil::ToBool( Value(), value )) { - return XML_NO_ERROR; + return XML_SUCCESS; } return XML_WRONG_ATTRIBUTE_TYPE; } @@ -1222,7 +1339,7 @@ XMLError XMLAttribute::QueryBoolValue( bool* value ) const XMLError XMLAttribute::QueryFloatValue( float* value ) const { if ( XMLUtil::ToFloat( Value(), value )) { - return XML_NO_ERROR; + return XML_SUCCESS; } return XML_WRONG_ATTRIBUTE_TYPE; } @@ -1231,7 +1348,7 @@ XMLError XMLAttribute::QueryFloatValue( float* value ) const XMLError XMLAttribute::QueryDoubleValue( double* value ) const { if ( XMLUtil::ToDouble( Value(), value )) { - return XML_NO_ERROR; + return XML_SUCCESS; } return XML_WRONG_ATTRIBUTE_TYPE; } @@ -1259,6 +1376,15 @@ void XMLAttribute::SetAttribute( unsigned v ) } +void XMLAttribute::SetAttribute(int64_t v) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + _value.SetStr(buf); +} + + + void XMLAttribute::SetAttribute( bool v ) { char buf[BUF_SIZE]; @@ -1359,7 +1485,15 @@ void XMLElement::SetText( unsigned v ) } -void XMLElement::SetText( bool v ) +void XMLElement::SetText(int64_t 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 ); @@ -1409,6 +1543,19 @@ XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const } +XMLError XMLElement::QueryInt64Text(int64_t* ival) const +{ + if (FirstChild() && FirstChild()->ToText()) { + const char* t = FirstChild()->Value(); + if (XMLUtil::ToInt64(t, ival)) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + XMLError XMLElement::QueryBoolText( bool* bval ) const { if ( FirstChild() && FirstChild()->ToText() ) { @@ -1536,15 +1683,15 @@ char* XMLElement::ParseAttributes( char* p ) prevAttribute = attrib; } // end of the tag - else if ( *p == '/' && *(p+1) == '>' ) { - _closingType = CLOSED; - return p+2; // done; sealed element. - } - // end of the tag else if ( *p == '>' ) { ++p; break; } + // end of the tag + else if ( *p == '/' && *(p+1) == '>' ) { + _closingType = CLOSED; + return p+2; // done; sealed element. + } else { _document->SetError( XML_ERROR_PARSING_ELEMENT, start, p ); return 0; @@ -1613,7 +1760,7 @@ bool XMLElement::ShallowEqual( const XMLNode* compare ) const { TIXMLASSERT( compare ); const XMLElement* other = compare->ToElement(); - if ( other && XMLUtil::StringEqual( other->Value(), Value() )) { + if ( other && XMLUtil::StringEqual( other->Name(), Name() )) { const XMLAttribute* a=FirstAttribute(); const XMLAttribute* b=other->FirstAttribute(); @@ -1680,13 +1827,14 @@ XMLDocument::XMLDocument( bool processEntities, Whitespace whitespace ) : XMLNode( 0 ), _writeBOM( false ), _processEntities( processEntities ), - _errorID( XML_NO_ERROR ), + _errorID(XML_SUCCESS), _whitespace( whitespace ), _errorStr1( 0 ), _errorStr2( 0 ), _charBuffer( 0 ) { - _document = this; // avoid warning about 'this' in initializer list + // avoid VC++ C4355 warning about 'this' in initializer list (C4355 is off by default in VS2012+) + _document = this; } @@ -1703,7 +1851,7 @@ void XMLDocument::Clear() #ifdef DEBUG const bool hadError = Error(); #endif - _errorID = XML_NO_ERROR; + _errorID = XML_SUCCESS; _errorStr1 = 0; _errorStr2 = 0; @@ -1824,6 +1972,28 @@ XMLError XMLDocument::LoadFile( const char* filename ) return _errorID; } +// This is likely overengineered template art to have a check that unsigned long value incremented +// by one still fits into size_t. If size_t type is larger than unsigned long type +// (x86_64-w64-mingw32 target) then the check is redundant and gcc and clang emit +// -Wtype-limits warning. This piece makes the compiler select code with a check when a check +// is useful and code with no check when a check is redundant depending on how size_t and unsigned long +// types sizes relate to each other. +template += sizeof(size_t))> +struct LongFitsIntoSizeTMinusOne { + static bool Fits( unsigned long value ) + { + return value < (size_t)-1; + } +}; + +template <> +struct LongFitsIntoSizeTMinusOne { + static bool Fits( unsigned long ) + { + return true; + } +}; XMLError XMLDocument::LoadFile( FILE* fp ) { @@ -1842,13 +2012,21 @@ XMLError XMLDocument::LoadFile( FILE* fp ) SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); return _errorID; } + TIXMLASSERT( filelength >= 0 ); - const size_t size = filelength; - if ( size == 0 ) { + if ( !LongFitsIntoSizeTMinusOne<>::Fits( filelength ) ) { + // Cannot handle files which won't fit in buffer together with null terminator + SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); + return _errorID; + } + + if ( filelength == 0 ) { SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); return _errorID; } + const size_t size = filelength; + TIXMLASSERT( _charBuffer == 0 ); _charBuffer = new char[size+1]; size_t read = fread( _charBuffer, 1, size, fp ); if ( read != size ) { @@ -1878,6 +2056,9 @@ XMLError XMLDocument::SaveFile( const char* filename, bool compact ) XMLError XMLDocument::SaveFile( FILE* fp, bool compact ) { + // Clear any error from the last save, otherwise it will get reported + // for *this* call. + SetError(XML_SUCCESS, 0, 0); XMLPrinter stream( fp, compact ); Print( &stream ); return _errorID; @@ -1895,6 +2076,7 @@ XMLError XMLDocument::Parse( const char* p, size_t len ) if ( len == (size_t)(-1) ) { len = strlen( p ); } + TIXMLASSERT( _charBuffer == 0 ); _charBuffer = new char[ len+1 ]; memcpy( _charBuffer, p, len ); _charBuffer[len] = 0; @@ -1916,11 +2098,13 @@ XMLError XMLDocument::Parse( const char* p, size_t len ) void XMLDocument::Print( XMLPrinter* streamer ) const { - XMLPrinter stdStreamer( stdout ); - if ( !streamer ) { - streamer = &stdStreamer; + if ( streamer ) { + Accept( streamer ); + } + else { + XMLPrinter stdoutStreamer( stdout ); + Accept( &stdoutStreamer ); } - Accept( streamer ); } @@ -1935,7 +2119,9 @@ void XMLDocument::SetError( XMLError error, const char* str1, const char* str2 ) const char* XMLDocument::ErrorName() const { TIXMLASSERT( _errorID >= 0 && _errorID < XML_ERROR_COUNT ); - return _errorNames[_errorID]; + const char* errorName = _errorNames[_errorID]; + TIXMLASSERT( errorName && errorName[0] ); + return errorName; } void XMLDocument::PrintError() const @@ -1952,8 +2138,11 @@ void XMLDocument::PrintError() const TIXML_SNPRINTF( buf2, LEN, "%s", _errorStr2 ); } + // Should check INT_MIN <= _errorID && _errorId <= INT_MAX, but that + // causes a clang "always true" -Wtautological-constant-out-of-range-compare warning + TIXMLASSERT( 0 <= _errorID && XML_ERROR_COUNT - 1 <= INT_MAX ); printf( "XMLDocument error id=%d '%s' str1=%s str2=%s\n", - _errorID, ErrorName(), buf1, buf2 ); + static_cast( _errorID ), ErrorName(), buf1, buf2 ); } } @@ -2005,35 +2194,14 @@ void XMLPrinter::Print( const char* format, ... ) vfprintf( _fp, format, va ); } else { -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - #if defined(WINCE) - int len = 512; - do { - len = len*2; - char* str = new char[len](); - len = _vsnprintf(str, len, format, va); - delete[] str; - }while (len < 0); - #else - int len = _vscprintf( format, va ); - #endif -#else - int len = vsnprintf( 0, 0, format, va ); -#endif + const int len = TIXML_VSCPRINTF( format, va ); // Close out and re-start the va-args va_end( va ); + TIXMLASSERT( len >= 0 ); va_start( va, format ); TIXMLASSERT( _buffer.Size() > 0 && _buffer[_buffer.Size() - 1] == 0 ); char* p = _buffer.PushArr( len ) - 1; // back up over the null terminator. -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - #if defined(WINCE) - _vsnprintf( p, len+1, format, va ); - #else - vsnprintf_s( p, len+1, _TRUNCATE, format, va ); - #endif -#else - vsnprintf( p, len+1, format, va ); -#endif + TIXML_VSNPRINTF( p, len+1, format, va ); } va_end( va ); } @@ -2055,6 +2223,7 @@ void XMLPrinter::PrintString( const char* p, bool restricted ) if ( _processEntities ) { const bool* flag = restricted ? _restrictedEntityFlag : _entityFlag; while ( *q ) { + TIXMLASSERT( p <= 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 @@ -2062,24 +2231,35 @@ void XMLPrinter::PrintString( const char* p, bool restricted ) // entity, and keep looking. if ( flag[(unsigned char)(*q)] ) { while ( p < q ) { - Print( "%c", *p ); - ++p; + const size_t delta = q - p; + // %.*s accepts type int as "precision" + const int toPrint = ( INT_MAX < delta ) ? INT_MAX : (int)delta; + Print( "%.*s", toPrint, p ); + p += toPrint; } + bool entityPatternPrinted = false; for( int i=0; i 0) ) { + TIXMLASSERT( p <= q ); + if ( !_processEntities || ( p < q ) ) { Print( "%s", p ); } } @@ -2141,6 +2321,14 @@ void XMLPrinter::PushAttribute( const char* name, unsigned v ) } +void XMLPrinter::PushAttribute(const char* name, int64_t v) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + PushAttribute(name, buf); +} + + void XMLPrinter::PushAttribute( const char* name, bool v ) { char buf[BUF_SIZE]; @@ -2199,9 +2387,7 @@ void XMLPrinter::PushText( const char* text, bool cdata ) SealElementIfJustOpened(); if ( cdata ) { - Print( "" ); + Print( "", text ); } else { PrintString( text, true ); @@ -2296,8 +2482,11 @@ bool XMLPrinter::VisitEnter( const XMLDocument& doc ) bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute ) { - const XMLElement* parentElem = element.Parent()->ToElement(); - bool compactMode = parentElem ? CompactMode(*parentElem) : _compactMode; + const XMLElement* parentElem = 0; + if ( element.Parent() ) { + parentElem = element.Parent()->ToElement(); + } + const bool compactMode = parentElem ? CompactMode( *parentElem ) : _compactMode; OpenElement( element.Name(), compactMode ); while ( attribute ) { PushAttribute( attribute->Name(), attribute->Value() ); diff --git a/tinyxml2.h b/tinyxml2.h index a6da2ec..9dcc345 100755 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -30,15 +30,17 @@ distribution. # include # include # include -# include +# if defined(__PS3__) +# include +# endif #else # include # include # include # include # include -# include #endif +#include /* TODO: intern strings instead of allocation. @@ -78,7 +80,7 @@ distribution. #if defined(DEBUG) # if defined(_MSC_VER) # // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like -# define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); } //if ( !(x)) WinDebugBreak() +# define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); } # elif defined (ANDROID_NDK) # include # define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); } @@ -86,45 +88,17 @@ distribution. # include # define TIXMLASSERT assert # endif -# else -# define TIXMLASSERT( x ) {} -#endif - - -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE) -// Microsoft visual studio, version 2005 and higher. -/*int _snprintf_s( - char *buffer, - size_t sizeOfBuffer, - size_t count, - const char *format [, - argument] ... -);*/ -inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) -{ - va_list va; - va_start( va, format ); - int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); - va_end( va ); - return result; -} -#define TIXML_SSCANF sscanf_s -#elif defined WINCE -#define TIXML_SNPRINTF _snprintf -#define TIXML_SSCANF sscanf #else -// GCC version 3 and higher -//#warning( "Using sn* functions." ) -#define TIXML_SNPRINTF snprintf -#define TIXML_SSCANF sscanf +# define TIXMLASSERT( x ) {} #endif + /* Versioning, past 1.0.14: http://semver.org/ */ -static const int TIXML2_MAJOR_VERSION = 3; -static const int TIXML2_MINOR_VERSION = 0; -static const int TIXML2_PATCH_VERSION = 0; +static const int TIXML2_MAJOR_VERSION = 4; +static const int TIXML2_MINOR_VERSION = 0; +static const int TIXML2_PATCH_VERSION = 0; namespace tinyxml2 { @@ -149,7 +123,7 @@ public: enum { NEEDS_ENTITY_PROCESSING = 0x01, NEEDS_NEWLINE_NORMALIZATION = 0x02, - COLLAPSE_WHITESPACE = 0x04, + NEEDS_WHITESPACE_COLLAPSING = 0x04, TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, @@ -196,7 +170,6 @@ private: NEEDS_DELETE = 0x200 }; - // After parsing, if *_end != 0, it can be set to zero. int _flags; char* _start; char* _end; @@ -211,13 +184,13 @@ private: Has a small initial memory pool, so that low or no usage will not cause a call to new/delete */ -template +template class DynArray { public: DynArray() { _mem = _pool; - _allocated = INIT; + _allocated = INITIAL_SIZE; _size = 0; } @@ -281,14 +254,17 @@ public: } int Capacity() const { + TIXMLASSERT( _allocated >= INITIAL_SIZE ); return _allocated; } const T* Mem() const { + TIXMLASSERT( _mem ); return _mem; } T* Mem() { + TIXMLASSERT( _mem ); return _mem; } @@ -312,7 +288,7 @@ private: } T* _mem; - T _pool[INIT]; + T _pool[INITIAL_SIZE]; int _allocated; // objects allocated int _size; // number objects in use }; @@ -513,7 +489,6 @@ public: // WARNING: must match XMLDocument::_errorNames[] enum XMLError { XML_SUCCESS = 0, - XML_NO_ERROR = 0, XML_NO_ATTRIBUTE, XML_WRONG_ATTRIBUTE_TYPE, XML_ERROR_FILE_NOT_FOUND, @@ -584,19 +559,10 @@ public: if ( p == q ) { return true; } - int n = 0; - while( *p && *q && *p == *q && n(const_cast(this)->FirstChildElement( value )); + XMLElement* FirstChildElement( const char* name = 0 ) { + return const_cast(const_cast(this)->FirstChildElement( name )); } /// Get the last child node, or null if none exists. @@ -760,16 +730,16 @@ public: } XMLNode* LastChild() { - return const_cast(const_cast(this)->LastChild() ); + return _lastChild; } /** Get the last child element or optionally the last child element with the specified name. */ - const XMLElement* LastChildElement( const char* value=0 ) const; + const XMLElement* LastChildElement( const char* name = 0 ) const; - XMLElement* LastChildElement( const char* value=0 ) { - return const_cast(const_cast(this)->LastChildElement(value) ); + XMLElement* LastChildElement( const char* name = 0 ) { + return const_cast(const_cast(this)->LastChildElement(name) ); } /// Get the previous (left) sibling node of this node. @@ -782,10 +752,10 @@ public: } /// Get the previous (left) sibling element of this node, with an optionally supplied name. - const XMLElement* PreviousSiblingElement( const char* value=0 ) const ; + const XMLElement* PreviousSiblingElement( const char* name = 0 ) const ; - XMLElement* PreviousSiblingElement( const char* value=0 ) { - return const_cast(const_cast(this)->PreviousSiblingElement( value ) ); + XMLElement* PreviousSiblingElement( const char* name = 0 ) { + return const_cast(const_cast(this)->PreviousSiblingElement( name ) ); } /// Get the next (right) sibling node of this node. @@ -798,10 +768,10 @@ public: } /// Get the next (right) sibling element of this node, with an optionally supplied name. - const XMLElement* NextSiblingElement( const char* value=0 ) const; + const XMLElement* NextSiblingElement( const char* name = 0 ) const; - XMLElement* NextSiblingElement( const char* value=0 ) { - return const_cast(const_cast(this)->NextSiblingElement( value ) ); + XMLElement* NextSiblingElement( const char* name = 0 ) { + return const_cast(const_cast(this)->NextSiblingElement( name ) ); } /** @@ -887,13 +857,26 @@ public: */ virtual bool Accept( XMLVisitor* visitor ) const = 0; - // internal - virtual char* ParseDeep( char*, StrPair* ); + /** + Set user data into the XMLNode. TinyXML-2 in + no way processes or interprets user data. + It is initially 0. + */ + void SetUserData(void* userData) { _userData = userData; } + + /** + Get user data set into the XMLNode. TinyXML-2 in + no way processes or interprets user data. + It is initially 0. + */ + void* GetUserData() const { return _userData; } protected: XMLNode( XMLDocument* ); virtual ~XMLNode(); + virtual char* ParseDeep( char*, StrPair* ); + XMLDocument* _document; XMLNode* _parent; mutable StrPair _value; @@ -904,6 +887,8 @@ protected: XMLNode* _prev; XMLNode* _next; + void* _userData; + private: MemPool* _memPool; void Unlink( XMLNode* child ); @@ -929,7 +914,6 @@ private: */ class TINYXML2_LIB XMLText : public XMLNode { - friend class XMLBase; friend class XMLDocument; public: virtual bool Accept( XMLVisitor* visitor ) const; @@ -950,7 +934,6 @@ public: return _isCData; } - char* ParseDeep( char*, StrPair* endTag ); virtual XMLNode* ShallowClone( XMLDocument* document ) const; virtual bool ShallowEqual( const XMLNode* compare ) const; @@ -958,6 +941,8 @@ protected: XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {} virtual ~XMLText() {} + char* ParseDeep( char*, StrPair* endTag ); + private: bool _isCData; @@ -980,7 +965,6 @@ public: virtual bool Accept( XMLVisitor* visitor ) const; - char* ParseDeep( char*, StrPair* endTag ); virtual XMLNode* ShallowClone( XMLDocument* document ) const; virtual bool ShallowEqual( const XMLNode* compare ) const; @@ -988,6 +972,8 @@ protected: XMLComment( XMLDocument* doc ); virtual ~XMLComment(); + char* ParseDeep( char*, StrPair* endTag ); + private: XMLComment( const XMLComment& ); // not supported XMLComment& operator=( const XMLComment& ); // not supported @@ -1018,7 +1004,6 @@ public: virtual bool Accept( XMLVisitor* visitor ) const; - char* ParseDeep( char*, StrPair* endTag ); virtual XMLNode* ShallowClone( XMLDocument* document ) const; virtual bool ShallowEqual( const XMLNode* compare ) const; @@ -1026,6 +1011,8 @@ protected: XMLDeclaration( XMLDocument* doc ); virtual ~XMLDeclaration(); + char* ParseDeep( char*, StrPair* endTag ); + private: XMLDeclaration( const XMLDeclaration& ); // not supported XMLDeclaration& operator=( const XMLDeclaration& ); // not supported @@ -1052,7 +1039,6 @@ public: virtual bool Accept( XMLVisitor* visitor ) const; - char* ParseDeep( char*, StrPair* endTag ); virtual XMLNode* ShallowClone( XMLDocument* document ) const; virtual bool ShallowEqual( const XMLNode* compare ) const; @@ -1060,6 +1046,8 @@ protected: XMLUnknown( XMLDocument* doc ); virtual ~XMLUnknown(); + char* ParseDeep( char*, StrPair* endTag ); + private: XMLUnknown( const XMLUnknown& ); // not supported XMLUnknown& operator=( const XMLUnknown& ); // not supported @@ -1092,11 +1080,18 @@ public: If the value isn't an integer, 0 will be returned. There is no error checking; use QueryIntValue() if you need error checking. */ - int IntValue() const { - int i=0; - QueryIntValue( &i ); - return i; - } + int IntValue() const { + int i = 0; + QueryIntValue(&i); + return i; + } + + int64_t Int64Value() const { + int64_t i = 0; + QueryInt64Value(&i); + return i; + } + /// Query as an unsigned integer. See IntValue() unsigned UnsignedValue() const { unsigned i=0; @@ -1129,7 +1124,9 @@ public: XMLError QueryIntValue( int* value ) const; /// See QueryIntValue XMLError QueryUnsignedValue( unsigned int* value ) const; - /// See QueryIntValue + /// See QueryIntValue + XMLError QueryInt64Value(int64_t* value) const; + /// See QueryIntValue XMLError QueryBoolValue( bool* value ) const; /// See QueryIntValue XMLError QueryDoubleValue( double* value ) const; @@ -1142,7 +1139,9 @@ public: void SetAttribute( int value ); /// Set the attribute to value. void SetAttribute( unsigned value ); - /// Set the attribute to value. + /// Set the attribute to value. + void SetAttribute(int64_t value); + /// Set the attribute to value. void SetAttribute( bool value ); /// Set the attribute to value. void SetAttribute( double value ); @@ -1174,7 +1173,6 @@ private: */ class TINYXML2_LIB XMLElement : public XMLNode { - friend class XMLBase; friend class XMLDocument; public: /// Get the name of an element (which is the Value() of the node.) @@ -1229,26 +1227,35 @@ public: QueryIntAttribute( name, &i ); return i; } + /// See IntAttribute() unsigned UnsignedAttribute( const char* name ) const { unsigned i=0; QueryUnsignedAttribute( name, &i ); return i; } - /// See IntAttribute() - bool BoolAttribute( const char* name ) const { + + /// See IntAttribute() + int64_t Int64Attribute(const char* name) const { + int64_t i = 0; + QueryInt64Attribute(name, &i); + return i; + } + + /// See IntAttribute() + bool BoolAttribute( const char* name ) const { bool b=false; QueryBoolAttribute( name, &b ); return b; } /// See IntAttribute() - double DoubleAttribute( const char* name ) const { + double DoubleAttribute( const char* name ) const { double d=0; QueryDoubleAttribute( name, &d ); return d; } /// See IntAttribute() - float FloatAttribute( const char* name ) const { + float FloatAttribute( const char* name ) const { float f=0; QueryFloatAttribute( name, &f ); return f; @@ -1274,7 +1281,8 @@ public: } return a->QueryIntValue( value ); } - /// See QueryIntAttribute() + + /// See QueryIntAttribute() XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) { @@ -1282,7 +1290,17 @@ public: } return a->QueryUnsignedValue( value ); } - /// See QueryIntAttribute() + + /// See QueryIntAttribute() + XMLError QueryInt64Attribute(const char* name, int64_t* value) const { + const XMLAttribute* a = FindAttribute(name); + if (!a) { + return XML_NO_ATTRIBUTE; + } + return a->QueryInt64Value(value); + } + + /// See QueryIntAttribute() XMLError QueryBoolAttribute( const char* name, bool* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) { @@ -1333,6 +1351,10 @@ public: return QueryUnsignedAttribute( name, value ); } + int QueryAttribute(const char* name, int64_t* value) const { + return QueryInt64Attribute(name, value); + } + int QueryAttribute( const char* name, bool* value ) const { return QueryBoolAttribute( name, value ); } @@ -1360,7 +1382,14 @@ public: XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); } - /// Sets the named attribute to value. + + /// Sets the named attribute to value. + void SetAttribute(const char* name, int64_t value) { + XMLAttribute* a = FindOrCreateAttribute(name); + a->SetAttribute(value); + } + + /// Sets the named attribute to value. void SetAttribute( const char* name, bool value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); @@ -1453,15 +1482,17 @@ public: @endverbatim */ void SetText( const char* inText ); - /// Convenience method for setting text inside and element. See SetText() for important limitations. + /// Convenience method for setting text inside an element. See SetText() for important limitations. void SetText( int value ); - /// Convenience method for setting text inside and element. See SetText() for important limitations. + /// Convenience method for setting text inside an element. See SetText() for important limitations. void SetText( unsigned value ); - /// Convenience method for setting text inside and element. See SetText() for important limitations. + /// Convenience method for setting text inside an element. See SetText() for important limitations. + void SetText(int64_t value); + /// Convenience method for setting text inside an element. See SetText() for important limitations. void SetText( bool value ); - /// Convenience method for setting text inside and element. See SetText() for important limitations. + /// Convenience method for setting text inside an element. See SetText() for important limitations. void SetText( double value ); - /// Convenience method for setting text inside and element. See SetText() for important limitations. + /// Convenience method for setting text inside an element. See SetText() for important limitations. void SetText( float value ); /** @@ -1493,7 +1524,9 @@ public: XMLError QueryIntText( int* ival ) const; /// See QueryIntText() XMLError QueryUnsignedText( unsigned* uval ) const; - /// See QueryIntText() + /// See QueryIntText() + XMLError QueryInt64Text(int64_t* uval) const; + /// See QueryIntText() XMLError QueryBoolText( bool* bval ) const; /// See QueryIntText() XMLError QueryDoubleText( double* dval ) const; @@ -1509,10 +1542,12 @@ public: int ClosingType() const { return _closingType; } - char* ParseDeep( char* p, StrPair* endTag ); virtual XMLNode* ShallowClone( XMLDocument* document ) const; virtual bool ShallowEqual( const XMLNode* compare ) const; +protected: + char* ParseDeep( char* p, StrPair* endTag ); + private: XMLElement( XMLDocument* doc ); virtual ~XMLElement(); @@ -1556,9 +1591,11 @@ public: ~XMLDocument(); virtual XMLDocument* ToDocument() { + TIXMLASSERT( this == _document ); return this; } virtual const XMLDocument* ToDocument() const { + TIXMLASSERT( this == _document ); return this; } @@ -1703,7 +1740,7 @@ public: /// Return true if there was an error parsing the document. bool Error() const { - return _errorID != XML_NO_ERROR; + return _errorID != XML_SUCCESS; } /// Return the errorID. XMLError ErrorID() const { @@ -1839,32 +1876,32 @@ public: return XMLHandle( _node ? _node->FirstChild() : 0 ); } /// Get the first child element of this handle. - XMLHandle FirstChildElement( const char* value=0 ) { - return XMLHandle( _node ? _node->FirstChildElement( value ) : 0 ); + XMLHandle FirstChildElement( const char* name = 0 ) { + return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 ); } /// Get the last child of this handle. XMLHandle LastChild() { return XMLHandle( _node ? _node->LastChild() : 0 ); } /// Get the last child element of this handle. - XMLHandle LastChildElement( const char* _value=0 ) { - return XMLHandle( _node ? _node->LastChildElement( _value ) : 0 ); + XMLHandle LastChildElement( const char* name = 0 ) { + return XMLHandle( _node ? _node->LastChildElement( name ) : 0 ); } /// Get the previous sibling of this handle. XMLHandle PreviousSibling() { return XMLHandle( _node ? _node->PreviousSibling() : 0 ); } /// Get the previous sibling element of this handle. - XMLHandle PreviousSiblingElement( const char* _value=0 ) { - return XMLHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 ); + XMLHandle PreviousSiblingElement( const char* name = 0 ) { + return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 ); } /// Get the next sibling of this handle. XMLHandle NextSibling() { return XMLHandle( _node ? _node->NextSibling() : 0 ); } /// Get the next sibling element of this handle. - XMLHandle NextSiblingElement( const char* _value=0 ) { - return XMLHandle( _node ? _node->NextSiblingElement( _value ) : 0 ); + XMLHandle NextSiblingElement( const char* name = 0 ) { + return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 ); } /// Safe cast to XMLNode. This can return null. @@ -1918,26 +1955,26 @@ public: const XMLConstHandle FirstChild() const { return XMLConstHandle( _node ? _node->FirstChild() : 0 ); } - const XMLConstHandle FirstChildElement( const char* value=0 ) const { - return XMLConstHandle( _node ? _node->FirstChildElement( value ) : 0 ); + const XMLConstHandle FirstChildElement( const char* name = 0 ) const { + return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 ); } const XMLConstHandle LastChild() const { return XMLConstHandle( _node ? _node->LastChild() : 0 ); } - const XMLConstHandle LastChildElement( const char* _value=0 ) const { - return XMLConstHandle( _node ? _node->LastChildElement( _value ) : 0 ); + const XMLConstHandle LastChildElement( const char* name = 0 ) const { + return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 ); } const XMLConstHandle PreviousSibling() const { return XMLConstHandle( _node ? _node->PreviousSibling() : 0 ); } - const XMLConstHandle PreviousSiblingElement( const char* _value=0 ) const { - return XMLConstHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 ); + const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const { + return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 ); } const XMLConstHandle NextSibling() const { return XMLConstHandle( _node ? _node->NextSibling() : 0 ); } - const XMLConstHandle NextSiblingElement( const char* _value=0 ) const { - return XMLConstHandle( _node ? _node->NextSiblingElement( _value ) : 0 ); + const XMLConstHandle NextSiblingElement( const char* name = 0 ) const { + return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 ); } @@ -2026,7 +2063,8 @@ public: void PushAttribute( const char* name, const char* value ); void PushAttribute( const char* name, int value ); void PushAttribute( const char* name, unsigned value ); - void PushAttribute( const char* name, bool value ); + void PushAttribute(const char* name, int64_t value); + void PushAttribute( const char* name, bool value ); void PushAttribute( const char* name, double value ); /// If streaming, close the Element. virtual void CloseElement( bool compactMode=false ); @@ -2037,7 +2075,9 @@ public: void PushText( int value ); /// Add a text node from an unsigned. void PushText( unsigned value ); - /// Add a text node from a bool. + /// Add a text node from an unsigned. + void PushText(int64_t value); + /// Add a text node from a bool. void PushText( bool value ); /// Add a text node from a float. void PushText( float value ); diff --git a/tinyxml2/test.vcxproj b/tinyxml2/test.vcxproj index e61bb1b..d46eb75 100644 --- a/tinyxml2/test.vcxproj +++ b/tinyxml2/test.vcxproj @@ -1,5 +1,5 @@  - + Debug-Dll @@ -37,51 +37,60 @@ {E8FB2712-8666-4662-A5B8-2B5B0FB1A260} test + 8.1 Application true Unicode + v140 Application true Unicode + v140 Application true Unicode + v140 Application true Unicode + v140 Application false true Unicode + v140 Application false true Unicode + v140 Application false true Unicode + v140 Application false true Unicode + v140 Unicode @@ -125,29 +134,25 @@ + - $(SolutionDir)bin\$(Platform)-$(Configuration)\ - - - $(SolutionDir)temp\$(Platform)-$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\ + - $(SolutionDir)bin\$(Platform)-$(Configuration)\ - - - $(SolutionDir)temp\$(Platform)-$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\ + - $(SolutionDir)bin\$(Platform)-$(Configuration)\ - - - $(SolutionDir)temp\$(Platform)-$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\ + - $(SolutionDir)bin\$(Platform)-$(Configuration)\ - - - $(SolutionDir)temp\$(Platform)-$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\ $(SolutionDir)bin\$(Platform)-$(Configuration)\ diff --git a/tinyxml2/tinyxml2.vcxproj b/tinyxml2/tinyxml2.vcxproj index 7155976..4c46354 100755 --- a/tinyxml2/tinyxml2.vcxproj +++ b/tinyxml2/tinyxml2.vcxproj @@ -1,5 +1,5 @@  - + Debug-Dll @@ -38,51 +38,60 @@ {D1C528B6-AA02-4D29-9D61-DC08E317A70D} Win32Proj tinyxml2 + 8.1 StaticLibrary true Unicode + v140 DynamicLibrary true Unicode + v140 StaticLibrary true Unicode + v140 DynamicLibrary true Unicode + v140 StaticLibrary false true Unicode + v140 DynamicLibrary false true Unicode + v140 StaticLibrary false true Unicode + v140 DynamicLibrary false true Unicode + v140 StaticLibrary @@ -132,13 +141,9 @@ true - $(SolutionDir)bin\$(Platform)-$(Configuration)\ - $(SolutionDir)temp\$(Platform)-$(Configuration)\ true - $(SolutionDir)bin\$(Platform)-$(Configuration)\ - $(SolutionDir)temp\$(Platform)-$(Configuration)\ true @@ -152,13 +157,9 @@ false - $(SolutionDir)bin\$(Platform)-$(Configuration)\ - $(SolutionDir)temp\$(Platform)-$(Configuration)\ false - $(SolutionDir)bin\$(Platform)-$(Configuration)\ - $(SolutionDir)temp\$(Platform)-$(Configuration)\ false diff --git a/xmltest.cpp b/xmltest.cpp index 243628c..3fdc0bd 100644 --- a/xmltest.cpp +++ b/xmltest.cpp @@ -30,7 +30,13 @@ int gFail = 0; bool XMLTest (const char* testString, const char* expected, const char* found, bool echo=true, bool extraNL=false ) { - bool pass = !strcmp( expected, found ); + bool pass; + if ( !expected && !found ) + pass = true; + else if ( !expected || !found ) + pass = false; + else + pass = !strcmp( expected, found ); if ( pass ) printf ("[pass]"); else @@ -410,6 +416,7 @@ int main( int argc, const char ** argv ) } element->InsertEndChild( sub[2] ); XMLNode* comment = element->InsertFirstChild( doc->NewComment( "comment" ) ); + comment->SetUserData((void*)2); element->InsertAfterChild( comment, sub[0] ); element->InsertAfterChild( sub[0], sub[1] ); sub[2]->InsertFirstChild( doc->NewText( "& Text!" )); @@ -419,6 +426,7 @@ int main( int argc, const char ** argv ) XMLTest( "Programmatic DOM", 2, doc->FirstChildElement()->LastChildElement( "sub" )->IntAttribute( "attrib" ) ); XMLTest( "Programmatic DOM", "& Text!", doc->FirstChildElement()->LastChildElement( "sub" )->FirstChild()->ToText()->Value() ); + XMLTest("User data", 2, (int)comment->GetUserData()); // And now deletion: element->DeleteChild( sub[2] ); @@ -507,13 +515,13 @@ int main( int argc, const char ** argv ) double dVal; result = ele->QueryDoubleAttribute( "attr0", &dVal ); - XMLTest( "Query attribute: int as double", result, (int)XML_NO_ERROR ); + XMLTest( "Query attribute: int as double", result, (int)XML_SUCCESS); XMLTest( "Query attribute: int as double", (int)dVal, 1 ); result = ele->QueryDoubleAttribute( "attr1", &dVal ); - XMLTest( "Query attribute: double as double", result, (int)XML_NO_ERROR ); + XMLTest( "Query attribute: double as double", result, (int)XML_SUCCESS); XMLTest( "Query attribute: double as double", (int)dVal, 2 ); result = ele->QueryIntAttribute( "attr1", &iVal ); - XMLTest( "Query attribute: double as int", result, (int)XML_NO_ERROR ); + XMLTest( "Query attribute: double as int", result, (int)XML_SUCCESS); XMLTest( "Query attribute: double as int", iVal, 2 ); result = ele->QueryIntAttribute( "attr2", &iVal ); XMLTest( "Query attribute: not a number", result, (int)XML_WRONG_ATTRIBUTE_TYPE ); @@ -680,6 +688,107 @@ int main( int argc, const char ** argv ) XMLTest( "SetText types", "1.5", element->GetText() ); } + // ---------- Attributes --------- + { + static const int64_t BIG = -123456789012345678; + XMLDocument doc; + XMLElement* element = doc.NewElement("element"); + doc.InsertFirstChild(element); + + { + element->SetAttribute("attrib", int(-100)); + int v = 0; + element->QueryIntAttribute("attrib", &v); + XMLTest("Attribute: int", -100, v, true); + element->QueryAttribute("attrib", &v); + XMLTest("Attribute: int", -100, v, true); + } + { + element->SetAttribute("attrib", unsigned(100)); + unsigned v = 0; + element->QueryUnsignedAttribute("attrib", &v); + XMLTest("Attribute: unsigned", unsigned(100), v, true); + element->QueryAttribute("attrib", &v); + XMLTest("Attribute: unsigned", unsigned(100), v, true); + } + { + element->SetAttribute("attrib", BIG); + int64_t v = 0; + element->QueryInt64Attribute("attrib", &v); + XMLTest("Attribute: int64_t", BIG, v, true); + element->QueryAttribute("attrib", &v); + XMLTest("Attribute: int64_t", BIG, v, true); + } + { + element->SetAttribute("attrib", true); + bool v = false; + element->QueryBoolAttribute("attrib", &v); + XMLTest("Attribute: bool", true, v, true); + element->QueryAttribute("attrib", &v); + XMLTest("Attribute: bool", true, v, true); + } + { + element->SetAttribute("attrib", 100.0); + double v = 0; + element->QueryDoubleAttribute("attrib", &v); + XMLTest("Attribute: double", 100.0, v, true); + element->QueryAttribute("attrib", &v); + XMLTest("Attribute: double", 100.0, v, true); + } + { + element->SetAttribute("attrib", 100.0f); + float v = 0; + element->QueryFloatAttribute("attrib", &v); + XMLTest("Attribute: float", 100.0f, v, true); + element->QueryAttribute("attrib", &v); + XMLTest("Attribute: float", 100.0f, v, true); + } + { + element->SetText(BIG); + int64_t v = 0; + element->QueryInt64Text(&v); + XMLTest("Element: int64_t", BIG, v, true); + } + } + + // ---------- XMLPrinter stream mode ------ + { + { + FILE* printerfp = fopen("resources/printer.xml", "w"); + XMLPrinter printer(printerfp); + printer.OpenElement("foo"); + printer.PushAttribute("attrib-text", "text"); + printer.PushAttribute("attrib-int", int(1)); + printer.PushAttribute("attrib-unsigned", unsigned(2)); + printer.PushAttribute("attrib-int64", int64_t(3)); + printer.PushAttribute("attrib-bool", true); + printer.PushAttribute("attrib-double", 4.0); + printer.CloseElement(); + fclose(printerfp); + } + { + XMLDocument doc; + doc.LoadFile("resources/printer.xml"); + XMLTest("XMLPrinter Stream mode: load", doc.ErrorID(), XML_SUCCESS, true); + + const XMLDocument& cdoc = doc; + + const XMLAttribute* attrib = cdoc.FirstChildElement("foo")->FindAttribute("attrib-text"); + XMLTest("attrib-text", "text", attrib->Value(), true); + attrib = cdoc.FirstChildElement("foo")->FindAttribute("attrib-int"); + XMLTest("attrib-int", int(1), attrib->IntValue(), true); + attrib = cdoc.FirstChildElement("foo")->FindAttribute("attrib-unsigned"); + XMLTest("attrib-unsigned", unsigned(2), attrib->UnsignedValue(), true); + attrib = cdoc.FirstChildElement("foo")->FindAttribute("attrib-int64"); + XMLTest("attrib-int64", int64_t(3), attrib->Int64Value(), true); + attrib = cdoc.FirstChildElement("foo")->FindAttribute("attrib-bool"); + XMLTest("attrib-bool", true, attrib->BoolValue(), true); + attrib = cdoc.FirstChildElement("foo")->FindAttribute("attrib-double"); + XMLTest("attrib-double", 4.0, attrib->DoubleValue(), true); + } + + } + // ---------- CDATA --------------- { @@ -997,7 +1106,7 @@ int main( int argc, const char ** argv ) { // This shouldn't crash. XMLDocument doc; - if(XML_NO_ERROR != doc.LoadFile( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" )) + if(XML_SUCCESS != doc.LoadFile( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" )) { doc.PrintError(); } @@ -1167,6 +1276,9 @@ int main( int argc, const char ** argv ) { XMLDocument doc; + XMLTest( "Document is initially empty", doc.NoChildren(), true ); + doc.Clear(); + XMLTest( "Empty is empty after Clear()", doc.NoChildren(), true ); doc.LoadFile( "resources/dream.xml" ); XMLTest( "Document has something to Clear()", doc.NoChildren(), false ); doc.Clear(); @@ -1247,7 +1359,7 @@ int main( int argc, const char ** argv ) static const char* xml_bom_preservation = "\xef\xbb\xbf\n"; { XMLDocument doc; - XMLTest( "BOM preservation (parse)", XML_NO_ERROR, doc.Parse( xml_bom_preservation ), false ); + XMLTest( "BOM preservation (parse)", XML_SUCCESS, doc.Parse( xml_bom_preservation ), false ); XMLPrinter printer; doc.Print( &printer ); @@ -1425,41 +1537,112 @@ int main( int argc, const char ** argv ) XMLPrinter printer; doc.Print( &printer ); } + { + // Issue 299. Can print elements that are not linked in. + // Will crash if issue not fixed. + XMLDocument doc; + XMLElement* newElement = doc.NewElement( "printme" ); + XMLPrinter printer; + newElement->Accept( &printer ); + // Delete the node to avoid possible memory leak report in debug output + doc.DeleteNode( newElement ); + } + { + // Issue 302. Clear errors from LoadFile/SaveFile + XMLDocument doc; + XMLTest( "Issue 302. Should be no error initially", "XML_SUCCESS", doc.ErrorName() ); + doc.SaveFile( "./no/such/path/pretty.xml" ); + XMLTest( "Issue 302. Fail to save", "XML_ERROR_FILE_COULD_NOT_BE_OPENED", doc.ErrorName() ); + doc.SaveFile( "./resources/out/compact.xml", true ); + XMLTest( "Issue 302. Subsequent success in saving", "XML_SUCCESS", doc.ErrorName() ); + } + + { + // If a document fails to load then subsequent + // successful loads should clear the error + XMLDocument doc; + XMLTest( "Should be no error initially", false, doc.Error() ); + doc.LoadFile( "resources/no-such-file.xml" ); + XMLTest( "No such file - should fail", true, doc.Error() ); + + doc.LoadFile( "resources/dream.xml" ); + XMLTest( "Error should be cleared", false, doc.Error() ); + } + + { + // Check that declarations are parsed only as the FirstChild + const char* xml0 = "" + " " + ""; + const char* xml1 = "" + " " + ""; + const char* xml2 = "" + ""; + XMLDocument doc; + doc.Parse(xml0); + XMLTest("Test that the code changes do not affect normal parsing", doc.Error(), false); + doc.Parse(xml1); + XMLTest("Test that the second declaration throws an error", doc.ErrorID(), XML_ERROR_PARSING_DECLARATION); + doc.Parse(xml2); + XMLTest("Test that declaration after a child throws an error", doc.ErrorID(), XML_ERROR_PARSING_DECLARATION); + } + + { + // No matter - before or after successfully parsing a text - + // calling XMLDocument::Value() causes an assert in debug. + const char* validXml = "" + "" + ""; + XMLDocument* doc = new XMLDocument(); + XMLTest( "XMLDocument::Value() returns null?", NULL, doc->Value() ); + doc->Parse( validXml ); + XMLTest( "XMLDocument::Value() returns null?", NULL, doc->Value() ); + delete doc; + } + + { + XMLDocument doc; + for( int i = 0; i < XML_ERROR_COUNT; i++ ) { + doc.SetError( (XMLError)i, 0, 0 ); + doc.ErrorName(); + } + } - // ----------- Performance tracking -------------- + // ----------- Performance tracking -------------- { #if defined( _MSC_VER ) __int64 start, end, freq; - QueryPerformanceFrequency( (LARGE_INTEGER*) &freq ); + QueryPerformanceFrequency((LARGE_INTEGER*)&freq); #endif - FILE* fp = fopen( "resources/dream.xml", "r" ); - fseek( fp, 0, SEEK_END ); - long size = ftell( fp ); - fseek( fp, 0, SEEK_SET ); + FILE* perfFP = fopen("resources/dream.xml", "r"); + fseek(perfFP, 0, SEEK_END); + long size = ftell(fp); + fseek(perfFP, 0, SEEK_SET); - char* mem = new char[size+1]; - fread( mem, size, 1, fp ); - fclose( fp ); + char* mem = new char[size + 1]; + fread(mem, size, 1, perfFP); + fclose(perfFP); mem[size] = 0; #if defined( _MSC_VER ) - QueryPerformanceCounter( (LARGE_INTEGER*) &start ); + QueryPerformanceCounter((LARGE_INTEGER*)&start); #else clock_t cstart = clock(); #endif static const int COUNT = 10; - for( int i=0; i