]> git.donarmstrong.com Git - flightcrew.git/blob - src/XercesExtensions/LocationAwareDOMParser.cpp
debian/patches/*: fix quilt-patch-missing-description lintian tag
[flightcrew.git] / src / XercesExtensions / LocationAwareDOMParser.cpp
1 /************************************************************************
2 **
3 **  Copyright (C) 2010  Strahinja Markovic
4 **
5 **  This file is part of FlightCrew.
6 **
7 **  FlightCrew is free software: you can redistribute it and/or modify
8 **  it under the terms of the GNU Lesser General Public License as published
9 **  by the Free Software Foundation, either version 3 of the License, or
10 **  (at your option) any later version.
11 **
12 **  FlightCrew is distributed in the hope that it will be useful,
13 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 **  GNU Lesser General Public License for more details.
16 **
17 **  You should have received a copy of the GNU Lesser General Public License
18 **  along with FlightCrew.  If not, see <http://www.gnu.org/licenses/>.
19 **
20 *************************************************************************/
21
22 #include <xercesc/internal/XMLScanner.hpp>
23 #include <xercesc/dom/DOMNamedNodeMap.hpp>
24 #include "LocationAwareDOMParser.h"
25 #include "LocationInfoDataHandler.h"
26
27 // This can't be a member variable of the parser since it needs to be around
28 // even after the parser is destroyed. The cleanup methods of the parser's
29 // super class call the handle() method of the handler.
30 // We only ever need a single handler and a const one at that... this could
31 // also easily go into a singleton, but this approach is simpler.
32 static const XercesExt::LocationInfoDataHandler LOCATION_DATA_HANDLER;
33 const char *LOCATION_INFO_KEY = "LocationInfoKey";
34 typedef unsigned int uint; 
35
36 namespace XercesExt
37 {
38
39 LocationAwareDOMParser::LocationAwareDOMParser( xc::XMLValidator   *const valToAdopt,
40                                                 xc::MemoryManager  *const manager,
41                                                 xc::XMLGrammarPool *const gramPool )
42     :
43     xc::XercesDOMParser( valToAdopt, manager, gramPool )
44 {
45     m_LocationInfoKey = xc::XMLString::transcode( LOCATION_INFO_KEY );
46 }
47
48
49 LocationAwareDOMParser::~LocationAwareDOMParser()
50 {
51     xc::XMLString::release( &m_LocationInfoKey );
52 }
53
54
55 void LocationAwareDOMParser::startElement( const xc::XMLElementDecl &elemDecl,
56                                            const unsigned int uriId,
57                                            const XMLCh *const prefixName,
58                                            const xc::RefVectorOf< xc::XMLAttr > &attrList,
59                                            const XMLSize_t attrCount,
60                                            const bool isEmpty,
61                                            const bool isRoot )
62 {
63     xc::XercesDOMParser::startElement(
64             elemDecl, uriId, prefixName, attrList, attrCount, isEmpty, isRoot );
65
66     const xc::Locator* locator = getScanner()->getLocator();
67     int line_number   = (int) locator->getLineNumber();
68     int column_number = (int) locator->getColumnNumber();
69
70     xc::DOMNode *current_node = getCurrentNode();
71
72     // It's OK to const_cast the handler since the parser will only ever
73     // call the handler's handle() method, which doesn't mutate the handler.
74     // In fact, this function not accepting a const handler is probably a design
75     // error on the part of Xerces developers.
76     current_node->setUserData( 
77         m_LocationInfoKey,
78         new NodeLocationInfo( line_number, column_number ),
79         const_cast< XercesExt::LocationInfoDataHandler* >( &LOCATION_DATA_HANDLER ) );
80
81     // Attribute nodes get the same location as the opening tag
82     // of the element they were declared in... it's the best we can do.
83     xc::DOMNamedNodeMap *attribute_map = current_node->getAttributes();\r
84     if ( !attribute_map )\r
85 \r
86         return;\r
87 \r
88     for ( uint i = 0; i < attribute_map->getLength(); ++i )\r
89     {\r
90         attribute_map->item( i )->setUserData( 
91             m_LocationInfoKey,
92             new NodeLocationInfo( line_number, column_number ),
93             const_cast< XercesExt::LocationInfoDataHandler* >( &LOCATION_DATA_HANDLER ) );
94     }
95 }
96
97 }