LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/gml - gmlreaderp.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 63 65 96.9 %
Date: 2024-05-07 17:03:27 Functions: 26 27 96.3 %

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

Generated by: LCOV version 1.14