LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/gml - gmlreaderp.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 67 69 97.1 %
Date: 2025-09-10 17:48:50 Functions: 29 30 96.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GML Reader
       4             :  * Purpose:  Private Declarations for OGR free GML Reader code.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2002, Frank Warmerdam
       9             :  * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #ifndef CPL_GMLREADERP_H_INCLUDED
      15             : #define CPL_GMLREADERP_H_INCLUDED
      16             : 
      17             : #if defined(HAVE_XERCES)
      18             : 
      19             : #include "xercesc_headers.h"
      20             : #include "ogr_xerces.h"
      21             : 
      22             : #endif /* HAVE_XERCES */
      23             : 
      24             : #include "cpl_string.h"
      25             : #include "gmlreader.h"
      26             : #include "ogr_api.h"
      27             : #include "cpl_vsi.h"
      28             : #include "cpl_multiproc.h"
      29             : #include "gmlutils.h"
      30             : 
      31             : #include <map>
      32             : #include <string>
      33             : #include <vector>
      34             : 
      35             : #define PARSER_BUF_SIZE (10 * 8192)
      36             : 
      37             : class GMLReader;
      38             : 
      39             : typedef struct _GeometryNamesStruct GeometryNamesStruct;
      40             : 
      41             : bool OGRGMLIsGeometryElement(const char *pszElement);
      42             : 
      43             : /************************************************************************/
      44             : /*                        GFSTemplateList                               */
      45             : /************************************************************************/
      46             : 
      47             : class GFSTemplateItem;
      48             : 
      49             : class GFSTemplateList
      50             : {
      51             :   private:
      52             :     bool m_bSequentialLayers;
      53             :     GFSTemplateItem *pFirst;
      54             :     GFSTemplateItem *pLast;
      55             :     GFSTemplateItem *Insert(const char *pszName);
      56             : 
      57             :     CPL_DISALLOW_COPY_ASSIGN(GFSTemplateList)
      58             : 
      59             :   public:
      60             :     GFSTemplateList();
      61             :     ~GFSTemplateList();
      62             :     void Update(const char *pszName, int bHasGeom);
      63             : 
      64          10 :     GFSTemplateItem *GetFirst()
      65             :     {
      66          10 :         return pFirst;
      67             :     }
      68             : 
      69           5 :     bool HaveSequentialLayers()
      70             :     {
      71           5 :         return m_bSequentialLayers;
      72             :     }
      73             : 
      74             :     int GetClassCount();
      75             : };
      76             : 
      77             : void gmlUpdateFeatureClasses(GFSTemplateList *pCC, GMLReader *pReader,
      78             :                              int *pnHasSequentialLayers);
      79             : 
      80             : /************************************************************************/
      81             : /*                              GMLHandler                              */
      82             : /************************************************************************/
      83             : 
      84             : #define STACK_SIZE 5
      85             : 
      86             : typedef enum
      87             : {
      88             :     STATE_TOP,
      89             :     STATE_DEFAULT,
      90             :     STATE_FEATURE,
      91             :     STATE_PROPERTY,
      92             :     STATE_FEATUREPROPERTY,
      93             :     STATE_GEOMETRY,
      94             :     STATE_IGNORED_FEATURE,
      95             :     STATE_BOUNDED_BY,
      96             :     STATE_BOUNDED_BY_IN_FEATURE,
      97             :     STATE_CITYGML_ATTRIBUTE
      98             : } HandlerState;
      99             : 
     100             : typedef struct
     101             : {
     102             :     CPLXMLNode *psNode;
     103             :     CPLXMLNode *psLastChild;
     104             : } NodeLastChild;
     105             : 
     106             : typedef enum
     107             : {
     108             :     APPSCHEMA_GENERIC,
     109             :     APPSCHEMA_CITYGML,
     110             :     APPSCHEMA_AIXM,
     111             :     APPSCHEMA_MTKGML /* format of National Land Survey Finnish */
     112             : } GMLAppSchemaType;
     113             : 
     114             : class GMLHandler /* non final */
     115             : {
     116             :     char *m_pszCurField = nullptr;
     117             :     unsigned int m_nCurFieldAlloc = 0;
     118             :     unsigned int m_nCurFieldLen = 0;
     119             :     bool m_bInCurField = false;
     120             :     int m_nAttributeIndex = -1;
     121             :     int m_nAttributeDepth = 0;
     122             : 
     123             :     char *m_pszGeometry = nullptr;
     124             :     unsigned int m_nGeomAlloc = 0;
     125             :     unsigned int m_nGeomLen = 0;
     126             :     int m_nGeometryDepth = 0;
     127             :     bool m_bAlreadyFoundGeometry = false;
     128             :     int m_nGeometryPropertyIndex = 0;
     129             :     std::map<std::string, CPLXMLNode *> m_oMapElementToSubstitute{};
     130             : 
     131             :     int m_nDepth = 0;
     132             :     int m_nDepthFeature = 0;
     133             :     int m_nUnlimitedDepth = -1;  // -1 unknown, 0=false, 1=true
     134             : 
     135             :     int m_inBoundedByDepth = 0;
     136             : 
     137             :     char *m_pszCityGMLGenericAttrName = nullptr;
     138             :     int m_inCityGMLGenericAttrDepth = 0;
     139             : 
     140             :     bool m_bReportHref = false;
     141             :     char *m_pszHref = nullptr;
     142             :     char *m_pszUom = nullptr;
     143             :     char *m_pszValue = nullptr;
     144             :     char *m_pszKieli = nullptr;
     145             : 
     146             :     GeometryNamesStruct *pasGeometryNames = nullptr;
     147             : 
     148             :     std::vector<NodeLastChild> apsXMLNode{};
     149             : 
     150             :     int m_nSRSDimensionIfMissing = 0;
     151             : 
     152             :     OGRErr startElementTop(const char *pszName, int nLenName, void *attr);
     153             : 
     154             :     OGRErr endElementIgnoredFeature();
     155             : 
     156             :     OGRErr startElementBoundedBy(const char *pszName, int nLenName, void *attr);
     157             :     OGRErr endElementBoundedBy();
     158             : 
     159             :     OGRErr endElementBoundedByInFeature();
     160             : 
     161             :     OGRErr startElementFeatureAttribute(const char *pszName, int nLenName,
     162             :                                         void *attr);
     163             :     OGRErr endElementFeature();
     164             : 
     165             :     OGRErr startElementCityGMLGenericAttr(const char *pszName, int nLenName,
     166             :                                           void *attr);
     167             :     OGRErr endElementCityGMLGenericAttr();
     168             : 
     169             :     OGRErr startElementGeometry(const char *pszName, int nLenName, void *attr);
     170             :     void ParseAIXMElevationProperties(const CPLXMLNode *);
     171             :     CPLXMLNode *ParseAIXMElevationPoint(CPLXMLNode *);
     172             :     OGRErr endElementGeometry();
     173             :     OGRErr dataHandlerGeometry(const char *data, int nLen);
     174             : 
     175             :     OGRErr endElementAttribute();
     176             :     OGRErr dataHandlerAttribute(const char *data, int nLen);
     177             : 
     178             :     OGRErr startElementDefault(const char *pszName, int nLenName, void *attr);
     179             :     OGRErr endElementDefault();
     180             : 
     181             :     OGRErr startElementFeatureProperty(const char *pszName, int nLenName,
     182             :                                        void *attr);
     183             :     OGRErr endElementFeatureProperty();
     184             : 
     185             :     void DealWithAttributes(const char *pszName, int nLenName, void *attr);
     186             :     bool IsConditionMatched(const char *pszCondition, void *attr);
     187             :     int FindRealPropertyByCheckingConditions(int nIdx, void *attr);
     188             : 
     189             :     CPL_DISALLOW_COPY_ASSIGN(GMLHandler)
     190             : 
     191             :   protected:
     192             :     explicit GMLHandler(GMLReader *poReader);
     193             : 
     194             :     GMLReader *m_poReader = nullptr;
     195             :     GMLAppSchemaType eAppSchemaType = APPSCHEMA_GENERIC;
     196             : 
     197             :     int nStackDepth = 0;
     198             :     HandlerState stateStack[STACK_SIZE];
     199             : 
     200             :     CPLString m_osFID{};
     201             :     virtual const char *GetFID(void *attr) = 0;
     202             : 
     203             :     virtual CPLXMLNode *AddAttributes(CPLXMLNode *psNode, void *attr) = 0;
     204             : 
     205             :     OGRErr startElement(const char *pszName, int nLenName, void *attr);
     206             :     OGRErr endElement();
     207             :     OGRErr dataHandler(const char *data, int nLen);
     208             : 
     209             :     bool IsGeometryElement(const char *pszElement);
     210             : 
     211             :   public:
     212             :     virtual ~GMLHandler();
     213             : 
     214             :     virtual char *GetAttributeValue(void *attr,
     215             :                                     const char *pszAttributeName) = 0;
     216             :     virtual char *GetAttributeByIdx(void *attr, unsigned int idx,
     217             :                                     char **ppszKey) = 0;
     218             : 
     219           5 :     GMLAppSchemaType GetAppSchemaType() const
     220             :     {
     221           5 :         return eAppSchemaType;
     222             :     }
     223             : };
     224             : 
     225             : #if defined(HAVE_XERCES)
     226             : 
     227             : /************************************************************************/
     228             : /*                         GMLXercesHandler                             */
     229             : /************************************************************************/
     230             : class GMLXercesHandler final : public DefaultHandler, public GMLHandler
     231             : {
     232             :     int m_nEntityCounter = 0;
     233             :     CPLString m_osElement{};
     234             :     CPLString m_osCharacters{};
     235             :     CPLString m_osAttrName{};
     236             :     CPLString m_osAttrValue{};
     237             : 
     238             :   public:
     239             :     explicit GMLXercesHandler(GMLReader *poReader);
     240             : 
     241             :     void startElement(const XMLCh *const uri, const XMLCh *const localname,
     242             :                       const XMLCh *const qname,
     243             :                       const Attributes &attrs) override;
     244             :     void endElement(const XMLCh *const uri, const XMLCh *const localname,
     245             :                     const XMLCh *const qname) override;
     246             :     void characters(const XMLCh *const chars, const XMLSize_t length) override;
     247             : 
     248             :     void fatalError(const SAXParseException &) override;
     249             : 
     250             :     void startEntity(const XMLCh *const name) override;
     251             : 
     252             :     const char *GetFID(void *attr) override;
     253             :     CPLXMLNode *AddAttributes(CPLXMLNode *psNode, void *attr) override;
     254             :     virtual char *GetAttributeValue(void *attr,
     255             :                                     const char *pszAttributeName) override;
     256             :     virtual char *GetAttributeByIdx(void *attr, unsigned int idx,
     257             :                                     char **ppszKey) override;
     258             : };
     259             : 
     260             : #endif
     261             : 
     262             : #if defined(HAVE_EXPAT)
     263             : 
     264             : #include "ogr_expat.h"
     265             : 
     266             : /************************************************************************/
     267             : /*                           GMLExpatHandler                            */
     268             : /************************************************************************/
     269             : class GMLExpatHandler final : public GMLHandler
     270             : {
     271             :     XML_Parser m_oParser = nullptr;
     272             :     bool m_bStopParsing = false;
     273             :     int m_nDataHandlerCounter = 0;
     274             : 
     275             :     void DealWithError(OGRErr eErr);
     276             : 
     277             :     CPL_DISALLOW_COPY_ASSIGN(GMLExpatHandler)
     278             : 
     279             :   public:
     280             :     GMLExpatHandler(GMLReader *poReader, XML_Parser oParser);
     281             : 
     282         582 :     bool HasStoppedParsing()
     283             :     {
     284         582 :         return m_bStopParsing;
     285             :     }
     286             : 
     287         587 :     void ResetDataHandlerCounter()
     288             :     {
     289         587 :         m_nDataHandlerCounter = 0;
     290         587 :     }
     291             : 
     292             :     const char *GetFID(void *attr) override;
     293             :     CPLXMLNode *AddAttributes(CPLXMLNode *psNode, void *attr) override;
     294             :     virtual char *GetAttributeValue(void *attr,
     295             :                                     const char *pszAttributeName) override;
     296             :     virtual char *GetAttributeByIdx(void *attr, unsigned int idx,
     297             :                                     char **ppszKey) override;
     298             : 
     299             :     static void XMLCALL startElementCbk(void *pUserData, const char *pszName,
     300             :                                         const char **ppszAttr);
     301             : 
     302             :     static void XMLCALL endElementCbk(void *pUserData, const char *pszName);
     303             : 
     304             :     static void XMLCALL dataHandlerCbk(void *pUserData, const char *data,
     305             :                                        int nLen);
     306             : };
     307             : 
     308             : #endif
     309             : 
     310             : /************************************************************************/
     311             : /*                             GMLReadState                             */
     312             : /************************************************************************/
     313             : 
     314             : class GMLReadState
     315             : {
     316             :     std::vector<std::string> aosPathComponents{};
     317             : 
     318             :     CPL_DISALLOW_COPY_ASSIGN(GMLReadState)
     319             : 
     320             :   public:
     321         911 :     GMLReadState() = default;
     322         911 :     ~GMLReadState() = default;
     323             : 
     324             :     void PushPath(const char *pszElement, int nLen = -1);
     325             :     void PopPath();
     326             : 
     327        6233 :     const char *GetLastComponent() const
     328             :     {
     329        6233 :         return (m_nPathLength == 0)
     330        6233 :                    ? ""
     331        6233 :                    : aosPathComponents[m_nPathLength - 1].c_str();
     332             :     }
     333             : 
     334        6049 :     size_t GetLastComponentLen() const
     335             :     {
     336        6049 :         return (m_nPathLength == 0)
     337        6049 :                    ? 0
     338        6049 :                    : aosPathComponents[m_nPathLength - 1].size();
     339             :     }
     340             : 
     341             :     void Reset();
     342             : 
     343             :     GMLFeature *m_poFeature = nullptr;
     344             :     GMLReadState *m_poParentState = nullptr;
     345             : 
     346             :     std::string osPath{};  // element path ... | as separator.
     347             :     int m_nPathLength = 0;
     348             : };
     349             : 
     350             : /************************************************************************/
     351             : /*                              GMLReader                               */
     352             : /************************************************************************/
     353             : 
     354             : class GMLReader final : public IGMLReader
     355             : {
     356             :   private:
     357             :     bool m_bClassListLocked = false;
     358             : 
     359             :     int m_nClassCount = 0;
     360             :     GMLFeatureClass **m_papoClass = nullptr;
     361             :     bool m_bLookForClassAtAnyLevel = false;
     362             : 
     363             :     char *m_pszFilename = nullptr;
     364             : 
     365             : #ifndef HAVE_XERCES
     366             :     bool bUseExpatReader = true;
     367             : #else
     368             :     bool bUseExpatReader = false;
     369             : #endif
     370             : 
     371             :     GMLHandler *m_poGMLHandler = nullptr;
     372             : 
     373             : #if defined(HAVE_XERCES)
     374             :     SAX2XMLReader *m_poSAXReader = nullptr;
     375             :     XMLPScanToken m_oToFill{};
     376             :     GMLFeature *m_poCompleteFeature = nullptr;
     377             :     InputSource *m_GMLInputSource = nullptr;
     378             :     bool m_bEOF = false;
     379             :     bool m_bXercesInitialized = false;
     380             :     bool SetupParserXerces();
     381             :     GMLFeature *NextFeatureXerces();
     382             : #endif
     383             : 
     384             : #if defined(HAVE_EXPAT)
     385             :     XML_Parser oParser = nullptr;
     386             :     GMLFeature **ppoFeatureTab = nullptr;
     387             :     int nFeatureTabLength = 0;
     388             :     int nFeatureTabIndex = 0;
     389             :     int nFeatureTabAlloc = 0;
     390             :     bool SetupParserExpat();
     391             :     GMLFeature *NextFeatureExpat();
     392             :     char *pabyBuf = nullptr;
     393             :     CPLString m_osErrorMessage{};
     394             : #endif
     395             : 
     396             :     VSILFILE *fpGML = nullptr;
     397             :     bool m_bReadStarted = false;
     398             : 
     399             :     GMLReadState *m_poState = nullptr;
     400             :     GMLReadState *m_poRecycledState = nullptr;
     401             : 
     402             :     bool m_bStopParsing = false;
     403             : 
     404             :     bool SetupParser();
     405             :     void CleanupParser();
     406             : 
     407             :     bool m_bFetchAllGeometries = false;
     408             : 
     409             :     bool m_bInvertAxisOrderIfLatLong = false;
     410             :     bool m_bConsiderEPSGAsURN = false;
     411             :     GMLSwapCoordinatesEnum m_eSwapCoordinates = GML_SWAP_AUTO;
     412             :     bool m_bGetSecondaryGeometryOption = false;
     413             : 
     414             :     int ParseFeatureType(CPLXMLNode *psSchemaNode, const char *pszName,
     415             :                          const char *pszType);
     416             : 
     417             :     char *m_pszGlobalSRSName = nullptr;
     418             :     bool m_bCanUseGlobalSRSName = false;
     419             : 
     420             :     char *m_pszFilteredClassName = nullptr;
     421             :     int m_nFilteredClassIndex = -1;
     422             : 
     423             :     int m_nHasSequentialLayers = -1;
     424             : 
     425             :     std::string osElemPath{};
     426             : 
     427             :     bool m_bFaceHoleNegative = false;
     428             : 
     429             :     bool m_bSetWidthFlag = true;
     430             : 
     431             :     bool m_bReportAllAttributes = false;
     432             : 
     433             :     bool m_bIsWFSJointLayer = false;
     434             : 
     435             :     bool m_bEmptyAsNull = true;
     436             : 
     437             :     bool m_bUseBBOX = false;
     438             : 
     439             :     bool ParseXMLHugeFile(const char *pszOutputFilename,
     440             :                           const bool bSqliteIsTempFile,
     441             :                           const int iSqliteCacheMB);
     442             : 
     443             :     CPL_DISALLOW_COPY_ASSIGN(GMLReader)
     444             : 
     445             :   public:
     446             :     GMLReader(bool bExpatReader, bool bInvertAxisOrderIfLatLong,
     447             :               bool bConsiderEPSGAsURN, GMLSwapCoordinatesEnum eSwapCoordinates,
     448             :               bool bGetSecondaryGeometryOption);
     449             :     ~GMLReader() override;
     450             : 
     451           0 :     bool IsClassListLocked() const override
     452             :     {
     453           0 :         return m_bClassListLocked;
     454             :     }
     455             : 
     456         456 :     void SetClassListLocked(bool bFlag) override
     457             :     {
     458         456 :         m_bClassListLocked = bFlag;
     459         456 :     }
     460             : 
     461             :     void SetSourceFile(const char *pszFilename) override;
     462             :     void SetFP(VSILFILE *fp) override;
     463             :     const char *GetSourceFileName() override;
     464             : 
     465        3651 :     int GetClassCount() const override
     466             :     {
     467        3651 :         return m_nClassCount;
     468             :     }
     469             : 
     470             :     GMLFeatureClass *GetClass(int i) const override;
     471             :     GMLFeatureClass *GetClass(const char *pszName) const override;
     472             : 
     473             :     int AddClass(GMLFeatureClass *poClass) override;
     474             :     void ClearClasses() override;
     475             : 
     476             :     GMLFeature *NextFeature() override;
     477             : 
     478             :     bool LoadClasses(const char *pszFile = nullptr) override;
     479             :     bool SaveClasses(const char *pszFile = nullptr) override;
     480             : 
     481             :     bool ResolveXlinks(const char *pszFile, bool *pbOutIsTempFile,
     482             :                        char **papszSkip = nullptr,
     483             :                        const bool bStrict = false) override;
     484             : 
     485             :     bool HugeFileResolver(const char *pszFile, bool bSqliteIsTempFile,
     486             :                           int iSqliteCacheMB) override;
     487             : 
     488             :     bool PrescanForSchema(bool bGetExtents = true,
     489             :                           bool bOnlyDetectSRS = false) override;
     490             :     bool PrescanForTemplate() override;
     491             :     bool ReArrangeTemplateClasses(GFSTemplateList *pCC);
     492             :     void ResetReading() override;
     493             : 
     494             :     // ---
     495             : 
     496       64814 :     GMLReadState *GetState() const
     497             :     {
     498       64814 :         return m_poState;
     499             :     }
     500             : 
     501             :     void PopState();
     502             :     void PushState(GMLReadState *);
     503             : 
     504        6886 :     bool ShouldLookForClassAtAnyLevel()
     505             :     {
     506        6886 :         return m_bLookForClassAtAnyLevel;
     507             :     }
     508             : 
     509             :     int GetFeatureElementIndex(const char *pszElement, int nLen,
     510             :                                GMLAppSchemaType eAppSchemaType);
     511             :     int GetAttributeElementIndex(const char *pszElement, int nLen,
     512             :                                  const char *pszAttrKey = nullptr);
     513             :     bool IsCityGMLGenericAttributeElement(const char *pszElement, void *attr);
     514             : 
     515             :     void PushFeature(const char *pszElement, const char *pszFID,
     516             :                      int nClassIndex);
     517             : 
     518             :     void SetFeaturePropertyDirectly(const char *pszElement, char *pszValue,
     519             :                                     int iPropertyIn,
     520             :                                     GMLPropertyType eType = GMLPT_Untyped);
     521             : 
     522           8 :     void SetWidthFlag(bool bFlag)
     523             :     {
     524           8 :         m_bSetWidthFlag = bFlag;
     525           8 :     }
     526             : 
     527         112 :     bool HasStoppedParsing() override
     528             :     {
     529         112 :         return m_bStopParsing;
     530             :     }
     531             : 
     532        4927 :     bool FetchAllGeometries()
     533             :     {
     534        4927 :         return m_bFetchAllGeometries;
     535             :     }
     536             : 
     537             :     void SetGlobalSRSName(const char *pszGlobalSRSName) override;
     538             : 
     539         507 :     const char *GetGlobalSRSName() override
     540             :     {
     541         507 :         return m_pszGlobalSRSName;
     542             :     }
     543             : 
     544        1090 :     bool CanUseGlobalSRSName() override
     545             :     {
     546        1090 :         return m_bCanUseGlobalSRSName;
     547             :     }
     548             : 
     549             :     bool SetFilteredClassName(const char *pszClassName) override;
     550             : 
     551        4279 :     const char *GetFilteredClassName() override
     552             :     {
     553        4279 :         return m_pszFilteredClassName;
     554             :     }
     555             : 
     556          49 :     int GetFilteredClassIndex()
     557             :     {
     558          49 :         return m_nFilteredClassIndex;
     559             :     }
     560             : 
     561          88 :     bool IsSequentialLayers() const override
     562             :     {
     563          88 :         return m_nHasSequentialLayers == TRUE;
     564             :     }
     565             : 
     566         447 :     void SetReportAllAttributes(bool bFlag)
     567             :     {
     568         447 :         m_bReportAllAttributes = bFlag;
     569         447 :     }
     570             : 
     571         511 :     bool ReportAllAttributes() const
     572             :     {
     573         511 :         return m_bReportAllAttributes;
     574             :     }
     575             : 
     576         447 :     void SetIsWFSJointLayer(bool bFlag)
     577             :     {
     578         447 :         m_bIsWFSJointLayer = bFlag;
     579         447 :     }
     580             : 
     581       29269 :     bool IsWFSJointLayer() const
     582             :     {
     583       29269 :         return m_bIsWFSJointLayer;
     584             :     }
     585             : 
     586         447 :     void SetEmptyAsNull(bool bFlag)
     587             :     {
     588         447 :         m_bEmptyAsNull = bFlag;
     589         447 :     }
     590             : 
     591          70 :     bool IsEmptyAsNull() const
     592             :     {
     593          70 :         return m_bEmptyAsNull;
     594             :     }
     595             : 
     596         447 :     void SetUseBBOX(bool bFlag)
     597             :     {
     598         447 :         m_bUseBBOX = bFlag;
     599         447 :     }
     600             : 
     601         909 :     bool UseBBOX() const
     602             :     {
     603         909 :         return m_bUseBBOX;
     604             :     }
     605             : 
     606             :     static CPLMutex *hMutex;
     607             : };
     608             : 
     609             : #endif /* CPL_GMLREADERP_H_INCLUDED */

Generated by: LCOV version 1.14