1 : /**********************************************************************
2 : * $Id: reader.cpp 17910 2009-10-27 02:07:33Z chaitanya $
3 : *
4 : * Project: iom - The INTERLIS Object Model
5 : * Purpose: For more information, please see <http://iom.sourceforge.net>
6 : * Author: Claude Eisenhut
7 : *
8 : **********************************************************************
9 : * Copyright (c) 2007, Claude Eisenhut
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 OR
22 : * 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 :
31 : /** @file
32 : * adapter to xml parser
33 : * @defgroup reader xml reader functions
34 : * @{
35 : */
36 :
37 : #include <cassert>
38 : #include <cstring>
39 :
40 : #include <xercesc/util/XMLString.hpp>
41 : #include <xercesc/sax/Locator.hpp>
42 : #include <xercesc/sax2/XMLReaderFactory.hpp>
43 : #include <xercesc/sax2/Attributes.hpp>
44 :
45 : #include <iom/iom_p.h>
46 :
47 : XMLStringPool *ParserHandler::namev=0;
48 :
49 :
50 : /** read complete HEADERSECTION
51 : * Requires: call to setFilename()
52 : */
53 12 : int iom_file::readHeader(const char *model)
54 : {
55 12 : handler=dbgnew class ParserHandler(this,model);
56 12 : parser=XMLReaderFactory::createXMLReader();
57 : // Do not report validation errors
58 12 : parser->setFeature(XMLUni::fgSAX2CoreValidation, false);
59 : // use scanner that performs well-formedness checking only.
60 12 : parser->setProperty(XMLUni::fgXercesScannerName,(void *)XMLUni::fgWFXMLScanner);
61 24 : parser->setContentHandler(handler);
62 12 : parser->setEntityResolver(handler);
63 12 : parser->setErrorHandler(handler);
64 12 : return readLoop(filename);
65 : }
66 :
67 :
68 12 : int iom_file::readLoop(const char *filename)
69 : {
70 : try
71 : {
72 12 : if (!parser->parseFirst(filename, token))
73 : {
74 0 : iom_issueerr("scanFirst() failed");
75 0 : return IOM_ERR_XMLPARSER;
76 : }
77 12 : bool gotMore = true;
78 46350 : while (gotMore && !parser->getErrorCount()){
79 46326 : gotMore = parser->parseNext(token);
80 : }
81 12 : parser->parseReset(token);
82 : }
83 0 : catch (const XMLException& toCatch)
84 : {
85 0 : char* message = XMLString::transcode(toCatch.getMessage());
86 0 : iom_issueerr(message);
87 0 : XMLString::release(&message);
88 0 : return IOM_ERR_XMLPARSER;
89 : }
90 0 : catch (const SAXException& toCatch)
91 : {
92 0 : char* message = XMLString::transcode(toCatch.getMessage());
93 0 : iom_issueerr(message);
94 0 : XMLString::release(&message);
95 0 : return IOM_ERR_XMLPARSER;
96 : }
97 12 : return 0;
98 : }
99 :
100 :
101 : /** read one (next) basket
102 : */
103 0 : int iom_file::readBasket(IomFile file)
104 : {
105 0 : return 1;
106 : }
107 :
108 : /** sets filename
109 : */
110 12 : void iom_file::setFilename(const char *filename1)
111 : {
112 12 : if(filename)free((void *)filename);
113 12 : filename=strdup(filename1);
114 12 : }
115 :
116 : /** @}
117 : */
118 :
119 : //#include <xercesc/util/XMLUniDefs.hpp>
120 : //#include <xercesc/util/XMLUni.hpp>
121 : //#include <xercesc/sax/AttributeList.hpp>
122 :
123 12461 : Element::Element()
124 : : object(0)
125 : , propertyName(0)
126 : , oid(0)
127 : , bid(0)
128 12461 : , orderPos(0)
129 : {
130 12461 : }
131 24922 : Element::Element(const Element& src)
132 : : object(src.object)
133 : , propertyName(src.propertyName)
134 : , oid(XMLString::replicate(src.oid))
135 : , bid(XMLString::replicate(src.bid))
136 24922 : , orderPos(src.orderPos)
137 : {
138 24922 : }
139 0 : Element& Element::operator=(const Element& src){
140 0 : if(this!=&src){
141 0 : object=src.object;
142 0 : if(bid){
143 0 : XMLString::release(&bid);
144 : }
145 0 : if(src.bid){
146 0 : bid=XMLString::replicate(src.bid);
147 : }
148 0 : if(oid){
149 0 : XMLString::release(&oid);
150 : }
151 0 : if(src.oid){
152 0 : oid=XMLString::replicate(src.oid);
153 : }
154 0 : propertyName=src.propertyName;
155 0 : orderPos=src.orderPos;
156 : }
157 0 : return *this;
158 : }
159 37383 : Element::~Element(){
160 37383 : if(bid)XMLString::release(&bid);
161 37383 : if(oid)XMLString::release(&oid);
162 37383 : }
163 :
164 4605 : const XMLCh *Element::getOid()
165 : {
166 4605 : return oid;
167 : }
168 :
169 4605 : void Element::setOid(const XMLCh *oid1)
170 : {
171 4605 : if(oid)XMLString::release(&oid);
172 4605 : oid=XMLString::replicate(oid1);
173 4605 : }
174 :
175 4605 : const XMLCh *Element::getBid()
176 : {
177 4605 : return bid;
178 : }
179 :
180 0 : void Element::setBid(const XMLCh *bid1)
181 : {
182 0 : if(bid)XMLString::release(&bid);
183 0 : bid=XMLString::replicate(bid1);
184 0 : }
185 :
186 4605 : unsigned int Element::getOrderPos()
187 : {
188 4605 : return orderPos;
189 : }
190 :
191 4605 : void Element::setOrderPos(unsigned int value)
192 : {
193 4605 : orderPos=value;
194 4605 : }
195 :
196 7784 : static const XMLCh* stripX(const XMLCh* value)
197 : {
198 7784 : if(XMLString::startsWith(value,X("x"))){
199 7784 : return value+1;
200 : }
201 0 : return value;
202 : }
203 :
204 12 : ParserHandler::ParserHandler(struct iom_file *inputfile,const char* model1)
205 : : locator(0)
206 : ,file(inputfile)
207 : ,model(model1 ? strdup(model1) : 0)
208 : ,skip(0)
209 : ,level(0)
210 : ,state(BEFORE_TRANSFER)
211 : ,dataContainer(0)
212 : ,object(0)
213 12 : ,m_nEntityCounter(0)
214 : {
215 : // setupTag2MetaobjMapping();
216 12 : }
217 :
218 12 : ParserHandler::~ParserHandler()
219 : {
220 12 : if(model){
221 12 : free(model);
222 12 : model=0;
223 : }
224 12 : }
225 :
226 0 : bool xisClassDef(int tag)
227 : {
228 0 : const XMLCh *const type=ParserHandler::getTagName(tag);
229 0 : if(!XMLString::compareString(type,X("iom04.metamodel.Table"))){
230 0 : return true;
231 : }
232 0 : return false;
233 : }
234 0 : bool xisAssociationDef(int tag)
235 : {
236 0 : const XMLCh *const type=ParserHandler::getTagName(tag);
237 0 : if(!XMLString::compareString(type,X("iom04.metamodel.AssociationDef"))){
238 0 : return true;
239 : }
240 0 : return false;
241 : }
242 0 : bool xisTopicDef(int tag)
243 : {
244 0 : const XMLCh *const type=ParserHandler::getTagName(tag);
245 0 : if(!XMLString::compareString(type,X("iom04.metamodel.Topic"))){
246 0 : return true;
247 : }
248 0 : return false;
249 : }
250 :
251 0 : void ParserHandler::startEntity (const XMLCh *const name)
252 : {
253 0 : m_nEntityCounter ++;
254 0 : if (m_nEntityCounter > 1000)
255 : {
256 0 : throw SAXNotSupportedException ("File probably corrupted (million laugh pattern)");
257 : }
258 0 : }
259 :
260 19888 : void ParserHandler::startElement (const XMLCh *const uri
261 : , const XMLCh *const localname
262 : , const XMLCh *const qname
263 : , const Attributes &attrs)
264 : {
265 19888 : level++;
266 19888 : m_nEntityCounter = 0;
267 19888 : if(skip>0){
268 4200 : skip++;
269 4200 : return;
270 : }
271 15688 : int tag=getTagId(localname);
272 15688 : if(state==BEFORE_TRANSFER && tag==tags::get_TRANSFER()){
273 12 : state=BEFORE_DATASECTION;
274 12 : return;
275 : }
276 15676 : if(state==BEFORE_DATASECTION && tag==tags::get_HEADERSECTION()){
277 12 : const XMLCh* sender=0;
278 12 : const XMLCh* version=0;
279 36 : for(unsigned int attri=0;attri<attrs.getLength();attri++){
280 24 : if(!XMLString::compareString(attrs.getLocalName(attri),ustrings::get_SENDER())){
281 12 : sender=attrs.getValue(attri);
282 : }
283 24 : if(!XMLString::compareString(attrs.getLocalName(attri),ustrings::get_VERSION())){
284 12 : version=attrs.getValue(attri);
285 : }
286 :
287 : }
288 12 : if(!sender){
289 : // SENDER is mandatory
290 0 : iom_issueparserr("Attribute SENDER missing in file ",IOM_ERRKIND_MISSING,locator->getLineNumber(),locator->getColumnNumber());
291 : }else{
292 12 : file->setHeadSecSender(sender);
293 : }
294 12 : if(!version){
295 : // VERSION is mandatory
296 0 : iom_issueparserr("Attribute VERSION missing in file ",IOM_ERRKIND_MISSING,locator->getLineNumber(),locator->getColumnNumber());
297 : }else{
298 12 : file->setHeadSecVersion(version);
299 12 : if (XMLString::compareString(version,X("2.2")))
300 : {
301 0 : iom_issueparserr("The VERSION attribute must be \"2.2\"",IOM_ERRKIND_INVALID,locator->getLineNumber(),locator->getColumnNumber());
302 : }
303 :
304 : }
305 12 : state=START_HEADERSECTION;
306 12 : return;
307 : }
308 :
309 15664 : if(state==BEFORE_DATASECTION && tag==tags::get_DATASECTION()){
310 12 : state=BEFORE_BASKET;
311 12 : return;
312 : }
313 15652 : if(state==BEFORE_BASKET){
314 12 : const XMLCh* bid=0;
315 12 : const XMLCh* consistency=0;
316 24 : for(unsigned int attri=0;attri<attrs.getLength();attri++){
317 12 : if(!XMLString::compareString(attrs.getLocalName(attri),ustrings::get_BID())){
318 12 : bid=attrs.getValue(attri);
319 : }
320 12 : if(!XMLString::compareString(attrs.getLocalName(attri),ustrings::get_CONSISTENCY())){
321 0 : consistency=attrs.getValue(attri);
322 : }
323 : }
324 12 : dataContainer=dbgnew struct iom_basket();
325 12 : dataContainer->setXMLLineNumber(locator->getLineNumber());
326 12 : dataContainer->setXMLColumnNumber(locator->getColumnNumber());
327 12 : if(!bid){
328 : // BOID is mandatory
329 0 : iom_issueparserr("Attribute BID missing in basket ",IOM_ERRKIND_MISSING,locator->getLineNumber(),locator->getColumnNumber());
330 : }else{
331 12 : dataContainer->setOid(stripX(bid));
332 : }
333 12 : if(consistency){
334 0 : if(!XMLString::compareString(consistency,ustrings::get_COMPLETE())){
335 0 : dataContainer->setConsistency(IOM_COMPLETE);
336 0 : }else if(!XMLString::compareString(consistency,ustrings::get_INCOMPLETE())){
337 0 : dataContainer->setConsistency(IOM_INCOMPLETE);
338 0 : }else if(!XMLString::compareString(consistency,ustrings::get_INCONSISTENT())){
339 0 : dataContainer->setConsistency(IOM_INCONSISTENT);
340 0 : }else if(!XMLString::compareString(consistency,ustrings::get_ADAPTED())){
341 0 : dataContainer->setConsistency(IOM_ADAPTED);
342 : }else{
343 0 : iom_issueparserr("Attribute CONSISTENCY has wrong value in basket ",IOM_ERRKIND_INVALID,locator->getLineNumber(),locator->getColumnNumber());
344 : }
345 : }
346 12 : dataContainer->setTag(tag);
347 12 : dataContainer->file=file;
348 12 : state=BEFORE_OBJECT;
349 12 : return;
350 : }
351 : // SegmentSequence
352 15640 : if(state==SS_AFTER_COORD){
353 0 : pushReturnState(SS_AFTER_COORD);
354 0 : if(tag==tags::get_COORD()){
355 0 : state=CV_COORD;
356 0 : object=dbgnew struct iom_object();
357 0 : object->setTag(tags::get_COORD());
358 : }else{
359 0 : state=ST_BEFORE_PROPERTY;
360 0 : object=dbgnew struct iom_object();
361 0 : object->setTag(tag);
362 : }
363 0 : return;
364 : }
365 :
366 : // PolylineValue
367 15640 : if((state==PV_POLYLINE
368 : || state==PV_AFTER_LINEATTR)
369 : && tag==tags::get_CLIPPED()){
370 0 : state=PV_CLIPPED;
371 0 : changeReturnState(PV_AFTER_CLIPPED);
372 0 : object->setConsistency(IOM_INCOMPLETE);
373 0 : return;
374 : }
375 15640 : if(state==PV_POLYLINE && tag==tags::get_LINEATTR()){
376 0 : state=PV_LINEATTR;
377 0 : return;
378 : }
379 15640 : if(state==PV_LINEATTR){
380 0 : pushReturnState(PV_AFTER_LINEATTRSTRUCT);
381 0 : state=ST_BEFORE_PROPERTY;
382 0 : object=dbgnew struct iom_object();
383 0 : object->setTag(tag);
384 0 : return;
385 : }
386 15640 : if(state==PV_AFTER_CLIPPED && tag==tags::get_CLIPPED()){
387 0 : state=PV_CLIPPED;
388 0 : pushReturnState(PV_AFTER_CLIPPED);
389 0 : return;
390 : }
391 15640 : if((state==PV_POLYLINE
392 : || state==PV_CLIPPED
393 : || state==PV_AFTER_LINEATTR)
394 : && tag==tags::get_COORD()){
395 0 : pushReturnState(SS_AFTER_COORD);
396 0 : object=dbgnew struct iom_object();
397 0 : object->setTag(tags::get_SEGMENTS());
398 0 : Element ele;
399 0 : ele.object=object;
400 0 : ele.propertyName=tags::get_segment();
401 0 : objStack.push(ele);
402 0 : state=CV_COORD;
403 0 : object=dbgnew struct iom_object();
404 0 : object->setTag(tags::get_COORD());
405 0 : return;
406 : }
407 :
408 : // SurfaceValue
409 15640 : if(state==SV_SURFACE && tag==tags::get_CLIPPED()){
410 0 : state=SV_CLIPPED;
411 0 : changeReturnState(SV_AFTER_CLIPPED);
412 0 : Element top=objStack.top();objStack.pop();
413 0 : Element ele=objStack.top();
414 0 : objStack.push(top);
415 0 : ele.object->setConsistency(IOM_INCOMPLETE);
416 0 : return;
417 : }
418 15640 : if(state==SV_AFTER_CLIPPED && tag==tags::get_CLIPPED()){
419 0 : pushReturnState(SV_AFTER_CLIPPED);
420 0 : state=SV_CLIPPED;
421 0 : object=dbgnew struct iom_object();
422 0 : object->setTag(tags::get_SURFACE());
423 0 : Element ele;
424 0 : ele.object=object;
425 0 : ele.propertyName=tags::get_boundary();
426 0 : objStack.push(ele);
427 0 : return;
428 : }
429 15640 : if((state==SV_SURFACE || state==SV_CLIPPED
430 : || state==BD_AFTER_BOUNDARY)
431 : && tag==tags::get_BOUNDARY()){
432 0 : object=dbgnew struct iom_object();
433 0 : object->setTag(tags::get_BOUNDARY());
434 0 : Element ele;
435 0 : ele.object=object;
436 0 : ele.propertyName=tags::get_polyline();
437 0 : objStack.push(ele);
438 0 : state=BD_BOUNDARY;
439 0 : return;
440 : }
441 15640 : if((state==BD_BOUNDARY || state==BD_AFTER_POLYLINE)
442 : && tags::get_POLYLINE()){
443 0 : pushReturnState(BD_AFTER_POLYLINE);
444 0 : state=PV_POLYLINE;
445 0 : object=dbgnew struct iom_object();
446 0 : object->setTag(tags::get_POLYLINE());
447 0 : Element ele;
448 0 : ele.object=object;
449 0 : ele.propertyName=tags::get_sequence();
450 0 : objStack.push(ele);
451 0 : return;
452 : }
453 :
454 : // CoordValue
455 15640 : if(state==CV_COORD && tag==tags::get_C1()){
456 0 : state=CV_C1;
457 : // ensure we save collected characters only inside C1
458 0 : propertyValue.reset();
459 0 : return;
460 : }
461 15640 : if(state==CV_AFTER_C1 && tag==tags::get_C2()){
462 0 : state=CV_C2;
463 : // ensure we save collected characters only inside C2
464 0 : propertyValue.reset();
465 0 : return;
466 : }
467 15640 : if(state==CV_AFTER_C2 && tag==tags::get_C3()){
468 0 : state=CV_C3;
469 : // ensure we save collected characters only inside C3
470 0 : propertyValue.reset();
471 0 : return;
472 : }
473 15640 : if(state==ST_BEFORE_CHARACTERS && tag==tags::get_SURFACE()){
474 0 : pushReturnState(ST_AFTER_SURFACE);
475 0 : state=SV_SURFACE;
476 0 : object=dbgnew struct iom_object();
477 0 : object->setTag(tags::get_MULTISURFACE());
478 0 : Element ele;
479 0 : ele.object=object;
480 0 : ele.propertyName=tags::get_surface();
481 0 : objStack.push(ele);
482 0 : object=dbgnew struct iom_object();
483 0 : object->setTag(tags::get_SURFACE());
484 : //ele=ceisnew Element();
485 0 : ele.object=object;
486 0 : ele.propertyName=tags::get_boundary();
487 0 : objStack.push(ele);
488 0 : return;
489 : }
490 15640 : if(state==ST_BEFORE_CHARACTERS && tag==tags::get_POLYLINE()){
491 0 : pushReturnState(ST_AFTER_POLYLINE);
492 0 : state=PV_POLYLINE;
493 0 : object=dbgnew struct iom_object();
494 0 : object->setTag(tags::get_POLYLINE());
495 0 : Element ele;
496 0 : ele.object=object;
497 0 : ele.propertyName=tags::get_sequence();
498 0 : objStack.push(ele);
499 0 : return;
500 : }
501 15640 : if(state==ST_BEFORE_CHARACTERS && tag==tags::get_COORD()){
502 0 : pushReturnState(ST_AFTER_COORD);
503 0 : state=CV_COORD;
504 0 : object=dbgnew struct iom_object();
505 0 : object->setTag(tags::get_COORD());
506 0 : return;
507 : }
508 :
509 15640 : if(state==BEFORE_OBJECT || state==ST_AFTER_STRUCTVALUE
510 : || state==ST_BEFORE_CHARACTERS
511 : || state==ST_BEFORE_EMBASSOC){
512 :
513 : // start StructValue
514 3167 : if(state==BEFORE_OBJECT){
515 3167 : pushReturnState(BEFORE_OBJECT);
516 0 : }else if(state==ST_AFTER_STRUCTVALUE){
517 0 : pushReturnState(ST_AFTER_STRUCTVALUE);
518 0 : }else if(state==ST_BEFORE_CHARACTERS){
519 0 : pushReturnState(ST_AFTER_STRUCTVALUE);
520 0 : }else if(state==ST_BEFORE_EMBASSOC){
521 0 : pushReturnState(ST_BEFORE_EMBASSOC);
522 : }
523 3167 : state=ST_BEFORE_PROPERTY;
524 3167 : const XMLCh* operation=0;
525 3167 : const XMLCh* oid=0;
526 3167 : const XMLCh* objBid=0;
527 3167 : const XMLCh* consistency=0;
528 6334 : for(unsigned int attri=0;attri<attrs.getLength();attri++){
529 3167 : if(!XMLString::compareString(attrs.getLocalName(attri),ustrings::get_TID())){
530 3167 : oid=attrs.getValue(attri);
531 : }
532 3167 : if(!XMLString::compareString(attrs.getLocalName(attri),ustrings::get_BID())){
533 0 : objBid=attrs.getValue(attri);
534 : }
535 3167 : if(!XMLString::compareString(attrs.getLocalName(attri),ustrings::get_OPERATION())){
536 0 : operation=attrs.getValue(attri);
537 : }
538 3167 : if(!XMLString::compareString(attrs.getLocalName(attri),ustrings::get_CONSISTENCY())){
539 0 : consistency=attrs.getValue(attri);
540 : }
541 : }
542 3167 : object=dbgnew struct iom_object();
543 3167 : object->setTag(tag);
544 3167 : object->setXMLLineNumber(locator->getLineNumber());
545 3167 : object->setXMLColumnNumber(locator->getColumnNumber());
546 3167 : if(oid){
547 3167 : object->setOid(stripX(oid));
548 : }
549 3167 : if(objBid){
550 0 : object->setBid(stripX(objBid));
551 : }
552 3167 : if(operation){
553 0 : if(!XMLString::compareString(operation,ustrings::get_INSERT())){
554 0 : object->setOperation(IOM_OP_INSERT);
555 0 : }else if(!XMLString::compareString(operation,ustrings::get_UPDATE())){
556 0 : object->setOperation(IOM_OP_UPDATE);
557 0 : }else if(!XMLString::compareString(operation,ustrings::get_DELETE())){
558 0 : object->setOperation(IOM_OP_DELETE);
559 : }else{
560 0 : iom_issueparserr("Attribute OPERATION has wrong value in object ",IOM_ERRKIND_INVALID,locator->getLineNumber(),locator->getColumnNumber());
561 : }
562 : }
563 3167 : if(consistency){
564 0 : if(!XMLString::compareString(consistency,ustrings::get_COMPLETE())){
565 0 : object->setConsistency(IOM_COMPLETE);
566 0 : }else if(!XMLString::compareString(consistency,ustrings::get_INCOMPLETE())){
567 0 : object->setConsistency(IOM_INCOMPLETE);
568 0 : }else if(!XMLString::compareString(consistency,ustrings::get_INCONSISTENT())){
569 0 : object->setConsistency(IOM_INCONSISTENT);
570 0 : }else if(!XMLString::compareString(consistency,ustrings::get_ADAPTED())){
571 0 : object->setConsistency(IOM_ADAPTED);
572 : }else{
573 0 : iom_issueparserr("Attribute CONSISTENCY has wrong value in object ",IOM_ERRKIND_INVALID,locator->getLineNumber(),locator->getColumnNumber());
574 : }
575 : }
576 3167 : return;
577 : }
578 12473 : if(state==ST_BEFORE_PROPERTY){
579 12461 : if(object.isNull()){
580 : //throw new IllegalStateException();
581 0 : assert(false);
582 : }
583 : // attribute ->characters
584 : // struct ->startElement
585 : // ref (refattr) ->endElement
586 : // ref (role) ->endElement
587 : // ref (embedded assoc) ->startElement or EndElement
588 12461 : const XMLCh* oid=0;
589 12461 : const XMLCh* objBid=0;
590 12461 : unsigned int orderPos=0;
591 17984 : for(unsigned int attri=0;attri<attrs.getLength();attri++){
592 5523 : if(!XMLString::compareString(attrs.getLocalName(attri),ustrings::get_REF())){
593 4605 : oid=attrs.getValue(attri);
594 : }
595 5523 : if(!XMLString::compareString(attrs.getLocalName(attri),ustrings::get_BID())){
596 0 : objBid=attrs.getValue(attri);
597 : }
598 5523 : if(!XMLString::compareString(attrs.getLocalName(attri),ustrings::get_EXTREF())){
599 0 : oid=attrs.getValue(attri);
600 : }
601 5523 : if(!XMLString::compareString(attrs.getLocalName(attri),ustrings::get_ORDER_POS())){
602 918 : bool done=XMLString::textToBin(attrs.getValue(attri),orderPos);
603 918 : if(!done || orderPos==0){
604 : // illgegal value
605 0 : iom_issueparserr("Attribute ORDER_POS has wrong value in object ",IOM_ERRKIND_INVALID,locator->getLineNumber(),locator->getColumnNumber());
606 0 : orderPos=0;
607 : }
608 : }
609 : }
610 : // save name,oid,bid
611 : // push state
612 12461 : Element ele;
613 12461 : ele.object=object;
614 12461 : ele.propertyName=tag;
615 12461 : if(oid){
616 4605 : if(objBid){
617 0 : ele.setBid(stripX(objBid));
618 : }
619 4605 : ele.setOid(stripX(oid));
620 4605 : ele.setOrderPos(orderPos);
621 : }
622 12461 : objStack.push(ele);
623 12461 : object=0;
624 12461 : if(oid){
625 4605 : state=ST_BEFORE_EMBASSOC;
626 : }else{
627 7856 : state=ST_BEFORE_CHARACTERS;
628 : }
629 : // ensure we save collected characters only inside
630 : // a property and not after a struct value
631 12461 : propertyValue.reset();
632 12461 : return;
633 : }
634 12 : skip=1;
635 : }
636 :
637 19888 : void ParserHandler::endElement (const XMLCh *const uri
638 : , const XMLCh *const localname
639 : , const XMLCh *const qname)
640 : {
641 19888 : level--;
642 19888 : m_nEntityCounter = 0;
643 19888 : if(skip>0){
644 4212 : skip--;
645 4212 : return;
646 : }
647 :
648 : // SegmentSequence
649 15676 : if(state==SS_AFTER_COORD){
650 0 : popReturnState();
651 0 : if(state==ST_AFTER_POLYLINE){
652 0 : Element ele=objStack.top();objStack.pop();
653 0 : object=ele.object; // SEGMENTS
654 0 : ele=objStack.top();objStack.pop();
655 0 : ele.object->parser_addAttrValue(ele.propertyName,object);
656 0 : object=ele.object; // POLYLINE
657 0 : }else if(state==BD_AFTER_POLYLINE){
658 0 : Element ele=objStack.top();objStack.pop();
659 0 : object=ele.object; // SEGMENTS
660 0 : ele=objStack.top();objStack.pop();
661 0 : ele.object->parser_addAttrValue(ele.propertyName,object);
662 0 : object=ele.object; // POLYLINE
663 0 : ele=objStack.top();
664 0 : ele.object->parser_addAttrValue(ele.propertyName,object);
665 0 : object=0;
666 0 : }else if(state==PV_AFTER_CLIPPED){
667 0 : Element ele=objStack.top();objStack.pop();
668 0 : object=ele.object; // SEGMENTS
669 0 : ele=objStack.top();
670 0 : ele.object->parser_addAttrValue(ele.propertyName,object);
671 0 : object=0;
672 : }else{
673 : //throw new IllegalStateException();
674 0 : assert(false);
675 : }
676 15676 : }else if(state==PV_AFTER_CLIPPED){
677 0 : Element ele=objStack.top();objStack.pop();
678 0 : object=ele.object; // POLYLINE
679 0 : state=ST_AFTER_POLYLINE;
680 15676 : }else if(state==PV_AFTER_LINEATTRSTRUCT){
681 0 : state=PV_AFTER_LINEATTR;
682 : // Boundaries
683 15676 : }else if(state==BD_AFTER_POLYLINE){
684 0 : Element ele=objStack.top();objStack.pop();
685 0 : object=ele.object; // BOUNDARY
686 0 : ele=objStack.top();
687 0 : ele.object->parser_addAttrValue(ele.propertyName,object);
688 : //Dumper dumper=new Dumper();
689 : //dumper.dumpObject(System.err,ele.object);
690 0 : object=0;
691 0 : state=BD_AFTER_BOUNDARY;
692 : // SurfaceValue
693 15676 : }else if(state==BD_AFTER_BOUNDARY){
694 0 : popReturnState();
695 0 : if(state==ST_AFTER_SURFACE){
696 0 : Element ele=objStack.top();objStack.pop();
697 0 : object=ele.object; // SURFACE
698 0 : ele=objStack.top();
699 0 : ele.object->parser_addAttrValue(ele.propertyName,object);
700 0 : }else if(state==SV_AFTER_CLIPPED){
701 0 : Element ele=objStack.top();objStack.pop();
702 0 : object=ele.object; // SURFACE
703 0 : ele=objStack.top();
704 0 : ele.object->parser_addAttrValue(ele.propertyName,object);
705 : }else{
706 : //throw new IllegalStateException("state "+state);
707 0 : assert(false);
708 : }
709 15676 : }else if(state==SV_AFTER_CLIPPED){
710 0 : state=ST_AFTER_SURFACE;
711 : // CoordValue
712 15676 : }else if(state==CV_AFTER_C1 || state==CV_AFTER_C2 || state==CV_AFTER_C3){
713 0 : popReturnState();
714 0 : if(state==SS_AFTER_COORD){
715 : // part of SEGMENTS
716 0 : Element ele=objStack.top();
717 0 : ele.object->parser_addAttrValue(ele.propertyName,object);
718 : //Dumper dumper=new Dumper();
719 : //dumper.dumpObject(System.err,ele.object);
720 0 : object=0;
721 0 : }else if(state==ST_AFTER_COORD){
722 : }else{
723 : //throw new IllegalStateException();
724 0 : assert(false);
725 : }
726 15676 : }else if(state==CV_C1){
727 0 : object->parser_addAttrValue(tags::get_C1(),propertyValue.getRawBuffer());
728 0 : propertyValue.reset();
729 0 : state=CV_AFTER_C1;
730 15676 : }else if(state==CV_C2){
731 0 : object->parser_addAttrValue(tags::get_C2(),propertyValue.getRawBuffer());
732 0 : propertyValue.reset();
733 0 : state=CV_AFTER_C2;
734 15676 : }else if(state==CV_C3){
735 0 : object->parser_addAttrValue(tags::get_C3(),propertyValue.getRawBuffer());
736 0 : propertyValue.reset();
737 0 : state=CV_AFTER_C3;
738 :
739 : // StructValue
740 23532 : }else if(state==ST_AFTER_STRUCTVALUE
741 : || state==ST_BEFORE_CHARACTERS){
742 : // attribute
743 : // struct
744 7856 : Element ele=objStack.top();objStack.pop();
745 7856 : if(state==ST_BEFORE_CHARACTERS){
746 : // attribute
747 : // may be: illegal whitespace, legal whitespace, not whitespace
748 7856 : ele.object->parser_addAttrValue(ele.propertyName,propertyValue.getRawBuffer());
749 : }else{
750 : // bag of structvalues
751 : // added to ele.object in endElement of structvalue
752 : }
753 7856 : object=ele.object;
754 7856 : propertyValue.reset();
755 7856 : state=ST_BEFORE_PROPERTY;
756 7820 : }else if(state==ST_BEFORE_EMBASSOC){
757 : // ref (refattr)
758 : // ref (role)
759 : // ref (embedded assoc) with or without assocattrs
760 4605 : Element ele=objStack.top();objStack.pop();
761 4605 : if(object.isNull()){
762 : // ref (refattr)
763 : // ref (role)
764 : // ref (embedded assoc) without assocattrs
765 4605 : object=dbgnew struct iom_object();
766 : }else{
767 : // ref (embedded assoc) with assocattrs
768 : }
769 4605 : object->setRefOid(ele.getOid());
770 4605 : object->setRefBid(ele.getBid());
771 4605 : object->setRefOrderPos(ele.getOrderPos());
772 4605 : ele.object->parser_addAttrValue(ele.propertyName,object);
773 4605 : object=ele.object;
774 4605 : propertyValue.reset();
775 4605 : state=ST_BEFORE_PROPERTY;
776 3215 : }else if(state==ST_AFTER_COORD){
777 : // attr of type COORD
778 0 : Element ele=objStack.top();objStack.pop();
779 0 : ele.object->parser_addAttrValue(ele.propertyName,object);
780 0 : object=ele.object;
781 0 : state=ST_BEFORE_PROPERTY;
782 0 : propertyValue.reset();
783 3215 : }else if(state==ST_AFTER_POLYLINE){
784 : // attr of type POLYLINE
785 0 : Element ele=objStack.top();objStack.pop();
786 0 : ele.object->parser_addAttrValue(ele.propertyName,object);
787 0 : object=ele.object;
788 0 : state=ST_BEFORE_PROPERTY;
789 0 : propertyValue.reset();
790 3215 : }else if(state==ST_AFTER_SURFACE){
791 : // attr of type SURFACE/AREA
792 0 : Element ele=objStack.top();objStack.pop();
793 0 : object=ele.object; // MULTISURFACE
794 0 : ele=objStack.top();objStack.pop();
795 0 : ele.object->parser_addAttrValue(ele.propertyName,object);
796 0 : object=ele.object;
797 0 : state=ST_BEFORE_PROPERTY;
798 0 : propertyValue.reset();
799 3215 : }else if(state==ST_BEFORE_PROPERTY){
800 3167 : popReturnState();
801 3167 : if(state==BEFORE_OBJECT){
802 3167 : dataContainer->addObject(object);
803 6334 : object=0;
804 : }else{
805 0 : if(state==ST_AFTER_STRUCTVALUE){
806 0 : Element ele=objStack.top();
807 0 : ele.object->parser_addAttrValue(ele.propertyName,object);
808 0 : object=0;
809 0 : }else if(state==PV_AFTER_LINEATTRSTRUCT){
810 0 : Element ele=objStack.top();
811 0 : ele.object->parser_addAttrValue(tags::get_lineattr(),object);
812 0 : object=0;
813 0 : }else if(state==SS_AFTER_COORD){
814 : // part of SEGMENTS
815 0 : Element ele=objStack.top();
816 0 : ele.object->parser_addAttrValue(ele.propertyName,object);
817 : //Dumper dumper=new Dumper();
818 : //dumper.dumpObject(System.err,ele.object);
819 0 : object=0;
820 : }
821 : }
822 48 : }else if(state==BEFORE_OBJECT){
823 12 : file->addBasket(dataContainer);
824 24 : dataContainer=0;
825 12 : state=BEFORE_BASKET;
826 36 : }else if(state==BEFORE_BASKET){
827 12 : state=BEFORE_DATASECTION;
828 24 : }else if(state==START_HEADERSECTION){
829 12 : state=BEFORE_DATASECTION;
830 12 : }else if(state==BEFORE_DATASECTION){
831 12 : state=BEFORE_TRANSFER;
832 : }
833 :
834 : }
835 :
836 :
837 : #if XERCES_VERSION_MAJOR >= 3
838 : /************************************************************************/
839 : /* characters() (xerces 3 version) */
840 : /************************************************************************/
841 :
842 : void ParserHandler::characters( const XMLCh* const chars,
843 : const XMLSize_t length )
844 : {
845 : if( state==ST_BEFORE_CHARACTERS
846 : || state==CV_C1
847 : || state==CV_C2
848 : || state==CV_C3 )
849 : {
850 : propertyValue.append(chars,length);
851 : }
852 : }
853 :
854 : #else
855 : /************************************************************************/
856 : /* characters() (xerces 2 version) */
857 : /************************************************************************/
858 :
859 15331 : void ParserHandler::characters( const XMLCh* const chars,
860 : const unsigned int length )
861 : {
862 15331 : if( state==ST_BEFORE_CHARACTERS
863 : || state==CV_C1
864 : || state==CV_C2
865 : || state==CV_C3 )
866 : {
867 7856 : propertyValue.append(chars,length);
868 : }
869 15331 : }
870 : #endif
871 :
872 0 : void ParserHandler::error(const SAXParseException& e)
873 : {
874 : #if 0
875 : std::cerr << "\nSAX Error at file " << StrX(e.getSystemId())
876 : << ", line " << e.getLineNumber()
877 : << ", char " << e.getColumnNumber()
878 : << "\n Message: " << StrX(e.getMessage()) << std::endl;
879 : #endif
880 0 : iom_issueparserr(StrX(e.getMessage()).localForm(),IOM_ERRKIND_XMLPARSER,e.getLineNumber(),e.getColumnNumber());
881 0 : }
882 :
883 0 : void ParserHandler::fatalError(const SAXParseException& e)
884 : {
885 : #if 0
886 : std::cerr << "\nSAX Error at file " << StrX(e.getSystemId())
887 : << ", line " << e.getLineNumber()
888 : << ", char " << e.getColumnNumber()
889 : << "\n Message: " << StrX(e.getMessage()) << std::endl;
890 : #endif
891 0 : iom_issueparserr(StrX(e.getMessage()).localForm(),IOM_ERRKIND_XMLPARSER,e.getLineNumber(),e.getColumnNumber());
892 0 : }
893 :
894 0 : void ParserHandler::warning(const SAXParseException& e)
895 : {
896 : #if 0
897 : std::cerr << "\nSAX Error at file " << StrX(e.getSystemId())
898 : << ", line " << e.getLineNumber()
899 : << ", char " << e.getColumnNumber()
900 : << "\n Message: " << StrX(e.getMessage()) << std::endl;
901 : #endif
902 0 : iom_issueparserr(StrX(e.getMessage()).localForm(),IOM_ERRKIND_XMLPARSER,e.getLineNumber(),e.getColumnNumber());
903 0 : }
904 :
905 12 : void ParserHandler::setDocumentLocator (const Locator *const locator1)
906 : {
907 12 : locator=locator1;
908 12 : }
909 :
910 :
911 : /** pushes a return state for the parser state machine to the stack.
912 : * Used before entering a sub state machine.
913 : */
914 3167 : void ParserHandler::pushReturnState(int returnState){
915 3167 : stateStack.push(returnState);
916 3167 : }
917 :
918 : /** pops a state for the parser state machine from the stack and makes it the
919 : * new current state.
920 : * Used when leaving a sub state machine.
921 : */
922 3167 : void ParserHandler::popReturnState(){
923 3167 : state=stateStack.top();
924 3167 : stateStack.pop();
925 3167 : }
926 :
927 : /** changes the top state on the stack for the parser state machine.
928 : * Used to change the return state of a sub state machine.
929 : */
930 0 : void ParserHandler::changeReturnState(int returnState){
931 0 : stateStack.pop();
932 0 : stateStack.push(returnState);
933 0 : }
934 :
935 :
936 : /** gets the id of an xml-element name
937 : */
938 2485 : int ParserHandler::getTagId(const char *name)
939 : {
940 2485 : if(!namev){
941 : //FIXME namev=dbgnew XMLStringPool();
942 0 : namev=new XMLStringPool();
943 : }
944 2485 : return namev->addOrFind(X(name));
945 : }
946 :
947 : /** gets the id of an xml-element name
948 : */
949 15688 : int ParserHandler::getTagId(const XMLCh *const name)
950 : {
951 15688 : if(!namev){
952 11 : namev=new XMLStringPool();
953 : }
954 15688 : return namev->addOrFind(name);
955 : }
956 :
957 : /** gets the id of an xml-element name
958 : */
959 3167 : const XMLCh *const ParserHandler::getTagName(int tagid)
960 : {
961 3167 : if(!namev){
962 0 : namev=new XMLStringPool();
963 : }
964 3167 : return namev->getValueForId(tagid);
965 : }
966 :
967 : /** cleanup reader module. This function is a part of iom_end().
968 : */
969 11 : void ParserHandler::at_iom_end()
970 : {
971 11 : if(namev){
972 11 : delete namev;
973 11 : namev=0;
974 : }
975 2150 : }
|