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-01-18 12:42:00 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           6 :     GFSTemplateItem *GetFirst()
      65             :     {
      66           6 :         return pFirst;
      67             :     }
      68             : 
      69           3 :     bool HaveSequentialLayers()
      70             :     {
      71           3 :         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
     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             :     GMLReader *m_poReader = nullptr;
     193             :     GMLAppSchemaType eAppSchemaType = APPSCHEMA_GENERIC;
     194             : 
     195             :     int nStackDepth = 0;
     196             :     HandlerState stateStack[STACK_SIZE];
     197             : 
     198             :     CPLString m_osFID{};
     199             :     virtual const char *GetFID(void *attr) = 0;
     200             : 
     201             :     virtual CPLXMLNode *AddAttributes(CPLXMLNode *psNode, void *attr) = 0;
     202             : 
     203             :     OGRErr startElement(const char *pszName, int nLenName, void *attr);
     204             :     OGRErr endElement();
     205             :     OGRErr dataHandler(const char *data, int nLen);
     206             : 
     207             :     bool IsGeometryElement(const char *pszElement);
     208             : 
     209             :   public:
     210             :     explicit GMLHandler(GMLReader *poReader);
     211             :     virtual ~GMLHandler();
     212             : 
     213             :     virtual char *GetAttributeValue(void *attr,
     214             :                                     const char *pszAttributeName) = 0;
     215             :     virtual char *GetAttributeByIdx(void *attr, unsigned int idx,
     216             :                                     char **ppszKey) = 0;
     217             : 
     218           3 :     GMLAppSchemaType GetAppSchemaType() const
     219             :     {
     220           3 :         return eAppSchemaType;
     221             :     }
     222             : };
     223             : 
     224             : #if defined(HAVE_XERCES)
     225             : 
     226             : /************************************************************************/
     227             : /*                         GMLXercesHandler                             */
     228             : /************************************************************************/
     229             : class GMLXercesHandler final : public DefaultHandler, public GMLHandler
     230             : {
     231             :     int m_nEntityCounter = 0;
     232             :     CPLString m_osElement{};
     233             :     CPLString m_osCharacters{};
     234             :     CPLString m_osAttrName{};
     235             :     CPLString m_osAttrValue{};
     236             : 
     237             :   public:
     238             :     explicit GMLXercesHandler(GMLReader *poReader);
     239             : 
     240             :     void startElement(const XMLCh *const uri, const XMLCh *const localname,
     241             :                       const XMLCh *const qname,
     242             :                       const Attributes &attrs) override;
     243             :     void endElement(const XMLCh *const uri, const XMLCh *const localname,
     244             :                     const XMLCh *const qname) override;
     245             :     void characters(const XMLCh *const chars, const XMLSize_t length) override;
     246             : 
     247             :     void fatalError(const SAXParseException &) override;
     248             : 
     249             :     void startEntity(const XMLCh *const name) override;
     250             : 
     251             :     virtual const char *GetFID(void *attr) override;
     252             :     virtual CPLXMLNode *AddAttributes(CPLXMLNode *psNode, void *attr) override;
     253             :     virtual char *GetAttributeValue(void *attr,
     254             :                                     const char *pszAttributeName) override;
     255             :     virtual char *GetAttributeByIdx(void *attr, unsigned int idx,
     256             :                                     char **ppszKey) override;
     257             : };
     258             : 
     259             : #endif
     260             : 
     261             : #if defined(HAVE_EXPAT)
     262             : 
     263             : #include "ogr_expat.h"
     264             : 
     265             : /************************************************************************/
     266             : /*                           GMLExpatHandler                            */
     267             : /************************************************************************/
     268             : class GMLExpatHandler final : public GMLHandler
     269             : {
     270             :     XML_Parser m_oParser = nullptr;
     271             :     bool m_bStopParsing = false;
     272             :     int m_nDataHandlerCounter = 0;
     273             : 
     274             :     void DealWithError(OGRErr eErr);
     275             : 
     276             :     CPL_DISALLOW_COPY_ASSIGN(GMLExpatHandler)
     277             : 
     278             :   public:
     279             :     GMLExpatHandler(GMLReader *poReader, XML_Parser oParser);
     280             : 
     281         547 :     bool HasStoppedParsing()
     282             :     {
     283         547 :         return m_bStopParsing;
     284             :     }
     285             : 
     286         552 :     void ResetDataHandlerCounter()
     287             :     {
     288         552 :         m_nDataHandlerCounter = 0;
     289         552 :     }
     290             : 
     291             :     virtual const char *GetFID(void *attr) override;
     292             :     virtual CPLXMLNode *AddAttributes(CPLXMLNode *psNode, void *attr) override;
     293             :     virtual char *GetAttributeValue(void *attr,
     294             :                                     const char *pszAttributeName) override;
     295             :     virtual char *GetAttributeByIdx(void *attr, unsigned int idx,
     296             :                                     char **ppszKey) override;
     297             : 
     298             :     static void XMLCALL startElementCbk(void *pUserData, const char *pszName,
     299             :                                         const char **ppszAttr);
     300             : 
     301             :     static void XMLCALL endElementCbk(void *pUserData, const char *pszName);
     302             : 
     303             :     static void XMLCALL dataHandlerCbk(void *pUserData, const char *data,
     304             :                                        int nLen);
     305             : };
     306             : 
     307             : #endif
     308             : 
     309             : /************************************************************************/
     310             : /*                             GMLReadState                             */
     311             : /************************************************************************/
     312             : 
     313             : class GMLReadState
     314             : {
     315             :     std::vector<std::string> aosPathComponents{};
     316             : 
     317             :     CPL_DISALLOW_COPY_ASSIGN(GMLReadState)
     318             : 
     319             :   public:
     320         862 :     GMLReadState() = default;
     321         862 :     ~GMLReadState() = default;
     322             : 
     323             :     void PushPath(const char *pszElement, int nLen = -1);
     324             :     void PopPath();
     325             : 
     326        5650 :     const char *GetLastComponent() const
     327             :     {
     328        5650 :         return (m_nPathLength == 0)
     329        5650 :                    ? ""
     330        5650 :                    : aosPathComponents[m_nPathLength - 1].c_str();
     331             :     }
     332             : 
     333        5466 :     size_t GetLastComponentLen() const
     334             :     {
     335        5466 :         return (m_nPathLength == 0)
     336        5466 :                    ? 0
     337        5466 :                    : aosPathComponents[m_nPathLength - 1].size();
     338             :     }
     339             : 
     340             :     void Reset();
     341             : 
     342             :     GMLFeature *m_poFeature = nullptr;
     343             :     GMLReadState *m_poParentState = nullptr;
     344             : 
     345             :     std::string osPath{};  // element path ... | as separator.
     346             :     int m_nPathLength = 0;
     347             : };
     348             : 
     349             : /************************************************************************/
     350             : /*                              GMLReader                               */
     351             : /************************************************************************/
     352             : 
     353             : class GMLReader final : public IGMLReader
     354             : {
     355             :   private:
     356             :     bool m_bClassListLocked = false;
     357             : 
     358             :     int m_nClassCount = 0;
     359             :     GMLFeatureClass **m_papoClass = nullptr;
     360             :     bool m_bLookForClassAtAnyLevel = false;
     361             : 
     362             :     char *m_pszFilename = nullptr;
     363             : 
     364             : #ifndef HAVE_XERCES
     365             :     bool bUseExpatReader = true;
     366             : #else
     367             :     bool bUseExpatReader = false;
     368             : #endif
     369             : 
     370             :     GMLHandler *m_poGMLHandler = nullptr;
     371             : 
     372             : #if defined(HAVE_XERCES)
     373             :     SAX2XMLReader *m_poSAXReader = nullptr;
     374             :     XMLPScanToken m_oToFill{};
     375             :     GMLFeature *m_poCompleteFeature = nullptr;
     376             :     InputSource *m_GMLInputSource = nullptr;
     377             :     bool m_bEOF = false;
     378             :     bool m_bXercesInitialized = false;
     379             :     bool SetupParserXerces();
     380             :     GMLFeature *NextFeatureXerces();
     381             : #endif
     382             : 
     383             : #if defined(HAVE_EXPAT)
     384             :     XML_Parser oParser = nullptr;
     385             :     GMLFeature **ppoFeatureTab = nullptr;
     386             :     int nFeatureTabLength = 0;
     387             :     int nFeatureTabIndex = 0;
     388             :     int nFeatureTabAlloc = 0;
     389             :     bool SetupParserExpat();
     390             :     GMLFeature *NextFeatureExpat();
     391             :     char *pabyBuf = nullptr;
     392             :     CPLString m_osErrorMessage{};
     393             : #endif
     394             : 
     395             :     VSILFILE *fpGML = nullptr;
     396             :     bool m_bReadStarted = false;
     397             : 
     398             :     GMLReadState *m_poState = nullptr;
     399             :     GMLReadState *m_poRecycledState = nullptr;
     400             : 
     401             :     bool m_bStopParsing = false;
     402             : 
     403             :     bool SetupParser();
     404             :     void CleanupParser();
     405             : 
     406             :     bool m_bFetchAllGeometries = false;
     407             : 
     408             :     bool m_bInvertAxisOrderIfLatLong = false;
     409             :     bool m_bConsiderEPSGAsURN = false;
     410             :     GMLSwapCoordinatesEnum m_eSwapCoordinates = GML_SWAP_AUTO;
     411             :     bool m_bGetSecondaryGeometryOption = false;
     412             : 
     413             :     int ParseFeatureType(CPLXMLNode *psSchemaNode, const char *pszName,
     414             :                          const char *pszType);
     415             : 
     416             :     char *m_pszGlobalSRSName = nullptr;
     417             :     bool m_bCanUseGlobalSRSName = false;
     418             : 
     419             :     char *m_pszFilteredClassName = nullptr;
     420             :     int m_nFilteredClassIndex = -1;
     421             : 
     422             :     int m_nHasSequentialLayers = -1;
     423             : 
     424             :     std::string osElemPath{};
     425             : 
     426             :     bool m_bFaceHoleNegative = false;
     427             : 
     428             :     bool m_bSetWidthFlag = true;
     429             : 
     430             :     bool m_bReportAllAttributes = false;
     431             : 
     432             :     bool m_bIsWFSJointLayer = false;
     433             : 
     434             :     bool m_bEmptyAsNull = true;
     435             : 
     436             :     bool m_bUseBBOX = false;
     437             : 
     438             :     bool ParseXMLHugeFile(const char *pszOutputFilename,
     439             :                           const bool bSqliteIsTempFile,
     440             :                           const int iSqliteCacheMB);
     441             : 
     442             :     CPL_DISALLOW_COPY_ASSIGN(GMLReader)
     443             : 
     444             :   public:
     445             :     GMLReader(bool bExpatReader, bool bInvertAxisOrderIfLatLong,
     446             :               bool bConsiderEPSGAsURN, GMLSwapCoordinatesEnum eSwapCoordinates,
     447             :               bool bGetSecondaryGeometryOption);
     448             :     virtual ~GMLReader();
     449             : 
     450           0 :     bool IsClassListLocked() const override
     451             :     {
     452           0 :         return m_bClassListLocked;
     453             :     }
     454             : 
     455         436 :     void SetClassListLocked(bool bFlag) override
     456             :     {
     457         436 :         m_bClassListLocked = bFlag;
     458         436 :     }
     459             : 
     460             :     void SetSourceFile(const char *pszFilename) override;
     461             :     void SetFP(VSILFILE *fp) override;
     462             :     const char *GetSourceFileName() override;
     463             : 
     464        3520 :     int GetClassCount() const override
     465             :     {
     466        3520 :         return m_nClassCount;
     467             :     }
     468             : 
     469             :     GMLFeatureClass *GetClass(int i) const override;
     470             :     GMLFeatureClass *GetClass(const char *pszName) const override;
     471             : 
     472             :     int AddClass(GMLFeatureClass *poClass) override;
     473             :     void ClearClasses() override;
     474             : 
     475             :     GMLFeature *NextFeature() override;
     476             : 
     477             :     bool LoadClasses(const char *pszFile = nullptr) override;
     478             :     bool SaveClasses(const char *pszFile = nullptr) override;
     479             : 
     480             :     bool ResolveXlinks(const char *pszFile, bool *pbOutIsTempFile,
     481             :                        char **papszSkip = nullptr,
     482             :                        const bool bStrict = false) override;
     483             : 
     484             :     bool HugeFileResolver(const char *pszFile, bool bSqliteIsTempFile,
     485             :                           int iSqliteCacheMB) override;
     486             : 
     487             :     bool PrescanForSchema(bool bGetExtents = true,
     488             :                           bool bOnlyDetectSRS = false) override;
     489             :     bool PrescanForTemplate() override;
     490             :     bool ReArrangeTemplateClasses(GFSTemplateList *pCC);
     491             :     void ResetReading() override;
     492             : 
     493             :     // ---
     494             : 
     495       57341 :     GMLReadState *GetState() const
     496             :     {
     497       57341 :         return m_poState;
     498             :     }
     499             : 
     500             :     void PopState();
     501             :     void PushState(GMLReadState *);
     502             : 
     503        6299 :     bool ShouldLookForClassAtAnyLevel()
     504             :     {
     505        6299 :         return m_bLookForClassAtAnyLevel;
     506             :     }
     507             : 
     508             :     int GetFeatureElementIndex(const char *pszElement, int nLen,
     509             :                                GMLAppSchemaType eAppSchemaType);
     510             :     int GetAttributeElementIndex(const char *pszElement, int nLen,
     511             :                                  const char *pszAttrKey = nullptr);
     512             :     bool IsCityGMLGenericAttributeElement(const char *pszElement, void *attr);
     513             : 
     514             :     void PushFeature(const char *pszElement, const char *pszFID,
     515             :                      int nClassIndex);
     516             : 
     517             :     void SetFeaturePropertyDirectly(const char *pszElement, char *pszValue,
     518             :                                     int iPropertyIn,
     519             :                                     GMLPropertyType eType = GMLPT_Untyped);
     520             : 
     521           8 :     void SetWidthFlag(bool bFlag)
     522             :     {
     523           8 :         m_bSetWidthFlag = bFlag;
     524           8 :     }
     525             : 
     526         102 :     bool HasStoppedParsing() override
     527             :     {
     528         102 :         return m_bStopParsing;
     529             :     }
     530             : 
     531        3926 :     bool FetchAllGeometries()
     532             :     {
     533        3926 :         return m_bFetchAllGeometries;
     534             :     }
     535             : 
     536             :     void SetGlobalSRSName(const char *pszGlobalSRSName) override;
     537             : 
     538         486 :     const char *GetGlobalSRSName() override
     539             :     {
     540         486 :         return m_pszGlobalSRSName;
     541             :     }
     542             : 
     543        1059 :     bool CanUseGlobalSRSName() override
     544             :     {
     545        1059 :         return m_bCanUseGlobalSRSName;
     546             :     }
     547             : 
     548             :     bool SetFilteredClassName(const char *pszClassName) override;
     549             : 
     550        3738 :     const char *GetFilteredClassName() override
     551             :     {
     552        3738 :         return m_pszFilteredClassName;
     553             :     }
     554             : 
     555          49 :     int GetFilteredClassIndex()
     556             :     {
     557          49 :         return m_nFilteredClassIndex;
     558             :     }
     559             : 
     560          82 :     bool IsSequentialLayers() const override
     561             :     {
     562          82 :         return m_nHasSequentialLayers == TRUE;
     563             :     }
     564             : 
     565         431 :     void SetReportAllAttributes(bool bFlag)
     566             :     {
     567         431 :         m_bReportAllAttributes = bFlag;
     568         431 :     }
     569             : 
     570         509 :     bool ReportAllAttributes() const
     571             :     {
     572         509 :         return m_bReportAllAttributes;
     573             :     }
     574             : 
     575         431 :     void SetIsWFSJointLayer(bool bFlag)
     576             :     {
     577         431 :         m_bIsWFSJointLayer = bFlag;
     578         431 :     }
     579             : 
     580       25516 :     bool IsWFSJointLayer() const
     581             :     {
     582       25516 :         return m_bIsWFSJointLayer;
     583             :     }
     584             : 
     585         431 :     void SetEmptyAsNull(bool bFlag)
     586             :     {
     587         431 :         m_bEmptyAsNull = bFlag;
     588         431 :     }
     589             : 
     590          70 :     bool IsEmptyAsNull() const
     591             :     {
     592          70 :         return m_bEmptyAsNull;
     593             :     }
     594             : 
     595         431 :     void SetUseBBOX(bool bFlag)
     596             :     {
     597         431 :         m_bUseBBOX = bFlag;
     598         431 :     }
     599             : 
     600         904 :     bool UseBBOX() const
     601             :     {
     602         904 :         return m_bUseBBOX;
     603             :     }
     604             : 
     605             :     static CPLMutex *hMutex;
     606             : };
     607             : 
     608             : #endif /* CPL_GMLREADERP_H_INCLUDED */

Generated by: LCOV version 1.14