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 : }