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: 2024-11-21 22:18:42 Functions: 29 30 96.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * $Id$
       3             :  *
       4             :  * Project:  GML Reader
       5             :  * Purpose:  Private Declarations for OGR free GML Reader code.
       6             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2002, Frank Warmerdam
      10             :  * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
      11             :  *
      12             :  * SPDX-License-Identifier: MIT
      13             :  ****************************************************************************/
      14             : 
      15             : #ifndef CPL_GMLREADERP_H_INCLUDED
      16             : #define CPL_GMLREADERP_H_INCLUDED
      17             : 
      18             : #if defined(HAVE_XERCES)
      19             : 
      20             : #include "xercesc_headers.h"
      21             : #include "ogr_xerces.h"
      22             : 
      23             : #endif /* HAVE_XERCES */
      24             : 
      25             : #include "cpl_string.h"
      26             : #include "gmlreader.h"
      27             : #include "ogr_api.h"
      28             : #include "cpl_vsi.h"
      29             : #include "cpl_multiproc.h"
      30             : #include "gmlutils.h"
      31             : 
      32             : #include <map>
      33             : #include <string>
      34             : #include <vector>
      35             : 
      36             : #define PARSER_BUF_SIZE (10 * 8192)
      37             : 
      38             : class GMLReader;
      39             : 
      40             : typedef struct _GeometryNamesStruct GeometryNamesStruct;
      41             : 
      42             : bool OGRGMLIsGeometryElement(const char *pszElement);
      43             : 
      44             : /************************************************************************/
      45             : /*                        GFSTemplateList                               */
      46             : /************************************************************************/
      47             : 
      48             : class GFSTemplateItem;
      49             : 
      50             : class GFSTemplateList
      51             : {
      52             :   private:
      53             :     bool m_bSequentialLayers;
      54             :     GFSTemplateItem *pFirst;
      55             :     GFSTemplateItem *pLast;
      56             :     GFSTemplateItem *Insert(const char *pszName);
      57             : 
      58             :     CPL_DISALLOW_COPY_ASSIGN(GFSTemplateList)
      59             : 
      60             :   public:
      61             :     GFSTemplateList();
      62             :     ~GFSTemplateList();
      63             :     void Update(const char *pszName, int bHasGeom);
      64             : 
      65           6 :     GFSTemplateItem *GetFirst()
      66             :     {
      67           6 :         return pFirst;
      68             :     }
      69             : 
      70           3 :     bool HaveSequentialLayers()
      71             :     {
      72           3 :         return m_bSequentialLayers;
      73             :     }
      74             : 
      75             :     int GetClassCount();
      76             : };
      77             : 
      78             : void gmlUpdateFeatureClasses(GFSTemplateList *pCC, GMLReader *pReader,
      79             :                              int *pnHasSequentialLayers);
      80             : 
      81             : /************************************************************************/
      82             : /*                              GMLHandler                              */
      83             : /************************************************************************/
      84             : 
      85             : #define STACK_SIZE 5
      86             : 
      87             : typedef enum
      88             : {
      89             :     STATE_TOP,
      90             :     STATE_DEFAULT,
      91             :     STATE_FEATURE,
      92             :     STATE_PROPERTY,
      93             :     STATE_FEATUREPROPERTY,
      94             :     STATE_GEOMETRY,
      95             :     STATE_IGNORED_FEATURE,
      96             :     STATE_BOUNDED_BY,
      97             :     STATE_BOUNDED_BY_IN_FEATURE,
      98             :     STATE_CITYGML_ATTRIBUTE
      99             : } HandlerState;
     100             : 
     101             : typedef struct
     102             : {
     103             :     CPLXMLNode *psNode;
     104             :     CPLXMLNode *psLastChild;
     105             : } NodeLastChild;
     106             : 
     107             : typedef enum
     108             : {
     109             :     APPSCHEMA_GENERIC,
     110             :     APPSCHEMA_CITYGML,
     111             :     APPSCHEMA_AIXM,
     112             :     APPSCHEMA_MTKGML /* format of National Land Survey Finnish */
     113             : } GMLAppSchemaType;
     114             : 
     115             : class GMLHandler
     116             : {
     117             :     char *m_pszCurField = nullptr;
     118             :     unsigned int m_nCurFieldAlloc = 0;
     119             :     unsigned int m_nCurFieldLen = 0;
     120             :     bool m_bInCurField = false;
     121             :     int m_nAttributeIndex = -1;
     122             :     int m_nAttributeDepth = 0;
     123             : 
     124             :     char *m_pszGeometry = nullptr;
     125             :     unsigned int m_nGeomAlloc = 0;
     126             :     unsigned int m_nGeomLen = 0;
     127             :     int m_nGeometryDepth = 0;
     128             :     bool m_bAlreadyFoundGeometry = false;
     129             :     int m_nGeometryPropertyIndex = 0;
     130             :     std::map<std::string, CPLXMLNode *> m_oMapElementToSubstitute{};
     131             : 
     132             :     int m_nDepth = 0;
     133             :     int m_nDepthFeature = 0;
     134             :     int m_nUnlimitedDepth = -1;  // -1 unknown, 0=false, 1=true
     135             : 
     136             :     int m_inBoundedByDepth = 0;
     137             : 
     138             :     char *m_pszCityGMLGenericAttrName = nullptr;
     139             :     int m_inCityGMLGenericAttrDepth = 0;
     140             : 
     141             :     bool m_bReportHref = false;
     142             :     char *m_pszHref = nullptr;
     143             :     char *m_pszUom = nullptr;
     144             :     char *m_pszValue = nullptr;
     145             :     char *m_pszKieli = nullptr;
     146             : 
     147             :     GeometryNamesStruct *pasGeometryNames = nullptr;
     148             : 
     149             :     std::vector<NodeLastChild> apsXMLNode{};
     150             : 
     151             :     int m_nSRSDimensionIfMissing = 0;
     152             : 
     153             :     OGRErr startElementTop(const char *pszName, int nLenName, void *attr);
     154             : 
     155             :     OGRErr endElementIgnoredFeature();
     156             : 
     157             :     OGRErr startElementBoundedBy(const char *pszName, int nLenName, void *attr);
     158             :     OGRErr endElementBoundedBy();
     159             : 
     160             :     OGRErr endElementBoundedByInFeature();
     161             : 
     162             :     OGRErr startElementFeatureAttribute(const char *pszName, int nLenName,
     163             :                                         void *attr);
     164             :     OGRErr endElementFeature();
     165             : 
     166             :     OGRErr startElementCityGMLGenericAttr(const char *pszName, int nLenName,
     167             :                                           void *attr);
     168             :     OGRErr endElementCityGMLGenericAttr();
     169             : 
     170             :     OGRErr startElementGeometry(const char *pszName, int nLenName, void *attr);
     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         512 :     bool HasStoppedParsing()
     282             :     {
     283         512 :         return m_bStopParsing;
     284             :     }
     285             : 
     286         517 :     void ResetDataHandlerCounter()
     287             :     {
     288         517 :         m_nDataHandlerCounter = 0;
     289         517 :     }
     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         802 :     GMLReadState() = default;
     321         802 :     ~GMLReadState() = default;
     322             : 
     323             :     void PushPath(const char *pszElement, int nLen = -1);
     324             :     void PopPath();
     325             : 
     326        5362 :     const char *GetLastComponent() const
     327             :     {
     328        5362 :         return (m_nPathLength == 0)
     329        5362 :                    ? ""
     330        5362 :                    : aosPathComponents[m_nPathLength - 1].c_str();
     331             :     }
     332             : 
     333        5178 :     size_t GetLastComponentLen() const
     334             :     {
     335        5178 :         return (m_nPathLength == 0)
     336        5178 :                    ? 0
     337        5178 :                    : 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         401 :     void SetClassListLocked(bool bFlag) override
     456             :     {
     457         401 :         m_bClassListLocked = bFlag;
     458         401 :     }
     459             : 
     460             :     void SetSourceFile(const char *pszFilename) override;
     461             :     void SetFP(VSILFILE *fp) override;
     462             :     const char *GetSourceFileName() override;
     463             : 
     464        3358 :     int GetClassCount() const override
     465             :     {
     466        3358 :         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       53727 :     GMLReadState *GetState() const
     496             :     {
     497       53727 :         return m_poState;
     498             :     }
     499             : 
     500             :     void PopState();
     501             :     void PushState(GMLReadState *);
     502             : 
     503        6011 :     bool ShouldLookForClassAtAnyLevel()
     504             :     {
     505        6011 :         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          93 :     bool HasStoppedParsing() override
     527             :     {
     528          93 :         return m_bStopParsing;
     529             :     }
     530             : 
     531        3710 :     bool FetchAllGeometries()
     532             :     {
     533        3710 :         return m_bFetchAllGeometries;
     534             :     }
     535             : 
     536             :     void SetGlobalSRSName(const char *pszGlobalSRSName) override;
     537             : 
     538         468 :     const char *GetGlobalSRSName() override
     539             :     {
     540         468 :         return m_pszGlobalSRSName;
     541             :     }
     542             : 
     543        1009 :     bool CanUseGlobalSRSName() override
     544             :     {
     545        1009 :         return m_bCanUseGlobalSRSName;
     546             :     }
     547             : 
     548             :     bool SetFilteredClassName(const char *pszClassName) override;
     549             : 
     550        3594 :     const char *GetFilteredClassName() override
     551             :     {
     552        3594 :         return m_pszFilteredClassName;
     553             :     }
     554             : 
     555          49 :     int GetFilteredClassIndex()
     556             :     {
     557          49 :         return m_nFilteredClassIndex;
     558             :     }
     559             : 
     560          81 :     bool IsSequentialLayers() const override
     561             :     {
     562          81 :         return m_nHasSequentialLayers == TRUE;
     563             :     }
     564             : 
     565         396 :     void SetReportAllAttributes(bool bFlag)
     566             :     {
     567         396 :         m_bReportAllAttributes = bFlag;
     568         396 :     }
     569             : 
     570         433 :     bool ReportAllAttributes() const
     571             :     {
     572         433 :         return m_bReportAllAttributes;
     573             :     }
     574             : 
     575         396 :     void SetIsWFSJointLayer(bool bFlag)
     576             :     {
     577         396 :         m_bIsWFSJointLayer = bFlag;
     578         396 :     }
     579             : 
     580       23830 :     bool IsWFSJointLayer() const
     581             :     {
     582       23830 :         return m_bIsWFSJointLayer;
     583             :     }
     584             : 
     585         396 :     void SetEmptyAsNull(bool bFlag)
     586             :     {
     587         396 :         m_bEmptyAsNull = bFlag;
     588         396 :     }
     589             : 
     590          31 :     bool IsEmptyAsNull() const
     591             :     {
     592          31 :         return m_bEmptyAsNull;
     593             :     }
     594             : 
     595         396 :     void SetUseBBOX(bool bFlag)
     596             :     {
     597         396 :         m_bUseBBOX = bFlag;
     598         396 :     }
     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