basehandler.h
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * $Id$
4  *
5  *
6  * Copyright (C) 1997-2015 by Dimitri van Heesch.
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation under the terms of the GNU General Public License is hereby
10  * granted. No representations are made about the suitability of this software
11  * for any purpose. It is provided "as is" without express or implied warranty.
12  * See the GNU General Public License for more details.
13  *
14  */
15 
16 #ifndef _BASEHANDLER_H
17 #define _BASEHANDLER_H
18 
19 #include <qxml.h>
20 #include <qdict.h>
21 #include <qstring.h>
22 
23 #include "debug.h"
24 
25 //-----------------------------------------------------------------------------
26 
28 {
29  public:
30  virtual void setDelegate(QXmlDefaultHandler *delegate) = 0;
31  virtual QXmlDefaultHandler *delegate() const = 0;
32  virtual ~IBaseHandler() {}
33 };
34 
35 //-----------------------------------------------------------------------------
36 
38 {
39  public:
40  virtual bool handleStartElement(const QString & name,
41  const QXmlAttributes & attrib) = 0;
42  virtual bool handleEndElement(const QString &name) = 0;
43  virtual ~IFallBackHandler() {}
44 };
45 
46 //-----------------------------------------------------------------------------
47 
48 template<class T> class ElementMapper
49 {
51  {
52  typedef void (T::*Handler)(const QXmlAttributes &attrib);
53  public:
54  StartElementHandler() : m_parent(0) {}
56  : m_parent(parent), m_handler(h) {}
57  void operator()(const QXmlAttributes &attrib)
58  { if (m_parent) (m_parent->*m_handler)(attrib); }
59  private:
61  Handler m_handler;
62  };
63 
65  {
66  typedef void (T::*Handler)();
67  public:
68  EndElementHandler() : m_parent(0) {}
70  : m_parent(parent), m_handler(h) {}
71  void operator()()
72  { if (m_parent) (m_parent->*m_handler)(); }
73  private:
75  Handler m_handler;
76  };
77 
78  public:
79  typedef StartElementHandler StartElementHandlerT;
80  typedef EndElementHandler EndElementHandlerT;
81 
82  ElementMapper() : m_startHandlers(67), m_endHandlers(67)
83  {
84  m_startHandlers.setAutoDelete(TRUE);
85  m_endHandlers.setAutoDelete(TRUE);
86  }
87  virtual ~ElementMapper()
88  {
89  }
90 
91  void addStartHandler(const char *key)
92  {
93  m_startHandlers.insert(key,new StartElementHandlerT);
94  }
95 
96  void addStartHandler(const char *key, T *obj, void (T::*handler)(const QXmlAttributes &))
97  {
98  m_startHandlers.insert(key,new StartElementHandlerT(obj,handler));
99  }
100 
101  void addEndHandler(const char *key)
102  {
103  m_endHandlers.insert(key,new EndElementHandlerT);
104  }
105 
106  void addEndHandler(const char *key, T *obj, void (T::*handler)())
107  {
108  m_endHandlers.insert(key,new EndElementHandlerT(obj,handler));
109  }
110 
111 
112  protected:
113  QDict<StartElementHandlerT> m_startHandlers;
114  QDict<EndElementHandlerT> m_endHandlers;
115 };
116 
117 //-----------------------------------------------------------------------------
118 
120 {
122 };
123 
124 //-----------------------------------------------------------------------------
125 
126 template<class T> class BaseHandler : public QXmlDefaultHandler,
127  public ElementMapper<T>,
128  public LocatorContainer,
129  public IBaseHandler
130 {
131  public:
134 
135  BaseHandler() : m_skipCount(0), m_delegateHandler(0), m_fallBackHandler(0)
136  {
137  }
138 
139  virtual ~BaseHandler()
140  {
141  ASSERT(m_delegateHandler==0);
142  }
143 
144  virtual bool startDocument()
145  {
146  return TRUE;
147  }
148 
149  virtual bool startElement( const QString & namespaceURI,
150  const QString & localName,
151  const QString & name,
152  const QXmlAttributes & attrib
153  )
154  {
155  if (m_delegateHandler)
156  {
157  return m_delegateHandler->startElement(namespaceURI,localName,name,attrib);
158  }
159  if (!m_skipUntil.isEmpty()) // skip mode
160  {
161  if (m_skipUntil==name) m_skipCount++;
162  debug(1,"line %d, col %d: skipping start tag %s count=%d\n",
163  s_theLocator->lineNumber(),s_theLocator->columnNumber(),
164  name.data(),m_skipCount);
165  return TRUE;
166  }
167 
168  StartElementHandlerT *handler = ElementMapper<T>::m_startHandlers[name.utf8()];
169  if (handler)
170  {
171  (*handler)(attrib);
172  //printf("found start tag %s\n",name.data());
173  }
174  else if (!m_fallBackHandler ||
175  !m_fallBackHandler->handleStartElement(name,attrib)
176  )
177  {
178  debug(1,"line %d, col %d: found unexpected tag `%s', skipping until matching end tag\n",
179  s_theLocator->lineNumber(),s_theLocator->columnNumber(),
180  name.data());
181  m_skipUntil = name;
182  m_skipCount=1;
183  }
184  return TRUE;
185  }
186 
187  virtual bool endElement( const QString& namespaceURI, const QString& localName, const QString& name )
188  {
189  if (m_delegateHandler)
190  {
191  return m_delegateHandler->endElement(namespaceURI,localName,name);
192  }
193 
194  if (name==m_skipUntil)
195  {
196  m_skipCount--;
197  debug(1,"line %d, col %d: skipping end tag %s count=%d\n",
198  s_theLocator->lineNumber(),s_theLocator->columnNumber(),
199  name.data(),m_skipCount);
200  if (m_skipCount==0)
201  {
202  m_skipUntil="";
203  }
204  //printf("found end tag %s\n",name.data());
205  }
206  else if (m_skipUntil.isEmpty())
207  {
208  EndElementHandlerT *handler = ElementMapper<T>::m_endHandlers[name.utf8()];
209  if (handler)
210  {
211  (*handler)();
212  //printf("found end tag %s\n",name.data());
213  }
214  else if (m_fallBackHandler)
215  {
216  m_fallBackHandler->handleEndElement(name);
217  }
218  }
219  m_curString="";
220  return TRUE;
221  }
222 
223  bool skippedEntity ( const QString &s )
224  {
225  if (m_delegateHandler)
226  {
227  return m_delegateHandler->skippedEntity(s);
228  }
229 
230  debug(1,"line %d, col %d: Skipped unhandled entity %s\n",
231  s_theLocator->lineNumber(),s_theLocator->columnNumber(),
232  s.data());
233  return TRUE;
234  }
235 
236  /*! called when a number of characters are received by the parser.
237  * \param ch the characters.
238  */
239  virtual bool characters ( const QString & ch )
240  {
241  if (m_delegateHandler)
242  {
243  return m_delegateHandler->characters(ch);
244  }
245 
246  //printf("Found characters \"%s\"\n",ch.data());
247  m_curString+=ch;
248  return TRUE;
249  }
250 
252  {
253  m_delegateHandler = delegate;
254  }
255 
257  {
258  return m_delegateHandler;
259  }
260 
262  {
263  m_fallBackHandler = h;
264  }
265 
267  {
268  return m_fallBackHandler;
269  }
270 
271  void setDocumentLocator( QXmlLocator * locator )
272  {
273  debug(2,"setDocumentLocator(%p)\n",locator);
274  s_theLocator = locator;
275  }
276 
277  protected:
283 };
284 
285 //-----------------------------------------------------------------------------
286 
287 template<class T> class BaseFallBackHandler : public ElementMapper<T>,
288  public IFallBackHandler
289 {
290  public:
293 
295  {
296  }
298  {
299  }
300 
302  const QXmlAttributes & attrib)
303  {
304  StartElementHandlerT *handler = ElementMapper<T>::m_startHandlers[name.utf8()];
305  if (handler)
306  {
307  (*handler)(attrib);
308  return TRUE;
309  }
310  return FALSE;
311  }
313  {
314  EndElementHandlerT *handler = ElementMapper<T>::m_endHandlers[name.utf8()];
315  if (handler)
316  {
317  (*handler)();
318  return TRUE;
319  }
320  return FALSE;
321  }
322 };
323 
324 
325 #endif
static QCString name
Definition: declinfo.cpp:673
bool skippedEntity(const QString &s)
Definition: basehandler.h:223
virtual ~BaseFallBackHandler()
Definition: basehandler.h:297
ElementMapper< T >::EndElementHandlerT EndElementHandlerT
Definition: basehandler.h:133
The QXmlLocator class provides the XML handler classes with information about the actual parsing posi...
Definition: qxml.h:379
ElementMapper< T >::EndElementHandlerT EndElementHandlerT
Definition: basehandler.h:292
QXmlDefaultHandler * m_delegateHandler
Definition: basehandler.h:281
QDict< StartElementHandlerT > m_startHandlers
Definition: basehandler.h:113
QDict< EndElementHandlerT > m_endHandlers
Definition: basehandler.h:114
QXmlDefaultHandler * delegate() const
Definition: basehandler.h:256
virtual bool endElement(const QString &namespaceURI, const QString &localName, const QString &name)
Definition: basehandler.h:187
virtual ~IBaseHandler()
Definition: basehandler.h:32
StartElementHandler StartElementHandlerT
Definition: basehandler.h:79
void setDocumentLocator(QXmlLocator *locator)
Definition: basehandler.h:271
const bool FALSE
Definition: qglobal.h:370
virtual bool characters(const QString &ch)
Definition: basehandler.h:239
static QXmlLocator * s_theLocator
Definition: basehandler.h:121
The QString class provides an abstraction of Unicode text and the classic C null-terminated char arra...
Definition: qstring.h:350
IFallBackHandler * fallBackHandler() const
Definition: basehandler.h:266
void operator()(const QXmlAttributes &attrib)
Definition: basehandler.h:57
StartElementHandler(T *parent, Handler h)
Definition: basehandler.h:55
void addStartHandler(const char *key, T *obj, void(T::*handler)(const QXmlAttributes &))
Definition: basehandler.h:96
virtual QXmlDefaultHandler * delegate() const =0
const char * data() const
Definition: qstring.h:542
QString m_skipUntil
Definition: basehandler.h:279
def key(type, name=None)
Definition: graph.py:13
virtual bool startElement(const QString &namespaceURI, const QString &localName, const QString &name, const QXmlAttributes &attrib)
Definition: basehandler.h:149
virtual void setDelegate(QXmlDefaultHandler *delegate)=0
EndElementHandler EndElementHandlerT
Definition: basehandler.h:80
The QXmlDefaultHandler class provides a default implementation of all XML handler classes...
Definition: qxml.h:472
IFallBackHandler * m_fallBackHandler
Definition: basehandler.h:282
bool handleStartElement(const QString &name, const QXmlAttributes &attrib)
Definition: basehandler.h:301
virtual ~ElementMapper()
Definition: basehandler.h:87
QString m_curString
Definition: basehandler.h:278
ElementMapper< T >::StartElementHandlerT StartElementHandlerT
Definition: basehandler.h:132
void setFallBackHandler(IFallBackHandler *h)
Definition: basehandler.h:261
ElementMapper< T >::StartElementHandlerT StartElementHandlerT
Definition: basehandler.h:291
The QXmlAttributes class provides XML attributes.
Definition: qxml.h:128
static msg_handler handler
Definition: qglobal.cpp:234
void addStartHandler(const char *key)
Definition: basehandler.h:91
bool handleEndElement(const QString &name)
Definition: basehandler.h:312
virtual bool startDocument()
Definition: basehandler.h:144
QCString utf8() const
Definition: qstring.cpp:14507
void addEndHandler(const char *key, T *obj, void(T::*handler)())
Definition: basehandler.h:106
virtual ~BaseHandler()
Definition: basehandler.h:139
static QCString * s
Definition: config.cpp:1042
def parent(G, child, parent_type)
Definition: graph.py:67
const bool TRUE
Definition: qglobal.h:371
EndElementHandler(T *parent, Handler h)
Definition: basehandler.h:69
void setDelegate(QXmlDefaultHandler *delegate)
Definition: basehandler.h:251
void addEndHandler(const char *key)
Definition: basehandler.h:101
#define ASSERT(x)
Definition: qglobal.h:590
virtual ~IFallBackHandler()
Definition: basehandler.h:43