Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OGR 4 : * Purpose: Convenience function for parsing with Expat library 5 : * Author: Even Rouault, even dot rouault at spatialys.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2009, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #ifndef OGR_EXPATH_INCLUDED 14 : #define OGR_EXPATH_INCLUDED 15 : 16 : #ifdef HAVE_EXPAT 17 : 18 : #include "cpl_error.h" 19 : #include "cpl_port.h" 20 : #include <cinttypes> 21 : #include <expat.h> 22 : 23 : #include <memory> 24 : 25 : /* Compatibility stuff for expat >= 1.95.0 and < 1.95.7 */ 26 : #ifndef XMLCALL 27 : #define XMLCALL 28 : #endif 29 : #ifndef XML_STATUS_OK 30 : #define XML_STATUS_OK 1 31 : #define XML_STATUS_ERROR 0 32 : #endif 33 : 34 : #undef XML_FALSE 35 : #define XML_FALSE static_cast<XML_Bool>(0) 36 : 37 : #undef XML_TRUE 38 : #define XML_TRUE static_cast<XML_Bool>(1) 39 : 40 : /* XML_StopParser only available for expat >= 1.95.8 */ 41 : #if !defined(XML_MAJOR_VERSION) || \ 42 : (XML_MAJOR_VERSION * 10000 + XML_MINOR_VERSION * 100 + \ 43 : XML_MICRO_VERSION) < 19508 44 : #define XML_StopParser(parser, resumable) 45 : #warning \ 46 : "Expat version is too old and does not have XML_StopParser. Corrupted files could hang OGR" 47 : #endif 48 : 49 : /* Only for internal use ! */ 50 : XML_Parser CPL_DLL OGRCreateExpatXMLParser(void); 51 : 52 16 : template <typename T> inline const char *OGRExpatGetParseError(const T &oParser) 53 : { 54 : #if XML_MAJOR_VERSION > 2 || (XML_MAJOR_VERSION == 2 && XML_MINOR_VERSION >= 9) 55 : return CPLSPrintf( 56 : "%s at line %" PRIu64 ", column %" PRIu64, 57 : XML_ErrorString(XML_GetErrorCode(oParser)), 58 : static_cast<std::uint64_t>(XML_GetCurrentLineNumber64(oParser)), 59 : static_cast<std::uint64_t>(XML_GetCurrentColumnNumber64(oParser))); 60 : #else 61 16 : return CPLSPrintf("%s at line %d, column %d", 62 : XML_ErrorString(XML_GetErrorCode(oParser)), 63 16 : static_cast<int>(XML_GetCurrentLineNumber(oParser)), 64 32 : static_cast<int>(XML_GetCurrentColumnNumber(oParser))); 65 : #endif 66 : } 67 : 68 : // 69 : //! @cond Doxygen_Suppress 70 : struct CPL_DLL OGRExpatUniquePtrDeleter 71 : { 72 205 : void operator()(XML_Parser oParser) const 73 : { 74 205 : XML_ParserFree(oParser); 75 205 : } 76 : }; 77 : 78 : //! @endcond 79 : 80 : /** Unique pointer type for XML_Parser. 81 : * @since GDAL 3.2 82 : */ 83 : using OGRExpatUniquePtr = 84 : std::unique_ptr<XML_ParserStruct, OGRExpatUniquePtrDeleter>; 85 : 86 : #endif /* HAVE_EXPAT */ 87 : 88 : #endif /* OGR_EXPATH_INCLUDED */