From bf59a2d4c8b5e21a4e834fbfdd02854695fc02b0 Mon Sep 17 00:00:00 2001 From: John Senneker Date: Tue, 19 Nov 2019 11:00:52 -0500 Subject: [PATCH] Added support for files larger than ~2GB. This implements #786. TinyXML reads the entire file into a pre-allocated buffer in memory. To get the buffer size, it uses `fseek()` to seek to the end of the file, and `ftell()` to get the current byte offset. But because `ftell()` returns a 32-bit signed value, it can only represent byte offsets, hence file sizes, up to about 2GB. To get around this, `fseek` and `ftell` have been replaced by the `TIXML_FSEEK` and `TIXML_FTELL` macros, respectively, which will resolve to 64-bit versions of these functions on platforms that have them. --- tinyxml2.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/tinyxml2.cpp b/tinyxml2.cpp index 6b79917..a0b8735 100755 --- a/tinyxml2.cpp +++ b/tinyxml2.cpp @@ -100,6 +100,20 @@ distribution. #define TIXML_SSCANF sscanf #endif +#if defined(_WIN64) + #define TIXML_FSEEK _fseeki64 + #define TIXML_FTELL _ftelli64 +#elif defined(__APPLE__) + #define TIXML_FSEEK fseeko + #define TIXML_FTELL ftello +#elif defined(__x86_64__) + #define TIXML_FSEEK fseeko64 + #define TIXML_FTELL ftello64 +#else + #define TIXML_FSEEK fseek + #define TIXML_FTELL ftell +#endif + static const char LINE_FEED = static_cast(0x0a); // all line endings are normalized to LF static const char LF = LINE_FEED; @@ -2280,15 +2294,15 @@ XMLError XMLDocument::LoadFile( FILE* fp ) { Clear(); - fseek( fp, 0, SEEK_SET ); + TIXML_FSEEK( fp, 0, SEEK_SET ); if ( fgetc( fp ) == EOF && ferror( fp ) != 0 ) { SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); return _errorID; } - fseek( fp, 0, SEEK_END ); - const long filelength = ftell( fp ); - fseek( fp, 0, SEEK_SET ); + TIXML_FSEEK( fp, 0, SEEK_END ); + const long long filelength = TIXML_FTELL( fp ); + TIXML_FSEEK( fp, 0, SEEK_SET ); if ( filelength == -1L ) { SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); return _errorID;