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 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "cpl_conv.h"
31 : #include "cpl_string.h"
32 :
33 : #include "ili2readerp.h"
34 : #include "ogr_ili2.h"
35 :
36 : #include <xercesc/sax2/Attributes.hpp>
37 :
38 : using namespace gdal::ili2;
39 :
40 : //
41 : // constants
42 : //
43 : static const char *const ILI2_DATASECTION = "DATASECTION";
44 :
45 : //
46 : // ILI2Handler
47 : //
48 4 : ILI2Handler::ILI2Handler(ILI2Reader *poReader)
49 : : m_poReader(poReader), level(0), dom_doc(nullptr), dom_elem(nullptr),
50 4 : m_nEntityCounter(0)
51 : {
52 4 : XMLCh *tmpCh = XMLString::transcode("CORE");
53 : DOMImplementation *impl =
54 4 : DOMImplementationRegistry::getDOMImplementation(tmpCh);
55 4 : XMLString::release(&tmpCh);
56 :
57 : // the root element
58 4 : tmpCh = XMLString::transcode("ROOT");
59 4 : dom_doc = impl->createDocument(nullptr, tmpCh, nullptr);
60 4 : XMLString::release(&tmpCh);
61 :
62 : // the first element is root
63 4 : dom_elem = dom_doc->getDocumentElement();
64 4 : }
65 :
66 8 : ILI2Handler::~ILI2Handler()
67 : {
68 : // remove all elements
69 4 : DOMNode *tmpNode = dom_doc->getFirstChild();
70 8 : while (tmpNode != nullptr)
71 : {
72 4 : /*tmpNode = */ dom_doc->removeChild(tmpNode);
73 4 : tmpNode = dom_doc->getFirstChild();
74 : }
75 :
76 : // release the dom tree
77 4 : dom_doc->release();
78 8 : }
79 :
80 4 : void ILI2Handler::startDocument()
81 : {
82 : // the level counter starts with DATASECTION
83 4 : level = -1;
84 4 : m_nEntityCounter = 0;
85 4 : }
86 :
87 4 : void ILI2Handler::endDocument()
88 : {
89 : // nothing to do
90 4 : }
91 :
92 10341 : void ILI2Handler::startElement(const XMLCh *const /* uri */,
93 : const XMLCh *const /* localname */,
94 : const XMLCh *const qname,
95 : const Attributes &attrs)
96 : {
97 : // start to add the layers, features with the DATASECTION
98 10341 : char *tmpC = nullptr;
99 10341 : m_nEntityCounter = 0;
100 10483 : if ((level >= 0) ||
101 10483 : (cmpStr(ILI2_DATASECTION, tmpC = XMLString::transcode(qname)) == 0))
102 : {
103 10203 : level++;
104 :
105 10203 : if (level >= 2)
106 : {
107 :
108 : // create the dom tree
109 : DOMElement *elem =
110 10195 : reinterpret_cast<DOMElement *>(dom_doc->createElement(qname));
111 :
112 : // add all attributes
113 10195 : unsigned int len = static_cast<unsigned int>(attrs.getLength());
114 11230 : for (unsigned int index = 0; index < len; index++)
115 1035 : elem->setAttribute(attrs.getQName(index),
116 1035 : attrs.getValue(index));
117 10195 : dom_elem->appendChild(elem);
118 10195 : dom_elem = elem;
119 : }
120 : }
121 10341 : XMLString::release(&tmpC);
122 10341 : }
123 :
124 10341 : void ILI2Handler::endElement(CPL_UNUSED const XMLCh *const uri,
125 : CPL_UNUSED const XMLCh *const localname,
126 : CPL_UNUSED const XMLCh *const qname)
127 : {
128 10341 : m_nEntityCounter = 0;
129 10341 : if (level >= 0)
130 : {
131 10203 : if (level == 2)
132 : {
133 :
134 : // go to the parent element and parse the child element
135 522 : DOMElement *childElem = dom_elem;
136 522 : dom_elem = (DOMElement *)dom_elem->getParentNode();
137 :
138 522 : m_poReader->AddFeature(childElem);
139 :
140 : // remove the child element
141 522 : /*childElem = (DOMElement*)*/ dom_elem->removeChild(childElem);
142 : }
143 9681 : else if (level >= 3)
144 : {
145 :
146 : // go to the parent element
147 9673 : dom_elem =
148 9673 : reinterpret_cast<DOMElement *>(dom_elem->getParentNode());
149 : }
150 10203 : level--;
151 : }
152 10341 : }
153 :
154 : /************************************************************************/
155 : /* characters() (xerces 3 version) */
156 : /************************************************************************/
157 :
158 7691 : void ILI2Handler::characters(const XMLCh *const chars,
159 : CPL_UNUSED const XMLSize_t length)
160 : {
161 : // add the text element
162 7691 : if (level >= 3)
163 : {
164 6686 : char *tmpC = XMLString::transcode(chars);
165 :
166 : // only add the text if it is not empty
167 6686 : if (trim(tmpC) != "")
168 5633 : dom_elem->appendChild(dom_doc->createTextNode(chars));
169 :
170 6686 : XMLString::release(&tmpC);
171 : }
172 7691 : }
173 :
174 0 : void ILI2Handler::startEntity(CPL_UNUSED const XMLCh *const name)
175 : {
176 0 : m_nEntityCounter++;
177 0 : if (m_nEntityCounter > 1000)
178 : {
179 : throw SAXNotSupportedException(
180 0 : "File probably corrupted (million laugh pattern)");
181 : }
182 0 : }
183 :
184 0 : void ILI2Handler::fatalError(const SAXParseException &)
185 : {
186 : // FIXME Error handling
187 0 : }
|