Blame addon/doxmlparser/src/basehandler.h

Packit 1c1d7e
/******************************************************************************
Packit 1c1d7e
 *
Packit 1c1d7e
 * $Id$
Packit 1c1d7e
 *
Packit 1c1d7e
 *
Packit 1c1d7e
 * Copyright (C) 1997-2015 by Dimitri van Heesch.
Packit 1c1d7e
 *
Packit 1c1d7e
 * Permission to use, copy, modify, and distribute this software and its
Packit 1c1d7e
 * documentation under the terms of the GNU General Public License is hereby 
Packit 1c1d7e
 * granted. No representations are made about the suitability of this software 
Packit 1c1d7e
 * for any purpose. It is provided "as is" without express or implied warranty.
Packit 1c1d7e
 * See the GNU General Public License for more details.
Packit 1c1d7e
 *
Packit 1c1d7e
 */
Packit 1c1d7e
Packit 1c1d7e
#ifndef _BASEHANDLER_H
Packit 1c1d7e
#define _BASEHANDLER_H
Packit 1c1d7e
Packit 1c1d7e
#include <qxml.h>
Packit 1c1d7e
#include <qdict.h>
Packit 1c1d7e
#include <qstring.h>
Packit 1c1d7e
Packit 1c1d7e
#include "debug.h"
Packit 1c1d7e
Packit 1c1d7e
//-----------------------------------------------------------------------------
Packit 1c1d7e
Packit 1c1d7e
class IBaseHandler
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    virtual void setDelegate(QXmlDefaultHandler *delegate) = 0;
Packit 1c1d7e
    virtual QXmlDefaultHandler *delegate() const = 0;
Packit 1c1d7e
    virtual ~IBaseHandler() {}
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
//-----------------------------------------------------------------------------
Packit 1c1d7e
Packit 1c1d7e
class IFallBackHandler
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    virtual bool handleStartElement(const QString & name, 
Packit 1c1d7e
                                    const QXmlAttributes & attrib) = 0;
Packit 1c1d7e
    virtual bool handleEndElement(const QString &name) = 0;
Packit 1c1d7e
    virtual ~IFallBackHandler() {}
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
//-----------------------------------------------------------------------------
Packit 1c1d7e
Packit 1c1d7e
template<class T> class ElementMapper
Packit 1c1d7e
{
Packit 1c1d7e
    class StartElementHandler
Packit 1c1d7e
    {
Packit 1c1d7e
         typedef void (T::*Handler)(const QXmlAttributes &attrib);
Packit 1c1d7e
       public:
Packit 1c1d7e
         StartElementHandler() : m_parent(0) {}
Packit 1c1d7e
         StartElementHandler(T *parent, Handler h) 
Packit 1c1d7e
           : m_parent(parent), m_handler(h) {}
Packit 1c1d7e
         void operator()(const QXmlAttributes &attrib) 
Packit 1c1d7e
           { if (m_parent) (m_parent->*m_handler)(attrib); }
Packit 1c1d7e
       private:
Packit 1c1d7e
         T *m_parent;
Packit 1c1d7e
         Handler m_handler;
Packit 1c1d7e
    };
Packit 1c1d7e
Packit 1c1d7e
    class EndElementHandler
Packit 1c1d7e
    {
Packit 1c1d7e
        typedef void (T::*Handler)();
Packit 1c1d7e
      public:
Packit 1c1d7e
        EndElementHandler() : m_parent(0) {}
Packit 1c1d7e
        EndElementHandler(T *parent, Handler h) 
Packit 1c1d7e
          : m_parent(parent), m_handler(h) {}
Packit 1c1d7e
        void operator()() 
Packit 1c1d7e
          { if (m_parent) (m_parent->*m_handler)(); }
Packit 1c1d7e
      private:
Packit 1c1d7e
        T *m_parent;
Packit 1c1d7e
        Handler m_handler;
Packit 1c1d7e
    };
Packit 1c1d7e
Packit 1c1d7e
  public:
Packit 1c1d7e
    typedef StartElementHandler StartElementHandlerT;
Packit 1c1d7e
    typedef EndElementHandler   EndElementHandlerT;
Packit 1c1d7e
	  
Packit 1c1d7e
    ElementMapper() : m_startHandlers(67), m_endHandlers(67)
Packit 1c1d7e
    {
Packit 1c1d7e
      m_startHandlers.setAutoDelete(TRUE);
Packit 1c1d7e
      m_endHandlers.setAutoDelete(TRUE);
Packit 1c1d7e
    }
Packit 1c1d7e
    virtual ~ElementMapper()
Packit 1c1d7e
    {
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void addStartHandler(const char *key)
Packit 1c1d7e
    {
Packit 1c1d7e
      m_startHandlers.insert(key,new StartElementHandlerT);
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void addStartHandler(const char *key, T *obj, void (T::*handler)(const QXmlAttributes &))
Packit 1c1d7e
    {
Packit 1c1d7e
      m_startHandlers.insert(key,new StartElementHandlerT(obj,handler));
Packit 1c1d7e
    }
Packit 1c1d7e
    
Packit 1c1d7e
    void addEndHandler(const char *key)
Packit 1c1d7e
    {
Packit 1c1d7e
      m_endHandlers.insert(key,new EndElementHandlerT);
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void addEndHandler(const char *key, T *obj, void (T::*handler)())
Packit 1c1d7e
    {
Packit 1c1d7e
      m_endHandlers.insert(key,new EndElementHandlerT(obj,handler));
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
  protected:
Packit 1c1d7e
    QDict<StartElementHandlerT> m_startHandlers;
Packit 1c1d7e
    QDict<EndElementHandlerT>   m_endHandlers;
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
//-----------------------------------------------------------------------------
Packit 1c1d7e
Packit 1c1d7e
struct LocatorContainer
Packit 1c1d7e
{
Packit 1c1d7e
    static QXmlLocator *s_theLocator;
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
//-----------------------------------------------------------------------------
Packit 1c1d7e
Packit 1c1d7e
template<class T> class BaseHandler : public QXmlDefaultHandler,
Packit 1c1d7e
                                      public ElementMapper<T>,
Packit 1c1d7e
                                      public LocatorContainer,
Packit 1c1d7e
                                      public IBaseHandler
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    typedef typename ElementMapper<T>::StartElementHandlerT StartElementHandlerT;
Packit 1c1d7e
    typedef typename ElementMapper<T>::EndElementHandlerT EndElementHandlerT;
Packit 1c1d7e
Packit 1c1d7e
    BaseHandler() : m_skipCount(0), m_delegateHandler(0), m_fallBackHandler(0)
Packit 1c1d7e
    {
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    virtual ~BaseHandler() 
Packit 1c1d7e
    {
Packit 1c1d7e
      ASSERT(m_delegateHandler==0);
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    virtual bool startDocument() 
Packit 1c1d7e
    {
Packit 1c1d7e
      return TRUE;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    virtual bool startElement(  const QString & namespaceURI, 
Packit 1c1d7e
                                const QString & localName, 
Packit 1c1d7e
                                const QString & name, 
Packit 1c1d7e
                                const QXmlAttributes & attrib
Packit 1c1d7e
                             )
Packit 1c1d7e
    {
Packit 1c1d7e
      if (m_delegateHandler) 
Packit 1c1d7e
      {
Packit 1c1d7e
        return m_delegateHandler->startElement(namespaceURI,localName,name,attrib);
Packit 1c1d7e
      }
Packit 1c1d7e
      if (!m_skipUntil.isEmpty()) // skip mode 
Packit 1c1d7e
      {
Packit 1c1d7e
        if (m_skipUntil==name) m_skipCount++;
Packit 1c1d7e
        debug(1,"line %d, col %d: skipping start tag %s count=%d\n",
Packit 1c1d7e
            s_theLocator->lineNumber(),s_theLocator->columnNumber(),
Packit 1c1d7e
            name.data(),m_skipCount);
Packit 1c1d7e
        return TRUE; 
Packit 1c1d7e
      }
Packit 1c1d7e
Packit 1c1d7e
      StartElementHandlerT *handler = ElementMapper<T>::m_startHandlers[name.utf8()];
Packit 1c1d7e
      if (handler)
Packit 1c1d7e
      {
Packit 1c1d7e
        (*handler)(attrib);
Packit 1c1d7e
        //printf("found start tag %s\n",name.data());
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (!m_fallBackHandler ||
Packit 1c1d7e
               !m_fallBackHandler->handleStartElement(name,attrib)
Packit 1c1d7e
              )
Packit 1c1d7e
      {
Packit 1c1d7e
        debug(1,"line %d, col %d: found unexpected tag `%s', skipping until matching end tag\n",
Packit 1c1d7e
            s_theLocator->lineNumber(),s_theLocator->columnNumber(),
Packit 1c1d7e
            name.data());
Packit 1c1d7e
        m_skipUntil = name;
Packit 1c1d7e
        m_skipCount=1;
Packit 1c1d7e
      }
Packit 1c1d7e
      return TRUE;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    virtual bool endElement( const QString& namespaceURI, const QString& localName, const QString& name )
Packit 1c1d7e
    {
Packit 1c1d7e
      if (m_delegateHandler) 
Packit 1c1d7e
      {
Packit 1c1d7e
        return m_delegateHandler->endElement(namespaceURI,localName,name);
Packit 1c1d7e
      }
Packit 1c1d7e
Packit 1c1d7e
      if (name==m_skipUntil)
Packit 1c1d7e
      {
Packit 1c1d7e
        m_skipCount--;
Packit 1c1d7e
        debug(1,"line %d, col %d: skipping end tag %s count=%d\n",
Packit 1c1d7e
            s_theLocator->lineNumber(),s_theLocator->columnNumber(),
Packit 1c1d7e
            name.data(),m_skipCount);
Packit 1c1d7e
        if (m_skipCount==0)
Packit 1c1d7e
        {
Packit 1c1d7e
          m_skipUntil="";
Packit 1c1d7e
        }
Packit 1c1d7e
        //printf("found end tag %s\n",name.data());
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (m_skipUntil.isEmpty())
Packit 1c1d7e
      {
Packit 1c1d7e
        EndElementHandlerT *handler = ElementMapper<T>::m_endHandlers[name.utf8()];
Packit 1c1d7e
        if (handler)
Packit 1c1d7e
        {
Packit 1c1d7e
          (*handler)();
Packit 1c1d7e
          //printf("found end tag %s\n",name.data());
Packit 1c1d7e
        }
Packit 1c1d7e
        else if (m_fallBackHandler)
Packit 1c1d7e
        {
Packit 1c1d7e
          m_fallBackHandler->handleEndElement(name);
Packit 1c1d7e
        }
Packit 1c1d7e
      }
Packit 1c1d7e
      m_curString="";
Packit 1c1d7e
      return TRUE;
Packit 1c1d7e
    }
Packit 1c1d7e
    
Packit 1c1d7e
    bool skippedEntity ( const QString &s )
Packit 1c1d7e
    {
Packit 1c1d7e
      if (m_delegateHandler)
Packit 1c1d7e
      {
Packit 1c1d7e
        return m_delegateHandler->skippedEntity(s);
Packit 1c1d7e
      }
Packit 1c1d7e
      
Packit 1c1d7e
      debug(1,"line %d, col %d: Skipped unhandled entity %s\n",
Packit 1c1d7e
          s_theLocator->lineNumber(),s_theLocator->columnNumber(),
Packit 1c1d7e
          s.data());
Packit 1c1d7e
      return TRUE;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    /*! called when a number of characters are received by the parser.
Packit 1c1d7e
     *  \param ch the characters.
Packit 1c1d7e
     */
Packit 1c1d7e
    virtual bool characters ( const QString & ch ) 
Packit 1c1d7e
    {
Packit 1c1d7e
      if (m_delegateHandler) 
Packit 1c1d7e
      {
Packit 1c1d7e
        return m_delegateHandler->characters(ch);
Packit 1c1d7e
      }
Packit 1c1d7e
Packit 1c1d7e
      //printf("Found characters \"%s\"\n",ch.data());
Packit 1c1d7e
      m_curString+=ch;
Packit 1c1d7e
      return TRUE;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void setDelegate(QXmlDefaultHandler *delegate)
Packit 1c1d7e
    {
Packit 1c1d7e
      m_delegateHandler = delegate;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    QXmlDefaultHandler *delegate() const
Packit 1c1d7e
    {
Packit 1c1d7e
      return m_delegateHandler;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void setFallBackHandler(IFallBackHandler *h)
Packit 1c1d7e
    {
Packit 1c1d7e
      m_fallBackHandler = h;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    IFallBackHandler *fallBackHandler() const
Packit 1c1d7e
    {
Packit 1c1d7e
      return m_fallBackHandler;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void setDocumentLocator( QXmlLocator * locator )
Packit 1c1d7e
    {
Packit 1c1d7e
      debug(2,"setDocumentLocator(%p)\n",locator);
Packit 1c1d7e
      s_theLocator = locator;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
  protected:
Packit 1c1d7e
    QString                     m_curString;
Packit 1c1d7e
    QString                     m_skipUntil;
Packit 1c1d7e
    int                         m_skipCount;
Packit 1c1d7e
    QXmlDefaultHandler         *m_delegateHandler;
Packit 1c1d7e
    IFallBackHandler           *m_fallBackHandler;
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
//-----------------------------------------------------------------------------
Packit 1c1d7e
Packit 1c1d7e
template<class T> class BaseFallBackHandler : public ElementMapper<T>,
Packit 1c1d7e
                                              public IFallBackHandler
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    typedef typename ElementMapper<T>::StartElementHandlerT StartElementHandlerT;
Packit 1c1d7e
    typedef typename ElementMapper<T>::EndElementHandlerT EndElementHandlerT;
Packit 1c1d7e
Packit 1c1d7e
    BaseFallBackHandler() 
Packit 1c1d7e
    {
Packit 1c1d7e
    }
Packit 1c1d7e
    virtual ~BaseFallBackHandler()
Packit 1c1d7e
    {
Packit 1c1d7e
    }
Packit 1c1d7e
    
Packit 1c1d7e
    bool handleStartElement(const QString & name, 
Packit 1c1d7e
                                    const QXmlAttributes & attrib)
Packit 1c1d7e
    {
Packit 1c1d7e
      StartElementHandlerT *handler = ElementMapper<T>::m_startHandlers[name.utf8()];
Packit 1c1d7e
      if (handler)
Packit 1c1d7e
      {
Packit 1c1d7e
        (*handler)(attrib);
Packit 1c1d7e
        return TRUE;
Packit 1c1d7e
      }
Packit 1c1d7e
      return FALSE;
Packit 1c1d7e
    }
Packit 1c1d7e
    bool handleEndElement(const QString &name)
Packit 1c1d7e
    {
Packit 1c1d7e
      EndElementHandlerT *handler = ElementMapper<T>::m_endHandlers[name.utf8()];
Packit 1c1d7e
      if (handler)
Packit 1c1d7e
      {
Packit 1c1d7e
        (*handler)();
Packit 1c1d7e
        return TRUE;
Packit 1c1d7e
      }
Packit 1c1d7e
      return FALSE;
Packit 1c1d7e
    }
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
#endif