LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/ili - ili2handler.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 59 66 89.4 %
Date: 2024-11-21 22:18:42 Functions: 8 10 80.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  Interlis 2 Reader
       4             :  * Purpose:  Implementation of ILI2Handler class.
       5             :  * Author:   Markus Schnider, Sourcepole AG
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2004, Pirmin Kalberer, Sourcepole AG
       9             :  * Copyright (c) 2008, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "cpl_conv.h"
      15             : #include "cpl_string.h"
      16             : 
      17             : #include "ili2readerp.h"
      18             : #include "ogr_ili2.h"
      19             : 
      20             : #include <xercesc/sax2/Attributes.hpp>
      21             : 
      22             : using namespace gdal::ili2;
      23             : 
      24             : //
      25             : // constants
      26             : //
      27             : static const char *const ILI2_DATASECTION = "DATASECTION";
      28             : 
      29             : //
      30             : // ILI2Handler
      31             : //
      32           4 : ILI2Handler::ILI2Handler(ILI2Reader *poReader)
      33             :     : m_poReader(poReader), level(0), dom_doc(nullptr), dom_elem(nullptr),
      34           4 :       m_nEntityCounter(0)
      35             : {
      36           4 :     XMLCh *tmpCh = XMLString::transcode("CORE");
      37             :     DOMImplementation *impl =
      38           4 :         DOMImplementationRegistry::getDOMImplementation(tmpCh);
      39           4 :     XMLString::release(&tmpCh);
      40             : 
      41             :     // the root element
      42           4 :     tmpCh = XMLString::transcode("ROOT");
      43           4 :     dom_doc = impl->createDocument(nullptr, tmpCh, nullptr);
      44           4 :     XMLString::release(&tmpCh);
      45             : 
      46             :     // the first element is root
      47           4 :     dom_elem = dom_doc->getDocumentElement();
      48           4 : }
      49             : 
      50           8 : ILI2Handler::~ILI2Handler()
      51             : {
      52             :     // remove all elements
      53           4 :     DOMNode *tmpNode = dom_doc->getFirstChild();
      54           8 :     while (tmpNode != nullptr)
      55             :     {
      56           4 :         /*tmpNode = */ dom_doc->removeChild(tmpNode);
      57           4 :         tmpNode = dom_doc->getFirstChild();
      58             :     }
      59             : 
      60             :     // release the dom tree
      61           4 :     dom_doc->release();
      62           8 : }
      63             : 
      64           4 : void ILI2Handler::startDocument()
      65             : {
      66             :     // the level counter starts with DATASECTION
      67           4 :     level = -1;
      68           4 :     m_nEntityCounter = 0;
      69           4 : }
      70             : 
      71           4 : void ILI2Handler::endDocument()
      72             : {
      73             :     // nothing to do
      74           4 : }
      75             : 
      76       10341 : void ILI2Handler::startElement(const XMLCh *const /* uri */,
      77             :                                const XMLCh *const /* localname */,
      78             :                                const XMLCh *const qname,
      79             :                                const Attributes &attrs)
      80             : {
      81             :     // start to add the layers, features with the DATASECTION
      82       10341 :     char *tmpC = nullptr;
      83       10341 :     m_nEntityCounter = 0;
      84       10483 :     if ((level >= 0) ||
      85       10483 :         (cmpStr(ILI2_DATASECTION, tmpC = XMLString::transcode(qname)) == 0))
      86             :     {
      87       10203 :         level++;
      88             : 
      89       10203 :         if (level >= 2)
      90             :         {
      91             : 
      92             :             // create the dom tree
      93             :             DOMElement *elem =
      94       10195 :                 reinterpret_cast<DOMElement *>(dom_doc->createElement(qname));
      95             : 
      96             :             // add all attributes
      97       10195 :             unsigned int len = static_cast<unsigned int>(attrs.getLength());
      98       11230 :             for (unsigned int index = 0; index < len; index++)
      99        1035 :                 elem->setAttribute(attrs.getQName(index),
     100        1035 :                                    attrs.getValue(index));
     101       10195 :             dom_elem->appendChild(elem);
     102       10195 :             dom_elem = elem;
     103             :         }
     104             :     }
     105       10341 :     XMLString::release(&tmpC);
     106       10341 : }
     107             : 
     108       10341 : void ILI2Handler::endElement(CPL_UNUSED const XMLCh *const uri,
     109             :                              CPL_UNUSED const XMLCh *const localname,
     110             :                              CPL_UNUSED const XMLCh *const qname)
     111             : {
     112       10341 :     m_nEntityCounter = 0;
     113       10341 :     if (level >= 0)
     114             :     {
     115       10203 :         if (level == 2)
     116             :         {
     117             : 
     118             :             // go to the parent element and parse the child element
     119         522 :             DOMElement *childElem = dom_elem;
     120         522 :             dom_elem = (DOMElement *)dom_elem->getParentNode();
     121             : 
     122         522 :             m_poReader->AddFeature(childElem);
     123             : 
     124             :             // remove the child element
     125         522 :             /*childElem = (DOMElement*)*/ dom_elem->removeChild(childElem);
     126             :         }
     127        9681 :         else if (level >= 3)
     128             :         {
     129             : 
     130             :             // go to the parent element
     131        9673 :             dom_elem =
     132        9673 :                 reinterpret_cast<DOMElement *>(dom_elem->getParentNode());
     133             :         }
     134       10203 :         level--;
     135             :     }
     136       10341 : }
     137             : 
     138             : /************************************************************************/
     139             : /*                     characters() (xerces 3 version)                  */
     140             : /************************************************************************/
     141             : 
     142        7691 : void ILI2Handler::characters(const XMLCh *const chars,
     143             :                              CPL_UNUSED const XMLSize_t length)
     144             : {
     145             :     // add the text element
     146        7691 :     if (level >= 3)
     147             :     {
     148        6686 :         char *tmpC = XMLString::transcode(chars);
     149             : 
     150             :         // only add the text if it is not empty
     151        6686 :         if (trim(tmpC) != "")
     152        5633 :             dom_elem->appendChild(dom_doc->createTextNode(chars));
     153             : 
     154        6686 :         XMLString::release(&tmpC);
     155             :     }
     156        7691 : }
     157             : 
     158           0 : void ILI2Handler::startEntity(CPL_UNUSED const XMLCh *const name)
     159             : {
     160           0 :     m_nEntityCounter++;
     161           0 :     if (m_nEntityCounter > 1000)
     162             :     {
     163             :         throw SAXNotSupportedException(
     164           0 :             "File probably corrupted (million laugh pattern)");
     165             :     }
     166           0 : }
     167             : 
     168           0 : void ILI2Handler::fatalError(const SAXParseException &)
     169             : {
     170             :     // FIXME Error handling
     171           0 : }

Generated by: LCOV version 1.14