summaryrefslogtreecommitdiffabout
path: root/qtcompat/xml
Side-by-side diff
Diffstat (limited to 'qtcompat/xml') (more/less context) (show whitespace changes)
-rw-r--r--qtcompat/xml/qdom.cpp5692
-rw-r--r--qtcompat/xml/qdom.h611
-rw-r--r--qtcompat/xml/qxml.cpp6087
-rw-r--r--qtcompat/xml/qxml.h674
4 files changed, 13064 insertions, 0 deletions
diff --git a/qtcompat/xml/qdom.cpp b/qtcompat/xml/qdom.cpp
new file mode 100644
index 0000000..b484688
--- a/dev/null
+++ b/qtcompat/xml/qdom.cpp
@@ -0,0 +1,5692 @@
+/****************************************************************************
+** $Id$
+**
+** Implementation of QDomDocument and related classes.
+**
+** Created : 000518
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the XML module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+/******************************************
+ * DOM support is disabled in QT 2.3.7 for sharp zaurus.
+ * Because of that we copied the code from 2.3.7 into qtcompat and enabled it
+ * there.
+ * Copyright (c) 2004 Ulf Schenk
+ *
+ * $Id$
+ ******************************************/
+
+#include "qdom.h"
+
+//US #ifndef QT_NO_DOM
+
+#include "qxml.h"
+#include "qmap.h"
+#include "qtextstream.h"
+#include "qiodevice.h"
+#include "qpixmap.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#if defined(_OS_LINUX_)
+# if defined(__alpha__) || defined(__alpha)
+# define Q_BROKEN_ALPHA
+# endif
+#endif
+
+// template class QDict<QDOM_NodePrivate>;
+
+// NOT REVISED
+
+/**
+ * TODO:
+ * If the document dies, remove all pointers to it from children
+ * which can not be deleted at this time.
+ *
+ * If a node dies and has direct children which can not be deleted,
+ * then remove the pointer to the parent.
+ *
+ * Handle QDomDocumentFragment on insertion correctly.
+ *
+ * createElement and friends create double reference counts.
+ */
+
+/**
+ * Reference counting:
+ *
+ * Some simple rules:
+ * 1) If an intern object returns a pointer to another intern object
+ * then the reference count of the returned object is not increased.
+ * 2) If an extern object is created and gets a pointer to some intern
+ * object, then the extern object increases the intern objects reference count.
+ * 3) If an extern object is deleted, then it decreases the reference count
+ * on its associated intern object and deletes it if nobody else hold references
+ * on the intern object.
+ */
+
+/**************************************************************
+ *
+ * QDOMHandler
+ *
+ **************************************************************/
+
+class QDomHandler : public QXmlDefaultHandler
+{
+public:
+ QDomHandler( QDOM_DocumentPrivate* d );
+ ~QDomHandler();
+
+ // content handler
+ void setDocumentLocator( QXmlLocator* locator );
+ bool endDocument();
+ bool startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts );
+ bool endElement( const QString& namespaceURI, const QString& localName, const QString& qName );
+ bool characters( const QString& ch );
+ bool processingInstruction( const QString& target, const QString& data );
+
+ // error handler
+ bool fatalError( const QXmlParseException& exception );
+
+ // lexical handler
+ bool startCDATA();
+ bool endCDATA();
+ bool startDTD( const QString& name, const QString&, const QString& );
+ bool comment( const QString& ch );
+
+ // decl handler
+ bool externalEntityDecl( const QString &name, const QString &publicId, const QString &systemId ) ;
+
+ // DTD handler
+ bool notationDecl( const QString & name, const QString & publicId, const QString & systemId );
+ bool unparsedEntityDecl( const QString &name, const QString &publicId, const QString &systemId, const QString &notationName ) ;
+
+private:
+ QXmlLocator* loc;
+ QDOM_DocumentPrivate* doc;
+ QDOM_NodePrivate* node;
+ bool cdata;
+};
+
+/*==============================================================*/
+/* Implementation */
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_ImplementationPrivate
+ *
+ **************************************************************/
+
+class QDOM_ImplementationPrivate : public QShared
+{
+public:
+ QDOM_ImplementationPrivate();
+ ~QDOM_ImplementationPrivate();
+
+ QDOM_ImplementationPrivate* clone();
+
+};
+
+QDOM_ImplementationPrivate::QDOM_ImplementationPrivate()
+{
+}
+
+QDOM_ImplementationPrivate::~QDOM_ImplementationPrivate()
+{
+}
+
+QDOM_ImplementationPrivate* QDOM_ImplementationPrivate::clone()
+{
+ QDOM_ImplementationPrivate* p = new QDOM_ImplementationPrivate;
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+/**************************************************************
+ *
+ * QDomImplementation
+ *
+ **************************************************************/
+
+/*!
+ \class QDomImplementation qdom.h
+ \brief The QDomImplementation class provides information about the features
+ of the DOM implementation.
+
+ \module XML
+
+ This class describes the features that are supported by the DOM
+ implementation. Currently only the XML subset of DOM Level 1 is supported.
+
+ Normally you will use the function QDomDocument::implementation() to get the
+ implementation object.
+
+ For further information about the Document Objct Model see
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1/">http://www.w3.org/TR/REC-DOM-Level-1/</a>.
+ For a more general introduction of the DOM implementation see the
+ QDomDocument documentation.
+
+ \sa hasFeature()
+*/
+
+/*!
+ Constructs a QDomImplementation object.
+*/
+QDomImplementation::QDomImplementation()
+{
+ impl = 0;
+}
+
+/*!
+ Copy constructor.
+*/
+QDomImplementation::QDomImplementation( const QDomImplementation& x )
+{
+ impl = x.impl;
+ if ( impl )
+ impl->ref();
+}
+
+/*!
+ \internal
+*/
+QDomImplementation::QDomImplementation( QDOM_ImplementationPrivate* p )
+{
+ // We want to be co-owners, so increase the reference count
+ impl = p;
+}
+
+/*!
+ Assignment operator.
+*/
+QDomImplementation& QDomImplementation::operator= ( const QDomImplementation& x )
+{
+ if ( x.impl )
+ x.impl->ref(); //avoid x=x
+ if ( impl && impl->deref() )
+ delete impl;
+ impl = x.impl;
+
+ return *this;
+}
+
+/*!
+ Returns TRUE if both objects were created from the same QDomDocument.
+*/
+bool QDomImplementation::operator==( const QDomImplementation& x ) const
+{
+ return ( impl == x.impl );
+}
+
+/*!
+ Returns TRUE if both objects were created from different QDomDocuments.
+*/
+bool QDomImplementation::operator!=( const QDomImplementation& x ) const
+{
+ return ( impl != x.impl );
+}
+
+/*!
+ Destructor.
+*/
+QDomImplementation::~QDomImplementation()
+{
+ if ( impl && impl->deref() )
+ delete impl;
+}
+
+/*!
+ The function returns TRUE if QDom implements the requested \a version of a \a
+ feature.
+
+ Currently only the feature "XML" in version "1.0" is supported.
+*/
+bool QDomImplementation::hasFeature( const QString& feature, const QString& version )
+{
+ if ( feature == "XML" )
+ if ( version.isEmpty() || version == "1.0" )
+ return TRUE;
+
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the object was not created by QDomDocument::implementation().
+*/
+bool QDomImplementation::isNull()
+{
+ return ( impl == 0 );
+}
+
+/*==============================================================*/
+/* NodeList */
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_NodeListPrivate
+ *
+ **************************************************************/
+
+class QDOM_NodePrivate : public QShared
+{
+public:
+ QDOM_NodePrivate( QDOM_DocumentPrivate*, QDOM_NodePrivate* parent = 0 );
+ QDOM_NodePrivate( QDOM_NodePrivate* n, bool deep );
+ virtual ~QDOM_NodePrivate();
+
+ QString nodeName() const { return name; }
+ QString nodeValue() const { return value; }
+ void setNodeValue( const QString& v ) { value = v; }
+
+ QDOM_DocumentPrivate* ownerDocument();
+
+ virtual QDOM_NamedNodeMapPrivate* attributes();
+ virtual QDOM_NodePrivate* insertBefore( QDOM_NodePrivate* newChild, QDOM_NodePrivate* refChild );
+ virtual QDOM_NodePrivate* insertAfter( QDOM_NodePrivate* newChild, QDOM_NodePrivate* refChild );
+ virtual QDOM_NodePrivate* replaceChild( QDOM_NodePrivate* newChild, QDOM_NodePrivate* oldChild );
+ virtual QDOM_NodePrivate* removeChild( QDOM_NodePrivate* oldChild );
+ virtual QDOM_NodePrivate* appendChild( QDOM_NodePrivate* newChild );
+
+ QDOM_NodePrivate* namedItem( const QString& name );
+
+ virtual QDOM_NodePrivate* cloneNode( bool deep = TRUE );
+ virtual void clear();
+
+ void setParent( QDOM_NodePrivate* );
+
+ // Dynamic cast
+ virtual bool isAttr() { return FALSE; }
+ virtual bool isCDATASection() { return FALSE; }
+ virtual bool isDocumentFragment() { return FALSE; }
+ virtual bool isDocument() { return FALSE; }
+ virtual bool isDocumentType() { return FALSE; }
+ virtual bool isElement() { return FALSE; }
+ virtual bool isEntityReference() { return FALSE; }
+ virtual bool isText() { return FALSE; }
+ virtual bool isEntity() { return FALSE; }
+ virtual bool isNotation() { return FALSE; }
+ virtual bool isProcessingInstruction() { return FALSE; }
+ virtual bool isCharacterData() { return FALSE; }
+ virtual bool isComment() { return FALSE; }
+
+ virtual void save( QTextStream&, int ) const;
+
+ // Variables
+ QDOM_NodePrivate* prev;
+ QDOM_NodePrivate* next;
+ QDOM_NodePrivate* parent;
+ QDOM_NodePrivate* first;
+ QDOM_NodePrivate* last;
+
+ QString name;
+ QString value;
+};
+
+class QDOM_NodeListPrivate : public QShared
+{
+public:
+ QDOM_NodeListPrivate( QDOM_NodePrivate* );
+ QDOM_NodeListPrivate( QDOM_NodePrivate*, const QString& );
+ virtual ~QDOM_NodeListPrivate();
+
+ virtual bool operator== ( const QDOM_NodeListPrivate& ) const;
+ virtual bool operator!= ( const QDOM_NodeListPrivate& ) const;
+
+ virtual QDOM_NodePrivate* item( int index );
+ virtual uint length() const;
+
+ QDOM_NodePrivate* node_impl;
+ QString tagname;
+};
+
+QDOM_NodeListPrivate::QDOM_NodeListPrivate( QDOM_NodePrivate* n_impl )
+{
+ node_impl = n_impl;
+ if ( node_impl )
+ node_impl->ref();
+}
+
+QDOM_NodeListPrivate::QDOM_NodeListPrivate( QDOM_NodePrivate* n_impl, const QString& name )
+{
+ node_impl = n_impl;
+ if ( node_impl )
+ node_impl->ref();
+ tagname = name;
+}
+
+QDOM_NodeListPrivate::~QDOM_NodeListPrivate()
+{
+ if ( node_impl && node_impl->deref() )
+ delete node_impl;
+}
+
+bool QDOM_NodeListPrivate::operator== ( const QDOM_NodeListPrivate& other ) const
+{
+ return ( node_impl == other.node_impl ) && ( tagname == other.tagname ) ;
+}
+
+bool QDOM_NodeListPrivate::operator!= ( const QDOM_NodeListPrivate& other ) const
+{
+ return ( node_impl != other.node_impl ) || ( tagname != other.tagname ) ;
+}
+
+QDOM_NodePrivate* QDOM_NodeListPrivate::item( int index )
+{
+ if ( !node_impl )
+ return 0;
+ QDOM_NodePrivate* p = node_impl->first;
+ int i = 0;
+ if ( tagname.isNull() ) {
+ while ( i < index && p ) {
+ p = p->next;
+ ++i;
+ }
+ } else {
+ while ( p && p != node_impl ) {
+ if ( p->isElement() && p->nodeName() == tagname ) {
+ if ( i == index )
+ break;
+ ++i;
+ }
+ if ( p->first )
+ p = p->first;
+ else if ( p->next )
+ p = p->next;
+ else {
+ p = p->parent;
+ while ( p && p != node_impl && !p->next )
+ p = p->parent;
+ if ( p && p != node_impl )
+ p = p->next;
+ }
+ }
+ }
+
+ return p;
+}
+
+uint QDOM_NodeListPrivate::length() const
+{
+ if ( !node_impl )
+ return 0;
+ uint i = 0;
+ QDOM_NodePrivate* p = node_impl->first;
+ if ( tagname.isNull() ) {
+ while ( p ) {
+ p = p->next;
+ ++i;
+ }
+ } else {
+ while ( p && p != node_impl ) {
+ if ( p->isElement() && p->nodeName() == tagname )
+ ++i;
+
+ if ( p->first )
+ p = p->first;
+ else if ( p->next )
+ p = p->next;
+ else {
+ p = p->parent;
+ while ( p && p != node_impl && !p->next )
+ p = p->parent;
+ if ( p && p != node_impl )
+ p = p->next;
+ }
+ }
+ }
+ return i;
+}
+
+/**************************************************************
+ *
+ * QDomNodeList
+ *
+ **************************************************************/
+
+/*!
+ \class QDomNodeList qdom.h
+ \brief The QDomNodeList class is a list of QDomNode objects.
+
+ \module XML
+
+ Lists can be obtained by QDomDocument::elementsByTagName() and
+ QDomNode::childNodes(). The Document Object Model (DOM) requires these lists
+ to be "live": whenever you change the underlying document, the contents of
+ the list will get updated.
+
+ For further information about the Document Objct Model see
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1/">http://www.w3.org/TR/REC-DOM-Level-1/</a>.
+ For a more general introduction of the DOM implementation see the
+ QDomDocument documentation.
+
+ \sa QDomNode::childNode() QDomDocument::elementsByTagName()
+*/
+
+/*!
+ Creates an empty node list.
+*/
+QDomNodeList::QDomNodeList()
+{
+ impl = 0;
+}
+
+/*! \internal
+*/
+QDomNodeList::QDomNodeList( QDOM_NodeListPrivate* p )
+{
+ impl = p;
+}
+
+/*!
+ Copy constructor.
+*/
+QDomNodeList::QDomNodeList( const QDomNodeList& n )
+{
+ impl = n.impl;
+ if ( impl )
+ impl->ref();
+}
+
+/*!
+ Assigns another node list to this object.
+*/
+QDomNodeList& QDomNodeList::operator= ( const QDomNodeList& n )
+{
+ if ( n.impl )
+ n.impl->ref();
+ if ( impl && impl->deref() )
+ delete impl;
+ impl = n.impl;
+
+ return *this;
+}
+
+/*!
+ Returns TRUE if both lists are equal, otherwise FALSE.
+*/
+bool QDomNodeList::operator== ( const QDomNodeList& n ) const
+{
+ if ( impl == n.impl )
+ return TRUE;
+ if ( !impl || !n.impl )
+ return FALSE;
+ return (*impl == *n.impl);
+}
+
+/*!
+ Returns TRUE if both lists are not equal, otherwise FALSE.
+*/
+bool QDomNodeList::operator!= ( const QDomNodeList& n ) const
+{
+ return !operator==(n);
+}
+
+/*!
+ Destructor.
+*/
+QDomNodeList::~QDomNodeList()
+{
+ if ( impl && impl->deref() )
+ delete impl;
+}
+
+/*!
+ Returns the node at position \a index.
+
+ If \a index is negative or if \a index >= length() then a null node is
+ returned (i.e. a node for which QDomNode::isNull() returns TRUE).
+*/
+QDomNode QDomNodeList::item( int index ) const
+{
+ if ( !impl )
+ return QDomNode();
+
+ return QDomNode( impl->item( index ) );
+}
+
+/*!
+ Returns the number of nodes in the list.
+
+ This function is the same as count().
+*/
+uint QDomNodeList::length() const
+{
+ if ( !impl )
+ return 0;
+ return impl->length();
+}
+
+/*!
+ \fn uint QDomNodeList::count() const
+
+ Returns the number of nodes in the list.
+
+ This function is the same as length().
+*/
+
+
+/*==============================================================*/
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_NodePrivate
+ *
+ **************************************************************/
+
+QDOM_NodePrivate::QDOM_NodePrivate( QDOM_DocumentPrivate* /* qd */, QDOM_NodePrivate *par )
+{
+ parent = par;
+ prev = 0;
+ next = 0;
+ first = 0;
+ last = 0;
+}
+
+QDOM_NodePrivate::QDOM_NodePrivate( QDOM_NodePrivate* n, bool deep )
+{
+ parent = 0;
+ prev = 0;
+ next = 0;
+ first = 0;
+ last = 0;
+
+ name = n->name;
+ value = n->value;
+
+ if ( !deep )
+ return;
+
+ for ( QDOM_NodePrivate* x = n->first; x; x = x->next )
+ appendChild( x->cloneNode( TRUE ) );
+}
+
+QDOM_NodePrivate::~QDOM_NodePrivate()
+{
+ QDOM_NodePrivate* p = first;
+ QDOM_NodePrivate* n;
+
+ while ( p ) {
+ n = p->next;
+ if ( p->deref() )
+ delete p;
+ else
+ p->parent = 0;
+ p = n;
+ }
+
+ first = 0;
+ last = 0;
+}
+
+void QDOM_NodePrivate::clear()
+{
+ QDOM_NodePrivate* p = first;
+ QDOM_NodePrivate* n;
+
+ while ( p ) {
+ n = p->next;
+ if ( p->deref() )
+ delete p;
+ p = n;
+ }
+
+ first = 0;
+ last = 0;
+}
+
+QDOM_NodePrivate* QDOM_NodePrivate::namedItem( const QString& n )
+{
+ QDOM_NodePrivate* p = first;
+ while ( p ) {
+ if ( p->nodeName() == n )
+ return p;
+ p = p->next;
+ }
+
+ return 0;
+}
+
+QDOM_NamedNodeMapPrivate* QDOM_NodePrivate::attributes()
+{
+ return 0;
+}
+
+QDOM_NodePrivate* QDOM_NodePrivate::insertBefore( QDOM_NodePrivate* newChild, QDOM_NodePrivate* refChild )
+{
+ // Error check
+ if ( !newChild )
+ return 0;
+
+ // Error check
+ if ( newChild == refChild )
+ return 0;
+
+ // Error check
+ if ( refChild && refChild->parent != this )
+ return 0;
+
+ // Special handling for inserting a fragment. We just insert
+ // all elements of the fragment instead of the fragment itself.
+ if ( newChild->isDocumentFragment() ) {
+ // Fragment is empty ?
+ if ( newChild->first == 0 )
+ return newChild;
+
+ // New parent
+ QDOM_NodePrivate* n = newChild->first;
+ while ( n ) {
+ n->parent = this;
+ n = n->next;
+ }
+
+ // Insert at the beginning ?
+ if ( !refChild || refChild->prev == 0 ) {
+ if ( first )
+ first->prev = newChild->last;
+ newChild->last->next = first;
+ if ( !last )
+ last = newChild->last;
+ first = newChild->first;
+ } else {// Insert in the middle
+ newChild->last->next = refChild;
+ newChild->first->prev = refChild->prev;
+ refChild->prev->next = newChild->first;
+ refChild->prev = newChild->last;
+ }
+
+ // No need to increase the reference since QDomDocumentFragment
+ // does not decrease the reference.
+
+ // Remove the nodes from the fragment
+ newChild->first = 0;
+ newChild->last = 0;
+ return newChild;
+ }
+
+ // No more errors can occure now, so we take
+ // ownership of the node.
+ newChild->ref();
+
+ if ( newChild->parent )
+ newChild->parent->removeChild( newChild );
+
+ newChild->parent = this;
+
+ if ( !refChild ) {
+ if ( first )
+ first->prev = newChild;
+ newChild->next = first;
+ if ( !last )
+ last = newChild;
+ first = newChild;
+ return newChild;
+ }
+
+ if ( refChild->prev == 0 ) {
+ if ( first )
+ first->prev = newChild;
+ newChild->next = first;
+ if ( !last )
+ last = newChild;
+ first = newChild;
+ return newChild;
+ }
+
+ newChild->next = refChild;
+ newChild->prev = refChild->prev;
+ refChild->prev->next = newChild;
+ refChild->prev = newChild;
+
+ return newChild;
+}
+
+QDOM_NodePrivate* QDOM_NodePrivate::insertAfter( QDOM_NodePrivate* newChild, QDOM_NodePrivate* refChild )
+{
+ // Error check
+ if ( !newChild )
+ return 0;
+
+ // Error check
+ if ( newChild == refChild )
+ return 0;
+
+ // Error check
+ if ( refChild && refChild->parent != this )
+ return 0;
+
+ // Special handling for inserting a fragment. We just insert
+ // all elements of the fragment instead of the fragment itself.
+ if ( newChild->isDocumentFragment() ) {
+ // Fragment is empty ?
+ if ( newChild->first == 0 )
+ return newChild;
+
+ // New parent
+ QDOM_NodePrivate* n = newChild->first;
+ while ( n ) {
+ n->parent = this;
+ n = n->next;
+ }
+
+ // Insert at the end
+ if ( !refChild || refChild->next == 0 ) {
+ if ( last )
+ last->next = newChild->first;
+ newChild->first->prev = last;
+ if ( !first )
+ first = newChild->first;
+ last = newChild->last;
+ } else { // Insert in the middle
+ newChild->first->prev = refChild;
+ newChild->last->next = refChild->next;
+ refChild->next->prev = newChild->last;
+ refChild->next = newChild->first;
+ }
+
+ // No need to increase the reference since QDomDocumentFragment
+ // does not decrease the reference.
+
+ // Remove the nodes from the fragment
+ newChild->first = 0;
+ newChild->last = 0;
+ return newChild;
+ }
+
+ // Release new node from its current parent
+ if ( newChild->parent )
+ newChild->parent->removeChild( newChild );
+
+ // No more errors can occure now, so we take
+ // ownership of the node
+ newChild->ref();
+
+ newChild->parent = this;
+
+ // Insert at the end
+ if ( !refChild ) {
+ if ( last )
+ last->next = newChild;
+ newChild->prev = last;
+ if ( !first )
+ first = newChild;
+ last = newChild;
+ return newChild;
+ }
+
+ if ( refChild->next == 0 ) {
+ if ( last )
+ last->next = newChild;
+ newChild->prev = last;
+ if ( !first )
+ first = newChild;
+ last = newChild;
+ return newChild;
+ }
+
+ newChild->prev = refChild;
+ newChild->next = refChild->next;
+ refChild->next->prev = newChild;
+ refChild->next = newChild;
+
+ return newChild;
+}
+
+QDOM_NodePrivate* QDOM_NodePrivate::replaceChild( QDOM_NodePrivate* newChild, QDOM_NodePrivate* oldChild )
+{
+ // Error check
+ if ( oldChild->parent != this )
+ return 0;
+
+ // Error check
+ if ( !newChild || !oldChild )
+ return 0;
+
+ // Error check
+ if ( newChild == oldChild )
+ return 0;
+
+ // Special handling for inserting a fragment. We just insert
+ // all elements of the fragment instead of the fragment itself.
+ if ( newChild->isDocumentFragment() ) {
+ // Fragment is empty ?
+ if ( newChild->first == 0 )
+ return newChild;
+
+ // New parent
+ QDOM_NodePrivate* n = newChild->first;
+ while ( n ) {
+ n->parent = this;
+ n = n->next;
+ }
+
+
+ if ( oldChild->next )
+ oldChild->next->prev = newChild->last;
+ if ( oldChild->prev )
+ oldChild->prev->next = newChild->first;
+
+ newChild->last->next = oldChild->next;
+ newChild->first->prev = oldChild->prev;
+
+ if ( first == oldChild )
+ first = newChild->first;
+ if ( last == oldChild )
+ last = newChild->last;
+
+ oldChild->parent = 0;
+ oldChild->next = 0;
+ oldChild->prev = 0;
+
+ // No need to increase the reference since QDomDocumentFragment
+ // does not decrease the reference.
+
+ // Remove the nodes from the fragment
+ newChild->first = 0;
+ newChild->last = 0;
+
+ // We are no longer interested in the old node
+ if ( oldChild ) oldChild->deref();
+
+ return oldChild;
+ }
+
+ // No more errors can occure now, so we take
+ // ownership of the node
+ newChild->ref();
+
+ // Release new node from its current parent
+ if ( newChild->parent )
+ newChild->parent->removeChild( newChild );
+
+ newChild->parent = this;
+
+ if ( oldChild->next )
+ oldChild->next->prev = newChild;
+ if ( oldChild->prev )
+ oldChild->prev->next = newChild;
+
+ newChild->next = oldChild->next;
+ newChild->prev = oldChild->prev;
+
+ if ( first == oldChild )
+ first = newChild;
+ if ( last == oldChild )
+ last = newChild;
+
+ oldChild->parent = 0;
+ oldChild->next = 0;
+ oldChild->prev = 0;
+
+ // We are no longer interested in the old node
+ if ( oldChild ) oldChild->deref();
+
+ return oldChild;
+}
+
+QDOM_NodePrivate* QDOM_NodePrivate::removeChild( QDOM_NodePrivate* oldChild )
+{
+ // Error check
+ if ( oldChild->parent != this )
+ return 0;
+
+ // Perhaps oldChild was just created with "createElement" or that. In this case
+ // its parent is QDomDocument but it is not part of the documents child list.
+ if ( oldChild->next == 0 && oldChild->prev == 0 && first != oldChild )
+ return 0;
+
+ if ( oldChild->next )
+ oldChild->next->prev = oldChild->prev;
+ if ( oldChild->prev )
+ oldChild->prev->next = oldChild->next;
+
+ if ( last == oldChild )
+ last = oldChild->prev;
+ if ( first == oldChild )
+ first = oldChild->next;
+
+ oldChild->parent = 0;
+ oldChild->next = 0;
+ oldChild->prev = 0;
+
+ // We are no longer interested in the old node
+ if ( oldChild ) oldChild->deref();
+
+ return oldChild;
+}
+
+QDOM_NodePrivate* QDOM_NodePrivate::appendChild( QDOM_NodePrivate* newChild )
+{
+ // No reference manipulation needed. Done in insertAfter.
+ return insertAfter( newChild, 0 );
+}
+
+void QDOM_NodePrivate::setParent( QDOM_NodePrivate* n )
+{
+ // Dont take over ownership of our parent :-)
+ parent = n;
+}
+
+QDOM_DocumentPrivate* QDOM_NodePrivate::ownerDocument()
+{
+ QDOM_NodePrivate* p = this;
+ while ( p && !p->isDocument() )
+ p = p->parent;
+
+ return (QDOM_DocumentPrivate*)p;
+}
+
+QDOM_NodePrivate* QDOM_NodePrivate::cloneNode( bool deep )
+{
+ QDOM_NodePrivate* p = new QDOM_NodePrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+void QDOM_NodePrivate::save( QTextStream& s, int indent ) const
+{
+ const QDOM_NodePrivate* n = first;
+ while ( n ) {
+ n->save( s, indent );
+ n = n->next;
+ }
+}
+
+/**************************************************************
+ *
+ * QDomNode
+ *
+ **************************************************************/
+
+#define IMPL ((QDOM_NodePrivate*)impl)
+
+/*!
+ \class QDomNode qdom.h
+ \brief The QDomNode class is the base class for all nodes of the DOM tree.
+
+ \module XML
+
+ This class is the base class for almost all other classes in the DOM. Many
+ functions in the DOM return a QDomNode. The various isXxx() functions are
+ useful to find out the type of the node. A QDomNode can be converted to a
+ subclass by using the toXxx() function family.
+
+ Copies of the QDomNode class share their data; this means modifying one will
+ change all copies. This is especially useful in combination with functions
+ which return a QDomNode, e.g. firstChild(). You can make an independent copy
+ of the node with cloneNode().
+
+ The following example looks for the first element in an XML document and
+ prints its name:
+ \code
+ QDomDocument d;
+ d.setContent( someXML );
+ QDomNode n = d.firstChild();
+ while ( !n.isNull() ) {
+ if ( n.isElement ) {
+ QDomElement e = n.toElement();
+ cout << "The name of the element is " << e.tagName() << endl;
+ return;
+ }
+ n = n.nextSibling();
+ }
+ cout << "no element in the Document" << endl;
+ \endcode
+
+ For further information about the Document Objct Model see
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1/">http://www.w3.org/TR/REC-DOM-Level-1/</a>.
+ For a more general introduction of the DOM implementation see the
+ QDomDocument documentation.
+*/
+
+/*!
+ Constructs an empty node.
+*/
+QDomNode::QDomNode()
+{
+ impl = 0;
+}
+
+/*!
+ Copy constructor.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomNode::QDomNode( const QDomNode& n )
+{
+ impl = n.impl;
+ if ( impl ) impl->ref();
+}
+
+/*!
+ \internal
+*/
+QDomNode::QDomNode( QDOM_NodePrivate* n )
+{
+ impl = n;
+ if ( impl ) impl->ref();
+}
+
+/*!
+ Assignment operator.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomNode& QDomNode::operator= ( const QDomNode& n )
+{
+ if ( n.impl ) n.impl->ref();
+ if ( impl && impl->deref() ) delete impl;
+ impl = n.impl;
+
+ return *this;
+}
+
+/*!
+ Returns TRUE if the two nodes are equal, otherwise FALSE.
+*/
+bool QDomNode::operator== ( const QDomNode& n ) const
+{
+ return ( impl == n.impl );
+}
+
+/*!
+ Returns TRUE if the two nodes are not equal, otherwise FALSE.
+*/
+bool QDomNode::operator!= ( const QDomNode& n ) const
+{
+ return ( impl != n.impl );
+}
+
+/*!
+ Destructor.
+*/
+QDomNode::~QDomNode()
+{
+ if ( impl && impl->deref() ) delete impl;
+}
+
+/*!
+ Returns the name of the node.
+
+ The meaning of the name depends on the subclass:
+
+ <ul>
+ <li> QDomElement - the tag name
+ <li> QDomAttr - the name of the attribute
+ <li> QDomText - the string "#text"
+ <li> QDomCDATASection - the string "#cdata-section"
+ <li> QDomEntityReference - the name of the referenced entity
+ <li> QDomEntity - the name of the entity
+ <li> QDomProcessingInstruction - the target of the processing instruction
+ <li> QDomDocument - the string "#document"
+ <li> QDomComment - the string "#comment"
+ <li> QDomDocumentType - the name of the document type
+ <li> QDomDocumentFragment - the string "#document-fragment"
+ <li> QDomNotation - the name of the notation
+ </ul>
+
+ \sa nodeValue()
+*/
+QString QDomNode::nodeName() const
+{
+ if ( !impl )
+ return QString::null;
+ return IMPL->name;
+}
+
+/*!
+ Returns the value of the node.
+
+ The meaning of the value depends on the subclass:
+
+ <ul>
+ <li> QDomAttr - the attribute value
+ <li> QDomText - the text
+ <li> QDomCDATASection - the content of the CDATA section
+ <li> QDomProcessingInstruction - the data of the processing intruction
+ <li> QDomComment - the comment
+ </ul>
+
+ All other subclasses not listed above do not have a node value. These classes
+ will return a null string.
+
+ \sa setNodeValue() nodeName()
+*/
+QString QDomNode::nodeValue() const
+{
+ if ( !impl )
+ return QString::null;
+ return IMPL->value;
+}
+
+/*!
+ Sets the value of the node to \a v.
+
+ \sa nodeValue()
+*/
+void QDomNode::setNodeValue( const QString& v )
+{
+ if ( !impl )
+ return;
+ IMPL->setNodeValue( v );
+}
+
+/*!
+ Returns the type of the node.
+
+ \sa toAttr() toCDATASection() toDocumentFragment() toDocument()
+ toDocumentType() toElement() toEntityReference() toText() toEntity()
+ toNotation() toProcessingInstruction() toCharacterData() toComment()
+*/
+QDomNode::NodeType QDomNode::nodeType() const
+{
+ // not very efficient, but will do for the moment.
+ if( isCDATASection() )
+ return CDATASectionNode;
+ if ( isText() )
+ return TextNode;
+ if ( isComment() )
+ return CommentNode;
+ if ( isCharacterData() )
+ return CharacterDataNode;
+ if( isAttr() )
+ return AttributeNode;
+ if( isElement() )
+ return ElementNode;
+ if (isEntityReference() )
+ return EntityReferenceNode;
+ if ( isEntity() )
+ return EntityNode;
+ if (isNotation() )
+ return NotationNode;
+ if ( isProcessingInstruction() )
+ return ProcessingInstructionNode;
+ if( isDocumentFragment() )
+ return DocumentFragmentNode;
+ if( isDocument() )
+ return DocumentNode;
+ if( isDocumentType() )
+ return DocumentTypeNode;
+
+ return QDomNode::BaseNode;
+}
+
+/*!
+ Returns the parent node, If this node has no parent, then a null node is
+ returned (i.e. a node for which isNull() returns TRUE).
+*/
+QDomNode QDomNode::parentNode() const
+{
+ if ( !impl )
+ return QDomNode();
+ return QDomNode( IMPL->parent );
+}
+
+/*!
+ Returns a list of all child nodes.
+
+ Most often you will call this function on a QDomElement object.
+ If the XML document looks like this:
+
+ \code
+ <body>
+ <h1>Heading</h1>
+ <p>Hallo <b>you</b></p>
+ </body>
+ \endcode
+
+ Then the list of child nodes for the "body"-element will contain the node
+ created by the &lt;h1&gt; tag and the node created by the &lt;p&gt; tag.
+
+ The nodes in the list are not copied; so changing the nodes in the list will
+ also change the children of this node.
+
+ \sa firstChild() lastChild()
+*/
+QDomNodeList QDomNode::childNodes() const
+{
+ if ( !impl )
+ return QDomNodeList();
+ return QDomNodeList( new QDOM_NodeListPrivate( impl ) );
+}
+
+/*!
+ Returns the first child of the node. If there is no child node, a null node
+ is returned.
+
+ \sa lastChild() childNodes()
+*/
+QDomNode QDomNode::firstChild() const
+{
+ if ( !impl )
+ return QDomNode();
+ return QDomNode( IMPL->first );
+}
+
+/*!
+ Returns the last child of the node. If there is no child node then a null
+ node is returned.
+
+ \sa firstChild() childNodes()
+*/
+QDomNode QDomNode::lastChild() const
+{
+ if ( !impl )
+ return QDomNode();
+ return QDomNode( IMPL->last );
+}
+
+/*!
+ Returns the previous sibling in the document tree. Changing the returned node
+ will also change the node in the document tree.
+
+ If you have XML like this:
+ \code
+ <h1>Heading</h1>
+ <p>The text...</p>
+ <h2>Next heading</h2>
+ \endcode
+
+ and this QDomNode represents the &lt;p&gt; tag, the previousSibling
+ will return the node representing the &lt;h1&gt; tag.
+
+ \sa nextSibling()
+*/
+QDomNode QDomNode::previousSibling() const
+{
+ if ( !impl )
+ return QDomNode();
+ return QDomNode( IMPL->prev );
+}
+
+/*!
+ Returns the next sibling in the document tree. Changing the returned node
+ will also change the node in the document tree.
+
+ If you have XML like this:
+ \code
+ <h1>Heading</h1>
+ <p>The text...</p>
+ <h2>Next heading</h2>
+ \endcode
+
+ and this QDomNode represents the &lt;p&gt; tag, the nextSibling
+ will return the node representing the &lt;h2&gt; tag.
+
+ \sa previousSibling()
+*/
+QDomNode QDomNode::nextSibling() const
+{
+ if ( !impl )
+ return QDomNode();
+ return QDomNode( IMPL->next );
+}
+
+/*!
+ Returns a map of all attributes. Attributes are only provided for
+ QDomElement.
+
+ Changing the attributes in the map will also change the attributes of this
+ QDomNode.
+*/
+QDomNamedNodeMap QDomNode::attributes() const
+{
+ if ( !impl )
+ return QDomNamedNodeMap();
+
+ return QDomNamedNodeMap( impl->attributes() );
+}
+
+/*!
+ Returns the document to which this node belongs.
+*/
+QDomDocument QDomNode::ownerDocument() const
+{
+ if ( !impl )
+ return QDomDocument();
+ return QDomDocument( IMPL->ownerDocument() );
+}
+
+/*!
+ Creates a real copy of the QDomNode.
+
+ If \a deep is TRUE, then the cloning is done recursive.
+ That means all children are copied, too. Otherwise the cloned
+ node does not contain child nodes.
+*/
+QDomNode QDomNode::cloneNode( bool deep ) const
+{
+ if ( !impl )
+ return QDomNode();
+ return QDomNode( IMPL->cloneNode( deep ) );
+}
+
+/*!
+ Inserts the node \a newChild before the child node \a refChild. \a refChild
+ has to be a direct child of this node. If \a refChild is null then \a
+ newChild is inserted as first child.
+
+ If \a newChild is currently child of another parent, then it is reparented.
+ If \a newChild is currently a child of this QDomNode, then its position in
+ the list of children is changed.
+
+ If \a newChild is a QDomDocumentFragment, then the children of the fragment
+ are removed from the fragment and inserted after \a refChild.
+
+ Returns a new reference to \a newChild on success or an empty node on
+ failure.
+
+ \sa insertAfter() replaceChild() removeChild() appendChild()
+*/
+QDomNode QDomNode::insertBefore( const QDomNode& newChild, const QDomNode& refChild )
+{
+ if ( !impl )
+ return QDomNode();
+ return QDomNode( IMPL->insertBefore( newChild.impl, refChild.impl ) );
+}
+
+/*!
+ Inserts the node \a newChild after the child node \a refChild. \a refChild
+ has to be a direct child of this node. If \a refChild is null then \a
+ newChild is appended as last child.
+
+ If \a newChild is currently child of another parent, then it is reparented.
+ If \a newChild is currently a child of this QDomNode, then its position in
+ the list of children is changed.
+
+ If \a newChild is a QDomDocumentFragment, then the children of the fragment
+ are removed from the fragment and inserted after \a refChild.
+
+ Returns a new reference to \a newChild on success or an empty node on failure.
+
+ \sa insertBefore() replaceChild() removeChild() appendChild()
+*/
+QDomNode QDomNode::insertAfter( const QDomNode& newChild, const QDomNode& refChild )
+{
+ if ( !impl )
+ return QDomNode();
+ return QDomNode( IMPL->insertAfter( newChild.impl, refChild.impl ) );
+}
+
+/*!
+ Replaces \a oldChild with \a newChild. \a oldChild has to be a direct child
+ of this node.
+
+ If \a newChild is currently child of another parent, then it is reparented.
+ If \a newChild is currently a child of this QDomNode, then its position in
+ the list of children is changed.
+
+ If \a newChild is a QDomDocumentFragment, then the children of the fragment
+ are removed from the fragment and inserted after \a refChild.
+
+ Returns a new reference to \a oldChild on success or a null node an failure.
+
+ \sa insertBefore() insertAfter() removeChild() appendChild()
+*/
+QDomNode QDomNode::replaceChild( const QDomNode& newChild, const QDomNode& oldChild )
+{
+ if ( !impl )
+ return QDomNode();
+ return QDomNode( IMPL->replaceChild( newChild.impl, oldChild.impl ) );
+}
+
+/*!
+ Removes \a oldChild from the list of children.
+ \a oldChild has to be a direct child of this node.
+
+ Returns a new reference to \a oldChild on success or a null node on failure.
+
+ \sa insertBefore() insertAfter() replaceChild() appendChild()
+*/
+QDomNode QDomNode::removeChild( const QDomNode& oldChild )
+{
+ if ( !impl )
+ return QDomNode();
+
+ if ( oldChild.isNull() )
+ return QDomNode();
+
+ return QDomNode( IMPL->removeChild( oldChild.impl ) );
+}
+
+/*!
+ Appends \a newChild to the end of the children list.
+
+ If \a newChild is currently child of another parent, then it is reparented.
+ If \a newChild is currently a child of this QDomNode, then its position in
+ the list of children is changed.
+
+ Returns a new reference to \a newChild.
+
+ \sa insertBefore() insertAfter() replaceChild() removeChild()
+*/
+QDomNode QDomNode::appendChild( const QDomNode& newChild )
+{
+ if ( !impl )
+ return QDomNode();
+ return QDomNode( IMPL->appendChild( newChild.impl ) );
+}
+
+/*!
+ Returns TRUE if this node does not reference any internal object, otherwise
+ FALSE.
+*/
+bool QDomNode::isNull() const
+{
+ return ( impl == 0 );
+}
+
+/*!
+ Dereferences the internal object. The node is then a null node.
+
+ \sa isNull()
+*/
+void QDomNode::clear()
+{
+ if ( impl && impl->deref() ) delete impl;
+ impl = 0;
+}
+
+/*!
+ Returns the first child node for which nodeName() equals \a name.
+
+ If no such direct child exists, a null node is returned.
+
+ \sa nodeName()
+*/
+QDomNode QDomNode::namedItem( const QString& name ) const
+{
+ if ( !impl )
+ return QDomNode();
+ return QDomNode( impl->namedItem( name ) );
+}
+
+/*!
+ Writes the XML representation of the node including all its children
+ on the stream.
+*/
+void QDomNode::save( QTextStream& str, int indent ) const
+{
+ if ( impl )
+ IMPL->save( str, indent );
+}
+
+/*!
+ Writes the XML representation of the node including all its children
+ on the stream.
+*/
+QTextStream& operator<<( QTextStream& str, const QDomNode& node )
+{
+ node.save( str, 0 );
+
+ return str;
+}
+
+/*!
+ Returns TRUE if the node is an attribute, otherwise FALSE.
+
+ If this function returns TRUE, this does not imply that this object is
+ a QDomAttribute; you can get the QDomAttribute with toAttribute().
+
+ \sa toAttribute()
+*/
+bool QDomNode::isAttr() const
+{
+ if(impl)
+ return impl->isAttr();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a CDATA section, otherwise FALSE.
+
+ If this function returns TRUE, this does not imply that this object is
+ a QDomCDATASection; you can get the QDomCDATASection with toCDATASection().
+
+ \sa toCDATASection()
+*/
+bool QDomNode::isCDATASection() const
+{
+ if(impl)
+ return impl->isCDATASection();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a document fragment, otherwise FALSE.
+
+ If this function returns TRUE, this does not imply that this object is
+ a QDomDocumentFragment; you can get the QDomDocumentFragment with
+ toDocumentFragment().
+
+ \sa toDocumentFragment()
+*/
+bool QDomNode::isDocumentFragment() const
+{
+ if(impl)
+ return impl->isDocumentFragment();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a document, otherwise FALSE.
+
+ If this function returns TRUE, this does not imply that this object is
+ a QDomDocument; you can get the QDomDocument with toDocument().
+
+ \sa toDocument()
+*/
+bool QDomNode::isDocument() const
+{
+ if(impl)
+ return impl->isDocument();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a document type, otherwise FALSE.
+
+ If this function returns TRUE, this does not imply that this object is
+ a QDomDocumentType; you can get the QDomDocumentType with toDocumentType().
+
+ \sa toDocumentType()
+*/
+bool QDomNode::isDocumentType() const
+{
+ if(impl)
+ return impl->isDocumentType();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is an element, otherwise FALSE.
+
+ If this function returns TRUE, this does not imply that this object is
+ a QDomElement; you can get the QDomElement with toElement().
+
+ \sa toElement()
+*/
+bool QDomNode::isElement() const
+{
+ if(impl)
+ return impl->isElement();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is an entity reference, otherwise FALSE.
+
+ If this function returns TRUE, this does not imply that this object is
+ a QDomEntityReference; you can get the QDomEntityReference with
+ toEntityReference().
+
+ \sa toEntityReference()
+*/
+bool QDomNode::isEntityReference() const
+{
+ if(impl)
+ return impl->isEntityReference();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a text, otherwise FALSE.
+
+ If this function returns TRUE, this does not imply that this object is
+ a QDomText; you can get the QDomText with toText().
+
+ \sa toText()
+*/
+bool QDomNode::isText() const
+{
+ if(impl)
+ return impl->isText();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is an entity, otherwise FALSE.
+
+ If this function returns TRUE, this does not imply that this object is
+ a QDomEntity; you can get the QDomEntity with toEntity().
+
+ \sa toEntity()
+*/
+bool QDomNode::isEntity() const
+{
+ if(impl)
+ return impl->isEntity();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a notation, otherwise FALSE.
+
+ If this function returns TRUE, this does not imply that this object is
+ a QDomNotation; you can get the QDomNotation with toNotation().
+
+ \sa toNotation()
+*/
+bool QDomNode::isNotation() const
+{
+ if(impl)
+ return impl->isNotation();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a processing instruction, otherwise FALSE.
+
+ If this function returns TRUE, this does not imply that this object is
+ a QDomProcessingInstruction; you can get the QProcessingInstruction with
+ toProcessingInstruction().
+
+ \sa toProcessingInstruction()
+*/
+bool QDomNode::isProcessingInstruction() const
+{
+ if(impl)
+ return impl->isProcessingInstruction();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a character data node, otherwise FALSE.
+
+ If this function returns TRUE, this does not imply that this object is
+ a QDomCharacterData; you can get the QDomCharacterData with
+ toCharacterData().
+
+ \sa toCharacterData()
+*/
+bool QDomNode::isCharacterData() const
+{
+ if(impl)
+ return impl->isCharacterData();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a comment, otherwise FALSE.
+
+ If this function returns TRUE, this does not imply that this object is
+ a QDomComment; you can get the QDomComment with toComment().
+
+ \sa toComment()
+*/
+bool QDomNode::isComment() const
+{
+ if(impl)
+ return impl->isComment();
+ return FALSE;
+}
+
+#undef IMPL
+
+/*==============================================================*/
+/* NamedNodeMap */
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_NamedNodeMapPrivate
+ *
+ **************************************************************/
+
+class QDOM_NamedNodeMapPrivate : public QShared
+{
+public:
+ QDOM_NamedNodeMapPrivate( QDOM_NodePrivate* );
+ ~QDOM_NamedNodeMapPrivate();
+
+ QDOM_NodePrivate* namedItem( const QString& name ) const;
+ QDOM_NodePrivate* setNamedItem( QDOM_NodePrivate* arg );
+ QDOM_NodePrivate* removeNamedItem( const QString& name );
+ QDOM_NodePrivate* item( int index ) const;
+ uint length() const;
+ bool contains( const QString& name ) const;
+
+ /**
+ * Remove all children from the map.
+ */
+ void clearMap();
+ bool isReadOnly() { return readonly; }
+ void setReadOnly( bool r ) { readonly = r; }
+ bool isAppendToParent() { return appendToParent; }
+ /**
+ * If TRUE, then the node will redirect insert/remove calls
+ * to its parent by calling QDOM_NodePrivate::appendChild or removeChild.
+ * In addition the map wont increase or decrease the reference count
+ * of the nodes it contains.
+ *
+ * By default this value is FALSE and the map will handle reference counting
+ * by itself.
+ */
+ void setAppendToParent( bool b ) { appendToParent = b; }
+
+ /**
+ * Creates a copy of the map. It is a deep copy
+ * that means that all children are cloned.
+ */
+ QDOM_NamedNodeMapPrivate* clone( QDOM_NodePrivate* parent );
+
+ // Variables
+ QDict<QDOM_NodePrivate> map;
+ QDOM_NodePrivate* parent;
+ bool readonly;
+ bool appendToParent;
+};
+
+QDOM_NamedNodeMapPrivate::QDOM_NamedNodeMapPrivate( QDOM_NodePrivate* n )
+{
+ readonly = FALSE;
+ parent = n;
+ appendToParent = FALSE;
+}
+
+QDOM_NamedNodeMapPrivate::~QDOM_NamedNodeMapPrivate()
+{
+ clearMap();
+}
+
+QDOM_NamedNodeMapPrivate* QDOM_NamedNodeMapPrivate::clone( QDOM_NodePrivate* p )
+{
+ QDOM_NamedNodeMapPrivate* m = new QDOM_NamedNodeMapPrivate( p );
+ m->readonly = readonly;
+ m->appendToParent = appendToParent;
+
+ QDictIterator<QDOM_NodePrivate> it ( map );
+ for ( ; it.current(); ++it )
+ m->setNamedItem( it.current()->cloneNode() );
+
+ // we are no longer interested in ownership
+ m->deref();
+ return m;
+}
+
+void QDOM_NamedNodeMapPrivate::clearMap()
+{
+ // Dereference all of our children if we took references
+ if ( !appendToParent ) {
+ QDictIterator<QDOM_NodePrivate> it( map );
+ for ( ; it.current(); ++it )
+ if ( it.current()->deref() )
+ delete it.current();
+ }
+
+ map.clear();
+}
+
+QDOM_NodePrivate* QDOM_NamedNodeMapPrivate::namedItem( const QString& name ) const
+{
+ QDOM_NodePrivate* p = map[ name ];
+ return p;
+}
+
+QDOM_NodePrivate* QDOM_NamedNodeMapPrivate::setNamedItem( QDOM_NodePrivate* arg )
+{
+ if ( readonly || !arg )
+ return 0;
+
+ if ( appendToParent )
+ return parent->appendChild( arg );
+
+ // We take a reference
+ arg->ref();
+ map.insert( arg->nodeName(), arg );
+ return arg;
+}
+
+QDOM_NodePrivate* QDOM_NamedNodeMapPrivate::removeNamedItem( const QString& name )
+{
+ if ( readonly )
+ return 0;
+
+ QDOM_NodePrivate* p = namedItem( name );
+ if ( p == 0 )
+ return 0;
+ if ( appendToParent )
+ return parent->removeChild( p );
+
+ map.remove( p->nodeName() );
+ // We took a reference, so we have to free one here
+ p->deref();
+ return p;
+}
+
+QDOM_NodePrivate* QDOM_NamedNodeMapPrivate::item( int index ) const
+{
+ if ( (uint)index >= length() )
+ return 0;
+
+ QDictIterator<QDOM_NodePrivate> it( map );
+ for ( int i = 0; i < index; ++i, ++it )
+ ;
+ return it.current();
+}
+
+uint QDOM_NamedNodeMapPrivate::length() const
+{
+ return map.count();
+}
+
+bool QDOM_NamedNodeMapPrivate::contains( const QString& name ) const
+{
+ return ( map[ name ] != 0 );
+}
+
+/**************************************************************
+ *
+ * QDomNamedNodeMap
+ *
+ **************************************************************/
+
+#define IMPL ((QDOM_NamedNodeMapPrivate*)impl)
+
+/*!
+ \class QDomNamedNodeMap qdom.h
+ \brief The QDomNamedNodeMap class contains a collection of nodes that can be
+ accessed by name.
+
+ \module XML
+
+ Note that QDomNamedNodeMap does not inherit from QDomNodeList;
+ QDomNamedNodeMaps does not provide any specific order of the nodes. Nodes
+ contained in a QDomNamedNodeMap may also be accessed by an ordinal index, but
+ this is simply to allow a convenient enumeration of the contents of a
+ QDomNamedNodeMap and does not imply that the DOM specifies an order on the
+ nodes.
+
+ The QDomNamedNodeMap is used in three places:
+
+ <ul>
+ <li> QDomDocumentType::entities() returns a map of all entities
+ described in the DTD.
+ <li> QDomDocumentType::notations() returns a map of all notations
+ described in the DTD.
+ <li> QDomElement::attributes() returns a map of all attributes of the
+ element.
+ </ul>
+
+ Items in the map are identified by the name which QDomNode::name() returns.
+ They can be queried using the namedItem() function and set using
+ setNamedItem().
+
+ \sa namedItem() setNamedItem()
+*/
+
+/*!
+ Constructs an empty map.
+*/
+QDomNamedNodeMap::QDomNamedNodeMap()
+{
+ impl = 0;
+}
+
+/*!
+ Copy constructor.
+*/
+QDomNamedNodeMap::QDomNamedNodeMap( const QDomNamedNodeMap& n )
+{
+ impl = n.impl;
+ if ( impl )
+ impl->ref();
+}
+
+/*!
+ \internal
+*/
+QDomNamedNodeMap::QDomNamedNodeMap( QDOM_NamedNodeMapPrivate* n )
+{
+ impl = n;
+ if ( impl )
+ impl->ref();
+}
+
+/*!
+ Assignement operator.
+*/
+QDomNamedNodeMap& QDomNamedNodeMap::operator= ( const QDomNamedNodeMap& n )
+{
+ if ( impl && impl->deref() )
+ delete impl;
+ impl = n.impl;
+ if ( impl )
+ impl->ref();
+
+ return *this;
+}
+
+/*!
+ Returns TRUE if the maps are equal, FALSE otherwise.
+*/
+bool QDomNamedNodeMap::operator== ( const QDomNamedNodeMap& n ) const
+{
+ return ( impl == n.impl );
+}
+
+/*!
+ Returns TRUE if the maps are not equal, FALSE otherwise.
+*/
+bool QDomNamedNodeMap::operator!= ( const QDomNamedNodeMap& n ) const
+{
+ return ( impl != n.impl );
+}
+
+/*!
+ Destructor.
+*/
+QDomNamedNodeMap::~QDomNamedNodeMap()
+{
+ if ( impl && impl->deref() )
+ delete impl;
+}
+
+/*!
+ Returns the node associated with they key \a name.
+
+ If the map does not contain such a node, then a null node is returned.
+
+ \sa setNamedItem()
+*/
+QDomNode QDomNamedNodeMap::namedItem( const QString& name ) const
+{
+ if ( !impl )
+ return QDomNode();
+ return QDomNode( IMPL->namedItem( name ) );
+}
+
+/*!
+ Inserts the node \a newNode in the map. The kye for the map is the name of \a
+ newNode as returned by QDomNode::nodeName().
+
+ The function returns the newly inserted node.
+
+ \sa removeNamedItem()
+*/
+QDomNode QDomNamedNodeMap::setNamedItem( const QDomNode& newNode )
+{
+ if ( !impl )
+ return QDomNode();
+ return QDomNode( IMPL->setNamedItem( (QDOM_NodePrivate*)newNode.impl ) );
+}
+
+/*!
+ Removes the node with the name \a name from the map.
+
+ The function returns the removed node or a null node
+ if the map did not contain a node with the name \a name.
+
+ \sa setNamedItem()
+*/
+QDomNode QDomNamedNodeMap::removeNamedItem( const QString& name )
+{
+ if ( !impl )
+ return QDomNode();
+ return QDomNode( IMPL->removeNamedItem( name ) );
+}
+
+/*!
+ Retrieves the node at position \a index.
+
+ This can be used to iterate over the map.
+
+ \sa length()
+*/
+QDomNode QDomNamedNodeMap::item( int index ) const
+{
+ if ( !impl )
+ return QDomNode();
+ return QDomNode( IMPL->item( index ) );
+}
+
+/*!
+ Returns the number of nodes in the map.
+
+ \sa item()
+*/
+uint QDomNamedNodeMap::length() const
+{
+ if ( !impl )
+ return 0;
+ return IMPL->length();
+}
+
+/*!
+ Returns TRUE if the map contains a node with the name \a name, otherwise
+ FALSE.
+*/
+bool QDomNamedNodeMap::contains( const QString& name ) const
+{
+ if ( !impl )
+ return FALSE;
+ return IMPL->contains( name );
+}
+
+#undef IMPL
+
+/*==============================================================*/
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_DocumentTypePrivate
+ *
+ **************************************************************/
+
+class QDOM_DocumentTypePrivate : public QDOM_NodePrivate
+{
+public:
+ QDOM_DocumentTypePrivate( QDOM_DocumentPrivate*, QDOM_NodePrivate* parent = 0 );
+ QDOM_DocumentTypePrivate( QDOM_DocumentTypePrivate* n, bool deep );
+ ~QDOM_DocumentTypePrivate();
+
+ // virtual QDOM_NamedNodeMapPrivate* entities();
+ // virtual QDOM_NamedNodeMapPrivate* notations();
+
+ // Overloaded from QDOM_NodePrivate
+ virtual QDOM_NodePrivate* cloneNode( bool deep = TRUE );
+ virtual QDOM_NodePrivate* insertBefore( QDOM_NodePrivate* newChild, QDOM_NodePrivate* refChild );
+ virtual QDOM_NodePrivate* insertAfter( QDOM_NodePrivate* newChild, QDOM_NodePrivate* refChild );
+ virtual QDOM_NodePrivate* replaceChild( QDOM_NodePrivate* newChild, QDOM_NodePrivate* oldChild );
+ virtual QDOM_NodePrivate* removeChild( QDOM_NodePrivate* oldChild );
+ virtual QDOM_NodePrivate* appendChild( QDOM_NodePrivate* newChild );
+
+ // Overloaded from QDOM_DocumentTypePrivate
+ virtual bool isDocumentType() { return TRUE; }
+ virtual void save( QTextStream& s, int ) const;
+
+ // Variables
+ QDOM_NamedNodeMapPrivate* entities;
+ QDOM_NamedNodeMapPrivate* notations;
+};
+
+QDOM_DocumentTypePrivate::QDOM_DocumentTypePrivate( QDOM_DocumentPrivate* doc, QDOM_NodePrivate* parent )
+ : QDOM_NodePrivate( doc, parent )
+{
+ entities = new QDOM_NamedNodeMapPrivate( this );
+ notations = new QDOM_NamedNodeMapPrivate( this );
+
+ entities->setAppendToParent( TRUE );
+ notations->setAppendToParent( TRUE );
+}
+
+QDOM_DocumentTypePrivate::QDOM_DocumentTypePrivate( QDOM_DocumentTypePrivate* n, bool deep )
+ : QDOM_NodePrivate( n, deep )
+{
+ entities = new QDOM_NamedNodeMapPrivate( this );
+ notations = new QDOM_NamedNodeMapPrivate( this );
+
+ entities->setAppendToParent( TRUE );
+ notations->setAppendToParent( TRUE );
+
+ // Refill the maps with our new children
+ QDOM_NodePrivate* p = first;
+ while ( p ) {
+ if ( p->isEntity() )
+ // Dont use normal insert function since we would create infinite recursion
+ entities->map.insert( p->nodeName(), p );
+ if ( p->isNotation() )
+ // Dont use normal insert function since we would create infinite recursion
+ notations->map.insert( p->nodeName(), p );
+ }
+}
+
+QDOM_DocumentTypePrivate::~QDOM_DocumentTypePrivate()
+{
+ if ( entities->deref() )
+ delete entities;
+ if ( notations->deref() )
+ delete notations;
+}
+
+QDOM_NodePrivate* QDOM_DocumentTypePrivate::cloneNode( bool deep)
+{
+ QDOM_NodePrivate* p = new QDOM_DocumentTypePrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+QDOM_NodePrivate* QDOM_DocumentTypePrivate::insertBefore( QDOM_NodePrivate* newChild, QDOM_NodePrivate* refChild )
+{
+ // Call the origianl implementation
+ QDOM_NodePrivate* p = QDOM_NodePrivate::insertBefore( newChild, refChild );
+ // Update the maps
+ if ( p && p->isEntity() )
+ entities->map.insert( p->nodeName(), p );
+ else if ( p && p->isNotation() )
+ notations->map.insert( p->nodeName(), p );
+
+ return p;
+}
+
+QDOM_NodePrivate* QDOM_DocumentTypePrivate::insertAfter( QDOM_NodePrivate* newChild, QDOM_NodePrivate* refChild )
+{
+ // Call the origianl implementation
+ QDOM_NodePrivate* p = QDOM_NodePrivate::insertAfter( newChild, refChild );
+ // Update the maps
+ if ( p && p->isEntity() )
+ entities->map.insert( p->nodeName(), p );
+ else if ( p && p->isNotation() )
+ notations->map.insert( p->nodeName(), p );
+
+ return p;
+}
+
+QDOM_NodePrivate* QDOM_DocumentTypePrivate::replaceChild( QDOM_NodePrivate* newChild, QDOM_NodePrivate* oldChild )
+{
+ // Call the origianl implementation
+ QDOM_NodePrivate* p = QDOM_NodePrivate::replaceChild( newChild, oldChild );
+ // Update the maps
+ if ( p ) {
+ if ( oldChild && oldChild->isEntity() )
+ entities->map.remove( oldChild->nodeName() );
+ else if ( oldChild && oldChild->isNotation() )
+ notations->map.remove( oldChild->nodeName() );
+
+ if ( p->isEntity() )
+ entities->map.insert( p->nodeName(), p );
+ else if ( p->isNotation() )
+ notations->map.insert( p->nodeName(), p );
+ }
+
+ return p;
+}
+
+QDOM_NodePrivate* QDOM_DocumentTypePrivate::removeChild( QDOM_NodePrivate* oldChild )
+{
+ // Call the origianl implementation
+ QDOM_NodePrivate* p = QDOM_NodePrivate::removeChild( oldChild );
+ // Update the maps
+ if ( p && p->isEntity() )
+ entities->map.remove( p->nodeName() );
+ else if ( p && p->isNotation() )
+ notations->map.remove( p ->nodeName() );
+
+ return p;
+}
+
+QDOM_NodePrivate* QDOM_DocumentTypePrivate::appendChild( QDOM_NodePrivate* newChild )
+{
+ return insertAfter( newChild, 0 );
+}
+
+void QDOM_DocumentTypePrivate::save( QTextStream& s, int ) const
+{
+ if ( name.isEmpty() )
+ return;
+ s << "<!DOCTYPE " << name << " ";
+
+ // qDebug("--------- 3 DocType %i %i", entities->map.count(), notations->map.count() );
+
+ if ( entities->length() > 0 || notations->length() > 0 ) {
+ s << "[ ";
+
+ QDictIterator<QDOM_NodePrivate> it2( notations->map );
+ for ( ; it2.current(); ++it2 )
+ it2.current()->save( s, 0 );
+
+ QDictIterator<QDOM_NodePrivate> it( entities->map );
+ for ( ; it.current(); ++it )
+ it.current()->save( s, 0 );
+
+ s << " ]";
+ }
+
+ s << ">";
+}
+
+/**************************************************************
+ *
+ * QDomDocumentType
+ *
+ **************************************************************/
+
+#define IMPL ((QDOM_DocumentTypePrivate*)impl)
+
+/*!
+ \class QDomDocumentType qdom.h
+ \brief The QDomDocumentType class is the representation of the DTD in the
+ document tree.
+
+ \module XML
+
+ The QDomDocumentType class allows readonly access to some of the data
+ structures in the DTD: it can return a map of all entities() and notations().
+
+ In addition the function name() returns the name of the document type as
+ specified in the &lt;!DOCTYPE name&gt; tag.
+
+ \sa QDomDocument
+*/
+
+/*!
+ Creates an empty QDomDocumentType object.
+*/
+QDomDocumentType::QDomDocumentType() : QDomNode()
+{
+}
+
+/*!
+ Copy constructor.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomDocumentType::QDomDocumentType( const QDomDocumentType& n )
+ : QDomNode( n )
+{
+}
+
+/*!
+ \internal
+*/
+QDomDocumentType::QDomDocumentType( QDOM_DocumentTypePrivate* n )
+ : QDomNode( n )
+{
+}
+
+/*!
+ Assignement operator.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomDocumentType& QDomDocumentType::operator= ( const QDomDocumentType& n )
+{
+ return (QDomDocumentType&) QDomNode::operator=( n );
+}
+
+/*!
+ Destructor.
+*/
+QDomDocumentType::~QDomDocumentType()
+{
+}
+
+/*!
+ Returns the name of the document type as specified in
+ the &lt;!DOCTYPE name&gt; tag.
+
+ \sa nodeName()
+*/
+QString QDomDocumentType::name() const
+{
+ if ( !impl )
+ return QString::null;
+
+ return IMPL->nodeName();
+}
+
+/*!
+ Returns a map of all entities described in the DTD.
+*/
+QDomNamedNodeMap QDomDocumentType::entities() const
+{
+ if ( !impl )
+ return QDomNamedNodeMap();
+ return QDomNamedNodeMap( IMPL->entities );
+}
+
+/*!
+ Returns a map of all notations described in the DTD.
+*/
+QDomNamedNodeMap QDomDocumentType::notations() const
+{
+ if ( !impl )
+ return QDomNamedNodeMap();
+ return QDomNamedNodeMap( IMPL->notations );
+}
+
+/*!
+ Returns \c DocumentTypeNode.
+
+ \sa isDocumentType() QDomNode::toDocumentType()
+*/
+QDomNode::NodeType QDomDocumentType::nodeType() const
+{
+ return DocumentTypeNode;
+}
+
+/*!
+ This function overloads QDomNode::isDocumentType().
+
+ \sa nodeType() QDomNode::toDocumentType()
+*/
+bool QDomDocumentType::isDocumentType() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/*==============================================================*/
+/* DocumentFragment */
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_DocumentFragmentPrivate
+ *
+ **************************************************************/
+
+class QDOM_DocumentFragmentPrivate : public QDOM_NodePrivate
+{
+public:
+ QDOM_DocumentFragmentPrivate( QDOM_DocumentPrivate*, QDOM_NodePrivate* parent = 0 );
+ QDOM_DocumentFragmentPrivate( QDOM_NodePrivate* n, bool deep );
+ ~QDOM_DocumentFragmentPrivate();
+
+ // Overloaded from QDOM_NodePrivate
+ virtual QDOM_NodePrivate* cloneNode( bool deep = TRUE );
+ virtual bool isDocumentFragment() { return TRUE; }
+
+ static QString* dfName;
+};
+
+QString* QDOM_DocumentFragmentPrivate::dfName = 0;
+
+QDOM_DocumentFragmentPrivate::QDOM_DocumentFragmentPrivate( QDOM_DocumentPrivate* doc, QDOM_NodePrivate* parent )
+ : QDOM_NodePrivate( doc, parent )
+{
+ if ( !dfName )
+ dfName = new QString( "#document-fragment" );
+ name = *dfName;
+}
+
+QDOM_DocumentFragmentPrivate::QDOM_DocumentFragmentPrivate( QDOM_NodePrivate* n, bool deep )
+ : QDOM_NodePrivate( n, deep )
+{
+}
+
+QDOM_DocumentFragmentPrivate::~QDOM_DocumentFragmentPrivate()
+{
+}
+
+QDOM_NodePrivate* QDOM_DocumentFragmentPrivate::cloneNode( bool deep)
+{
+ QDOM_NodePrivate* p = new QDOM_DocumentFragmentPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+/**************************************************************
+ *
+ * QDomDocumentFragment
+ *
+ **************************************************************/
+
+#define IMPL ((QDOM_DocumentFragmentPrivate*)impl)
+
+/*!
+ \class QDomDocumentFragment qdom.h
+ \brief The QDomDocumentFragment class is a tree of QDomNodes which is usually
+ not a complete QDomDocument.
+
+ \module XML
+
+ If you want to do complex tree operations it is useful to have a lightweight
+ class to store nodes and their relations. QDomDocumentFragment stores a
+ subtree of a document which does not necessarily represent a well-formed XML
+ document.
+
+ QDomDocumentFragment is also useful if you want to group several nodes in a
+ list and insert them all together as children of some
+ node. In these cases QDomDocumentFragment can be used as a temporary
+ container for this list of children.
+
+ The most important feature of QDomDocumentFragment is, that it is treated in
+ a special way by QDomNode::insertAfter(), QDomNode::insertBefore() and
+ QDomNode::replaceChild(): instead of inserting the fragment itself, all
+ children of the fragment are inserted.
+*/
+
+/*!
+ Constructs an empty DocumentFragment.
+*/
+QDomDocumentFragment::QDomDocumentFragment()
+{
+}
+
+/*!
+ \internal
+*/
+QDomDocumentFragment::QDomDocumentFragment( QDOM_DocumentFragmentPrivate* n )
+ : QDomNode( n )
+{
+}
+
+/*!
+ Copy constructor.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomDocumentFragment::QDomDocumentFragment( const QDomDocumentFragment& x )
+ : QDomNode( x )
+{
+}
+
+/*!
+ Assignment operator.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomDocumentFragment& QDomDocumentFragment::operator= ( const QDomDocumentFragment& x )
+{
+ return (QDomDocumentFragment&) QDomNode::operator=( x );
+}
+
+/*!
+ Destructor.
+*/
+QDomDocumentFragment::~QDomDocumentFragment()
+{
+}
+
+/*!
+ Returns \c DocumentFragment.
+
+ \sa isDocumentFragment() QDomNode::toDocumentFragment()
+*/
+QDomNode::NodeType QDomDocumentFragment::nodeType() const
+{
+ return QDomNode::DocumentFragmentNode;
+}
+
+/*!
+ This function reimplements QDomNode::isDocumentFragment().
+
+ \sa nodeType() QDomNode::toDocumentFragment()
+*/
+bool QDomDocumentFragment::isDocumentFragment() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/*==============================================================*/
+/* CharacterData */
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_CharacterDataPrivate
+ *
+ **************************************************************/
+
+class QDOM_CharacterDataPrivate : public QDOM_NodePrivate
+{
+public:
+ QDOM_CharacterDataPrivate( QDOM_DocumentPrivate*, QDOM_NodePrivate* parent, const QString& data );
+ QDOM_CharacterDataPrivate( QDOM_CharacterDataPrivate* n, bool deep );
+ ~QDOM_CharacterDataPrivate();
+
+ uint dataLength() const;
+ QString substringData( unsigned long offset, unsigned long count ) const;
+ void appendData( const QString& arg );
+ void insertData( unsigned long offset, const QString& arg );
+ void deleteData( unsigned long offset, unsigned long count );
+ void replaceData( unsigned long offset, unsigned long count, const QString& arg );
+
+ // Overloaded from QDOM_NodePrivate
+ virtual bool isCharacterData() { return TRUE; }
+ virtual QDOM_NodePrivate* cloneNode( bool deep = TRUE );
+
+ static QString* cdName;
+};
+
+QString* QDOM_CharacterDataPrivate::cdName = 0;
+
+QDOM_CharacterDataPrivate::QDOM_CharacterDataPrivate( QDOM_DocumentPrivate* d, QDOM_NodePrivate* p,
+ const QString& data )
+ : QDOM_NodePrivate( d, p )
+{
+ value = data;
+
+ if ( !cdName )
+ cdName = new QString( "#character-data" );
+ name = *cdName;
+}
+
+QDOM_CharacterDataPrivate::QDOM_CharacterDataPrivate( QDOM_CharacterDataPrivate* n, bool deep )
+ : QDOM_NodePrivate( n, deep )
+{
+}
+
+QDOM_CharacterDataPrivate::~QDOM_CharacterDataPrivate()
+{
+}
+
+QDOM_NodePrivate* QDOM_CharacterDataPrivate::cloneNode( bool deep )
+{
+ QDOM_NodePrivate* p = new QDOM_CharacterDataPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+uint QDOM_CharacterDataPrivate::dataLength() const
+{
+ return value.length();
+}
+
+QString QDOM_CharacterDataPrivate::substringData( unsigned long offset, unsigned long n ) const
+{
+ return value.mid( offset, n );
+}
+
+void QDOM_CharacterDataPrivate::insertData( unsigned long offset, const QString& arg )
+{
+ value.insert( offset, arg );
+}
+
+void QDOM_CharacterDataPrivate::deleteData( unsigned long offset, unsigned long n )
+{
+ value.remove( offset, n );
+}
+
+void QDOM_CharacterDataPrivate::replaceData( unsigned long offset, unsigned long n, const QString& arg )
+{
+ value.replace( offset, n, arg );
+}
+
+void QDOM_CharacterDataPrivate::appendData( const QString& arg )
+{
+ value += arg;
+}
+
+/**************************************************************
+ *
+ * QDomCharacterData
+ *
+ **************************************************************/
+
+#define IMPL ((QDOM_CharacterDataPrivate*)impl)
+
+/*!
+ \class QDomCharacterData qdom.h
+ \brief The QDomCharacterData class represents a generic string in the DOM.
+
+ \module XML
+
+ Character data as used in XML specifies a generic data string.
+ More specialized versions of this class are QDomText, QDomComment
+ and QDomCDATASection.
+
+ \sa QDomText QDomComment QDomCDATASection
+*/
+
+/*!
+ Constructs an empty character data object.
+*/
+QDomCharacterData::QDomCharacterData()
+{
+}
+
+/*!
+ Copy constructor.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomCharacterData::QDomCharacterData( const QDomCharacterData& x )
+ : QDomNode( x )
+{
+}
+
+/*!
+ \internal
+*/
+QDomCharacterData::QDomCharacterData( QDOM_CharacterDataPrivate* n )
+ : QDomNode( n )
+{
+}
+
+/*!
+ Assignment operator.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomCharacterData& QDomCharacterData::operator= ( const QDomCharacterData& x )
+{
+ return (QDomCharacterData&) QDomNode::operator=( x );
+}
+
+/*!
+ Destructor.
+*/
+QDomCharacterData::~QDomCharacterData()
+{
+}
+
+/*!
+ Returns the string stored in this object.
+
+ If the node is a null node, it will return a null string.
+*/
+QString QDomCharacterData::data() const
+{
+ if ( !impl )
+ return QString::null;
+ return impl->nodeValue();
+}
+
+/*!
+ Sets the string of this object to \a v.
+*/
+void QDomCharacterData::setData( const QString& v )
+{
+ if ( impl )
+ impl->setNodeValue( v );
+}
+
+/*!
+ Returns the length of the stored string.
+*/
+uint QDomCharacterData::length() const
+{
+ if ( impl )
+ return IMPL->dataLength();
+ return 0;
+}
+
+/*!
+ Returns the substring from position \a offset with length \a count.
+*/
+QString QDomCharacterData::substringData( unsigned long offset, unsigned long count )
+{
+ if ( !impl )
+ return QString::null;
+ return IMPL->substringData( offset, count );
+}
+
+/*!
+ Appends \a arg to the stored string.
+*/
+void QDomCharacterData::appendData( const QString& arg )
+{
+ if ( impl )
+ IMPL->appendData( arg );
+}
+
+/*!
+ Inserts the string \a arg at position \a offset into the stored string.
+*/
+void QDomCharacterData::insertData( unsigned long offset, const QString& arg )
+{
+ if ( impl )
+ IMPL->insertData( offset, arg );
+}
+
+/*!
+ Deletes the substring starting at position \a offset with length \a count.
+*/
+void QDomCharacterData::deleteData( unsigned long offset, unsigned long count )
+{
+ if ( impl )
+ IMPL->deleteData( offset, count );
+}
+
+/*!
+ Replaces the substring starting at \a offset with length \a count with the
+ string \a arg.
+*/
+void QDomCharacterData::replaceData( unsigned long offset, unsigned long count, const QString& arg )
+{
+ if ( impl )
+ IMPL->replaceData( offset, count, arg );
+}
+
+/*!
+ Returns the type of node this object refers to (i.e. \c TextNode,
+ \c CDATASectionNode, \c CommentNode or \c CharacterDataNode). For a null node
+ \c CharacterDataNode is returned.
+*/
+QDomNode::NodeType QDomCharacterData::nodeType() const
+{
+ if( !impl )
+ return CharacterDataNode;
+ return QDomNode::nodeType();
+}
+
+/*!
+ Returns TRUE.
+*/
+bool QDomCharacterData::isCharacterData() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * QDOM_TextPrivate
+ *
+ **************************************************************/
+
+class QDOM_TextPrivate : public QDOM_CharacterDataPrivate
+{
+public:
+ QDOM_TextPrivate( QDOM_DocumentPrivate*, QDOM_NodePrivate* parent, const QString& value );
+ QDOM_TextPrivate( QDOM_TextPrivate* n, bool deep );
+ ~QDOM_TextPrivate();
+
+ QDOM_TextPrivate* splitText( int offset );
+
+ // Overloaded from QDOM_NodePrivate
+ virtual QDOM_NodePrivate* cloneNode( bool deep = TRUE );
+ virtual bool isText() { return TRUE; }
+ virtual void save( QTextStream& s, int ) const;
+
+ static QString* textName;
+};
+
+/*==============================================================*/
+/* Attr */
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_AttrPrivate
+ *
+ **************************************************************/
+
+class QDOM_AttrPrivate : public QDOM_NodePrivate
+{
+public:
+ QDOM_AttrPrivate( QDOM_DocumentPrivate*, QDOM_NodePrivate* parent, const QString& name );
+ QDOM_AttrPrivate( QDOM_AttrPrivate* n, bool deep );
+ ~QDOM_AttrPrivate();
+
+ bool specified() const;
+
+ // Overloaded from QDOM_NodePrivate
+ virtual QDOM_NodePrivate* cloneNode( bool deep = TRUE );
+ virtual bool isAttr() { return TRUE; }
+ virtual void save( QTextStream& s, int ) const;
+
+ // Variables
+ bool m_specified;
+};
+
+QDOM_AttrPrivate::QDOM_AttrPrivate( QDOM_DocumentPrivate* d, QDOM_NodePrivate* parent, const QString& name_ )
+ : QDOM_NodePrivate( d, parent )
+{
+ name = name_;
+ m_specified = FALSE;
+ // qDebug("ATTR");
+}
+
+QDOM_AttrPrivate::QDOM_AttrPrivate( QDOM_AttrPrivate* n, bool deep )
+ : QDOM_NodePrivate( n, deep )
+{
+ m_specified = n->specified();
+ // qDebug("ATTR");
+}
+
+QDOM_AttrPrivate::~QDOM_AttrPrivate()
+{
+ // qDebug("~ATTR %s=%s", nodeName().latin1(), nodeValue().latin1() );
+}
+
+QDOM_NodePrivate* QDOM_AttrPrivate::cloneNode( bool deep )
+{
+ QDOM_NodePrivate* p = new QDOM_AttrPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+bool QDOM_AttrPrivate::specified() const
+{
+ return m_specified;
+}
+
+/*
+ Encode an attribute value upon saving.
+*/
+static QString encodeAttr( const QString& str )
+{
+ QString tmp( str );
+ uint len = tmp.length();
+ uint i = 0;
+ while ( i < len ) {
+ if ( tmp[(int)i] == '<' ) {
+ tmp.replace( i, 1, "&lt;" );
+ len += 3;
+ i += 4;
+ } else if ( tmp[(int)i] == '"' ) {
+ tmp.replace( i, 1, "&quot;" );
+ len += 5;
+ i += 6;
+ } else if ( tmp[(int)i] == '&' ) {
+ tmp.replace( i, 1, "&amp;" );
+ len += 4;
+ i += 5;
+ } else if ( tmp[(int)i] == '>' && i>=2 && tmp[(int)i-1]==']' && tmp[(int)i-2]==']' ) {
+ tmp.replace( i, 1, "&gt;" );
+ len += 3;
+ i += 4;
+ } else {
+ ++i;
+ }
+ }
+
+ return tmp;
+}
+
+void QDOM_AttrPrivate::save( QTextStream& s, int ) const
+{
+ s << name << "=\"" << encodeAttr( value ) << "\"";
+}
+
+/**************************************************************
+ *
+ * QDomAttr
+ *
+ **************************************************************/
+
+#define IMPL ((QDOM_AttrPrivate*)impl)
+
+/*!
+ \class QDomAttr qdom.h
+ \brief The QDomAttr class represents one attribute of a QDomElement
+
+ \module XML
+
+ For example, the following piece of XML gives an element with no children,
+ but two attributes:
+
+ \code
+ <link href="http://www.trolltech.com" color="red" />
+ \endcode
+
+ One can use the attributes of an element with code similar to:
+
+ \code
+ QDomElement e = ....;
+ QDomAttr a = e.attributeNode( "href" );
+ cout << a.value() << endl // gives "http://www.trolltech.com"
+ a.setValue( "http://doc.trolltech.com" );
+ QDomAttr a2 = e.attributeNode( "href" );
+ cout << a2.value() << endl // gives "http://doc.trolltech.com"
+ \endcode
+
+ This example also shows that changing an attribute received from an element
+ changes the attribute of the element. If you do not want to change the
+ value of the element's attribute you have to use cloneNode() to get an
+ independent copy of the attribute.
+
+ For further information about the Document Objct Model see
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1/">http://www.w3.org/TR/REC-DOM-Level-1/</a>.
+ For a more general introduction of the DOM implementation see the
+ QDomDocument documentation.
+*/
+
+
+/*!
+ Constructs an empty attribute.
+*/
+QDomAttr::QDomAttr()
+{
+}
+
+/*!
+ Copy constructor.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomAttr::QDomAttr( const QDomAttr& x )
+ : QDomNode( x )
+{
+}
+
+/*!
+ \internal
+*/
+QDomAttr::QDomAttr( QDOM_AttrPrivate* n )
+ : QDomNode( n )
+{
+}
+
+/*!
+ Assignment operator.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomAttr& QDomAttr::operator= ( const QDomAttr& x )
+{
+ return (QDomAttr&) QDomNode::operator=( x );
+}
+
+/*!
+ Destructor.
+*/
+QDomAttr::~QDomAttr()
+{
+}
+
+/*!
+ Returns the name of the attribute.
+*/
+QString QDomAttr::name() const
+{
+ if ( !impl )
+ return QString::null;
+ return impl->nodeName();
+}
+
+/*!
+ Returns TRUE if the attribute has been expicitly specified in the XML
+ document or was set by the user with setValue(), otherwise FALSE.
+
+ \sa setValue()
+*/
+bool QDomAttr::specified() const
+{
+ if ( !impl )
+ return FALSE;
+ return IMPL->specified();
+}
+
+/*!
+ Returns the current value of the attribute. Returns a null string
+ when the attribute has not been specified.
+
+ \sa specified() setValue()
+*/
+QString QDomAttr::value() const
+{
+ if ( !impl )
+ return QString::null;
+ return impl->nodeValue();
+}
+
+/*!
+ Sets the value of the attribute to \a v.
+
+ \sa value()
+*/
+void QDomAttr::setValue( const QString& v )
+{
+ if ( !impl )
+ return;
+ impl->setNodeValue( v );
+ IMPL->m_specified = TRUE;
+}
+
+/*!
+ Returns \c AttributeNode.
+*/
+QDomNode::NodeType QDomAttr::nodeType() const
+{
+ return AttributeNode;
+}
+
+/*!
+ Returns TRUE.
+*/
+bool QDomAttr::isAttr() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/*==============================================================*/
+/* Element */
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_ElementPrivate
+ *
+ **************************************************************/
+
+static void qNormalizeElement( QDOM_NodePrivate* n )
+{
+ QDOM_NodePrivate* p = n->first;
+ QDOM_TextPrivate* t = 0;
+
+ while ( p ) {
+ if ( p->isText() ) {
+ if ( t ) {
+ QDOM_NodePrivate* tmp = p->next;
+ t->appendData( p->nodeValue() );
+ n->removeChild( p );
+ p = tmp;
+ } else {
+ t = (QDOM_TextPrivate*)p;
+ p = p->next;
+ }
+ } else {
+ p = p->next;
+ t = 0;
+ }
+ }
+}
+
+
+class QDOM_ElementPrivate : public QDOM_NodePrivate
+{
+public:
+ QDOM_ElementPrivate( QDOM_DocumentPrivate*, QDOM_NodePrivate* parent, const QString& name );
+ QDOM_ElementPrivate( QDOM_ElementPrivate* n, bool deep );
+ ~QDOM_ElementPrivate();
+
+ virtual QString attribute( const QString& name, const QString& defValue ) const;
+ virtual void setAttribute( const QString& name, const QString& value );
+ virtual void removeAttribute( const QString& name );
+ virtual QDOM_AttrPrivate* attributeNode( const QString& name);
+ virtual QDOM_AttrPrivate* setAttributeNode( QDOM_AttrPrivate* newAttr );
+ virtual QDOM_AttrPrivate* removeAttributeNode( QDOM_AttrPrivate* oldAttr );
+ virtual bool hasAttribute( const QString& name );
+ virtual void normalize();
+
+ QString text();
+
+ // Overloaded from QDOM_NodePrivate
+ virtual QDOM_NamedNodeMapPrivate* attributes() { return m_attr; }
+ virtual bool isElement() { return TRUE; }
+ virtual QDOM_NodePrivate* cloneNode( bool deep = TRUE );
+ virtual void save( QTextStream& s, int ) const;
+
+ // Variables
+ QDOM_NamedNodeMapPrivate* m_attr;
+};
+
+QDOM_ElementPrivate::QDOM_ElementPrivate( QDOM_DocumentPrivate* d, QDOM_NodePrivate* p,
+ const QString& tagname )
+ : QDOM_NodePrivate( d, p )
+{
+ name = tagname;
+ m_attr = new QDOM_NamedNodeMapPrivate( this );
+}
+
+QDOM_ElementPrivate::QDOM_ElementPrivate( QDOM_ElementPrivate* n, bool deep ) :
+ QDOM_NodePrivate( n, deep )
+{
+ m_attr = n->m_attr->clone( this );
+ // Reference is down to 0, so we set it to 1 here.
+ m_attr->ref();
+}
+
+QDOM_ElementPrivate::~QDOM_ElementPrivate()
+{
+ // qDebug("~Element=%s", nodeName().latin1() );
+ if ( m_attr->deref() )
+ delete m_attr;
+}
+
+QDOM_NodePrivate* QDOM_ElementPrivate::cloneNode( bool deep)
+{
+ QDOM_NodePrivate* p = new QDOM_ElementPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+QString QDOM_ElementPrivate::attribute( const QString& name_, const QString& defValue ) const
+{
+ QDOM_NodePrivate* n = m_attr->namedItem( name_ );
+ if ( !n )
+ return defValue;
+
+ return n->nodeValue();
+}
+
+void QDOM_ElementPrivate::setAttribute( const QString& aname, const QString& newValue )
+{
+ removeAttribute( aname );
+
+ QDOM_NodePrivate* n = new QDOM_AttrPrivate( ownerDocument(), this, aname );
+ n->setNodeValue( newValue );
+
+ // Referencing is done by the map, so we set the reference
+ // counter back to 0 here. This is ok since we created the QDOM_AttrPrivate.
+ n->deref();
+ m_attr->setNamedItem( n );
+}
+
+void QDOM_ElementPrivate::removeAttribute( const QString& aname )
+{
+ QDOM_NodePrivate* p = m_attr->removeNamedItem( aname );
+ if ( p && p->count == 0 )
+ delete p;
+}
+
+QDOM_AttrPrivate* QDOM_ElementPrivate::attributeNode( const QString& aname )
+{
+ return (QDOM_AttrPrivate*)m_attr->namedItem( aname );
+}
+
+QDOM_AttrPrivate* QDOM_ElementPrivate::setAttributeNode( QDOM_AttrPrivate* newAttr )
+{
+ QDOM_NodePrivate* n = m_attr->namedItem( newAttr->nodeName() );
+
+ // Referencing is done by the maps
+ m_attr->setNamedItem( newAttr );
+
+ return (QDOM_AttrPrivate*)n;
+}
+
+QDOM_AttrPrivate* QDOM_ElementPrivate::removeAttributeNode( QDOM_AttrPrivate* oldAttr )
+{
+ return (QDOM_AttrPrivate*)m_attr->removeNamedItem( oldAttr->nodeName() );
+}
+
+bool QDOM_ElementPrivate::hasAttribute( const QString& aname )
+{
+ return m_attr->contains( aname );
+}
+
+void QDOM_ElementPrivate::normalize()
+{
+ qNormalizeElement( this );
+}
+
+QString QDOM_ElementPrivate::text()
+{
+ QString t( "" );
+
+ QDOM_NodePrivate* p = first;
+ while ( p ) {
+ if ( p->isText() || p->isCDATASection() )
+ t += p->nodeValue();
+ else if ( p->isElement() )
+ t += ((QDOM_ElementPrivate*)p)->text();
+ p = p->next;
+ }
+
+ return t;
+}
+
+void QDOM_ElementPrivate::save( QTextStream& s, int indent ) const
+{
+ for ( int i = 0; i < indent; ++i )
+ s << " ";
+
+ s << "<" << name;
+
+ if ( !m_attr->map.isEmpty() ) {
+ s << " ";
+ QDictIterator<QDOM_NodePrivate> it( m_attr->map );
+ for ( ; it.current(); ++it ) {
+ it.current()->save( s, 0 );
+ s << " ";
+ }
+ }
+
+ if ( last ) { // has child nodes
+ if ( first->isText() )
+ s << ">";
+ else
+ s << ">" << endl;
+ QDOM_NodePrivate::save( s, indent + 1 );
+ if ( !last->isText() )
+ for( int i = 0; i < indent; ++i )
+ s << " ";
+ s << "</" << name << ">" << endl;
+ } else {
+ s << "/>" << endl;
+ }
+}
+
+/**************************************************************
+ *
+ * QDomElement
+ *
+ **************************************************************/
+
+#define IMPL ((QDOM_ElementPrivate*)impl)
+
+/*!
+ \class QDomElement qdom.h
+ \brief The QDomElement class represents one element in the DOM tree.
+
+ \module XML
+
+ Elements have a name() and zero or more attributes associated with them.
+
+ Attributes of the element are represented by QDomAttr objects, that can be
+ queried using the attribute() and attributeNode() functions. You can set
+ attributes with the setAttribute() and setAttributeNode() functions.
+
+ For further information about the Document Objct Model see
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1/">http://www.w3.org/TR/REC-DOM-Level-1/</a>.
+ For a more general introduction of the DOM implementation see the
+ QDomDocument documentation.
+*/
+
+/*!
+ Constructs an empty element. Use the QDomDocument::createElement() function
+ to construct elements with content.
+*/
+QDomElement::QDomElement()
+ : QDomNode()
+{
+}
+
+/*!
+ Copy constructor.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomElement::QDomElement( const QDomElement& x )
+ : QDomNode( x )
+{
+}
+
+/*!
+ \internal
+*/
+QDomElement::QDomElement( QDOM_ElementPrivate* n )
+ : QDomNode( n )
+{
+}
+
+/*!
+ Assignment operator.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomElement& QDomElement::operator= ( const QDomElement& x )
+{
+ return (QDomElement&) QDomNode::operator=( x );
+}
+
+/*!
+ Destructor.
+*/
+QDomElement::~QDomElement()
+{
+}
+
+/*!
+ Returns \c ElementNode.
+*/
+QDomNode::NodeType QDomElement::nodeType() const
+{
+ return ElementNode;
+}
+
+/*!
+ Sets the tag name of this element.
+
+ \sa tagName()
+*/
+void QDomElement::setTagName( const QString& name )
+{
+ if ( impl )
+ impl->name = name;
+}
+
+/*!
+ Returns the tag name of this element. For an XML element like
+ \code
+ <img src="myimg.png">
+ \endcode
+ the tagname would return "img".
+
+ \sa setTagName()
+*/
+QString QDomElement::tagName() const
+{
+ if ( !impl )
+ return QString::null;
+ return impl->nodeName();
+}
+
+/*!
+ Returns the attribute with the name \a name. If the attribute does not exist
+ \a defValue is returned.
+
+ \sa setAttribute() attributeNode() setAttributeNode()
+*/
+QString QDomElement::attribute( const QString& name, const QString& defValue ) const
+{
+ if ( !impl )
+ return defValue;
+ return IMPL->attribute( name, defValue );
+}
+
+/*!
+ Sets the attribute with the name \a name to the string \a value. If the
+ attribute does not exist, a new one is created.
+*/
+void QDomElement::setAttribute( const QString& name, const QString& value )
+{
+ if ( !impl )
+ return;
+ IMPL->setAttribute( name, value );
+}
+
+/*!
+ \overload
+*/
+void QDomElement::setAttribute( const QString& name, int value )
+{
+ if ( !impl )
+ return;
+ QString x;
+ x.setNum( value );
+ IMPL->setAttribute( name, x );
+}
+
+/*!
+ \overload
+*/
+void QDomElement::setAttribute( const QString& name, uint value )
+{
+ if ( !impl )
+ return;
+ QString x;
+ x.setNum( value );
+ IMPL->setAttribute( name, x );
+}
+
+/*!
+ \overload
+*/
+void QDomElement::setAttribute( const QString& name, double value )
+{
+ if ( !impl )
+ return;
+ QString x;
+ x.setNum( value );
+ IMPL->setAttribute( name, x );
+}
+
+/*!
+ Removes the attribute with the name \a name from this element.
+
+ \sa setAttribute() attribute()
+*/
+void QDomElement::removeAttribute( const QString& name )
+{
+ if ( !impl )
+ return;
+ IMPL->removeAttribute( name );
+}
+
+/*!
+ Returns the QDomAttr object that corresponds to the attribute with the name
+ \a name. If no such attribute exists a null object is returned.
+
+ \sa setAttributeNode() attribute() setAttribute()
+*/
+QDomAttr QDomElement::attributeNode( const QString& name)
+{
+ if ( !impl )
+ return QDomAttr();
+ return QDomAttr( IMPL->attributeNode( name ) );
+}
+
+/*!
+ Adds the attribute \a newAttr to this element.
+
+ If an attribute with the name \a newAttr exists in the element, the function
+ returns this attribute; otherwise the function returns a null attribute.
+
+ \sa attributeNode()
+*/
+QDomAttr QDomElement::setAttributeNode( const QDomAttr& newAttr )
+{
+ if ( !impl )
+ return QDomAttr();
+ return QDomAttr( IMPL->setAttributeNode( ((QDOM_AttrPrivate*)newAttr.impl) ) );
+}
+
+/*!
+ Removes the attribute \a oldAttr from the element and returns it.
+
+ \sa attributeNode() setAttributeNode()
+*/
+QDomAttr QDomElement::removeAttributeNode( const QDomAttr& oldAttr )
+{
+ if ( !impl )
+ return QDomAttr(); // ### should this return oldAttr?
+ return QDomAttr( IMPL->removeAttributeNode( ((QDOM_AttrPrivate*)oldAttr.impl) ) );
+}
+
+/*!
+ Returns a QDomNodeList containing all descendant elements of this element
+ with the name \a tagname. The order they are in the node list, is the order
+ they are encountered in a preorder traversal of the element tree.
+*/
+QDomNodeList QDomElement::elementsByTagName( const QString& tagname ) const
+{
+ return QDomNodeList( new QDOM_NodeListPrivate( impl, tagname ) );
+}
+
+
+/*!
+ Calling normalize() on an element brings all its children into a standard
+ form. This means, that adjacent QDomText objects will be merged to
+ one text object (QDomCDATASection nodes are not merged).
+*/
+void QDomElement::normalize()
+{
+ if ( !impl )
+ return;
+ IMPL->normalize();
+}
+
+/*!
+ Returns TRUE.
+*/
+bool QDomElement::isElement() const
+{
+ return TRUE;
+}
+
+/*!
+ Returns a QDomNamedNodeMap containing all attributes for this element.
+
+ \sa attribute() setAttribute() attributeNode() setAttributeNode()
+*/
+QDomNamedNodeMap QDomElement::attributes() const
+{
+ if ( !impl )
+ return QDomNamedNodeMap();
+ return QDomNamedNodeMap( IMPL->attributes() );
+}
+
+/*!
+ Returns TRUE is this element has an attribute with the name \a name,
+ otherwise FALSE.
+*/
+bool QDomElement::hasAttribute( const QString& name ) const
+{
+ if ( !impl )
+ return FALSE;
+ return IMPL->hasAttribute( name );
+}
+
+/*!
+ Returns the text contained inside this element.
+
+ Example:
+ \code
+ <h1>Hello <b>Qt</b> <![CDATA[<xml is cool>]]></h1>
+ \endcode
+
+ The function text() of the QDomElement for the &lt;h1&gt; tag,
+ will return "Hello Qt &lt;xml is cool&gt;".
+
+ Comments are ignored by this function. It evaluates only
+ QDomText and QDomCDATASection objects.
+*/
+QString QDomElement::text() const
+{
+ if ( !impl )
+ return QString::null;
+ return IMPL->text();
+}
+
+#undef IMPL
+
+/*==============================================================*/
+/* Text */
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_TextPrivate
+ *
+ **************************************************************/
+
+QString* QDOM_TextPrivate::textName = 0;
+
+QDOM_TextPrivate::QDOM_TextPrivate( QDOM_DocumentPrivate* d, QDOM_NodePrivate* parent, const QString& value )
+ : QDOM_CharacterDataPrivate( d, parent, value )
+{
+ if ( !textName )
+ textName = new QString( "#text" );
+ name = *textName;
+}
+
+QDOM_TextPrivate::QDOM_TextPrivate( QDOM_TextPrivate* n, bool deep )
+ : QDOM_CharacterDataPrivate( n, deep )
+{
+}
+
+QDOM_TextPrivate::~QDOM_TextPrivate()
+{
+}
+
+QDOM_NodePrivate* QDOM_TextPrivate::cloneNode( bool deep)
+{
+ QDOM_NodePrivate* p = new QDOM_TextPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+QDOM_TextPrivate* QDOM_TextPrivate::splitText( int offset )
+{
+ if ( !parent ) {
+ qWarning( "QDomText::splitText The node has no parent. So I can not split" );
+ return 0;
+ }
+
+ QDOM_TextPrivate* t = new QDOM_TextPrivate( ownerDocument(), 0, value.mid( offset ) );
+ value.truncate( offset );
+
+ parent->insertAfter( t, this );
+
+ return t;
+}
+
+void QDOM_TextPrivate::save( QTextStream& s, int ) const
+{
+ s << encodeAttr( value );
+}
+
+/**************************************************************
+ *
+ * QDomText
+ *
+ **************************************************************/
+
+#define IMPL ((QDOM_TextPrivate*)impl)
+
+/*!
+ \class QDomText qdom.h
+ \brief The QDomText class represents textual data in the parsed XML document.
+
+ \module XML
+
+ For further information about the Document Objct Model see
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1/">http://www.w3.org/TR/REC-DOM-Level-1/</a>.
+ For a more general introduction of the DOM implementation see the
+ QDomDocument documentation.
+*/
+
+/*!
+ Constructs an empty QDomText object.
+
+ To construct a QDomText with content, use QDomDocument::createTextNode().
+*/
+QDomText::QDomText()
+ : QDomCharacterData()
+{
+}
+
+/*!
+ Copy constructor.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomText::QDomText( const QDomText& x )
+ : QDomCharacterData( x )
+{
+}
+
+/*!
+ \internal
+*/
+QDomText::QDomText( QDOM_TextPrivate* n )
+ : QDomCharacterData( n )
+{
+}
+
+/*!
+ Assignment operator.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomText& QDomText::operator= ( const QDomText& x )
+{
+ return (QDomText&) QDomNode::operator=( x );
+}
+
+/*!
+ Destructor.
+*/
+QDomText::~QDomText()
+{
+}
+
+/*!
+ Returns \c TextNode.
+*/
+QDomNode::NodeType QDomText::nodeType() const
+{
+ return TextNode;
+}
+
+/*!
+ Splits this object at position \a offset into two QDomText objects. The newly
+ created object is inserted into the document tree after this object.
+
+ The function returns the newly created object.
+
+ \sa QDomElement::normalize()
+*/
+QDomText QDomText::splitText( int offset )
+{
+ if ( !impl )
+ return QDomText();
+ return QDomText( IMPL->splitText( offset ) );
+}
+
+/*!
+ Returns TRUE.
+*/
+bool QDomText::isText() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/*==============================================================*/
+/* Comment */
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_CommentPrivate
+ *
+ **************************************************************/
+
+class QDOM_CommentPrivate : public QDOM_CharacterDataPrivate
+{
+public:
+ QDOM_CommentPrivate( QDOM_DocumentPrivate*, QDOM_NodePrivate* parent, const QString& value );
+ QDOM_CommentPrivate( QDOM_CommentPrivate* n, bool deep );
+ ~QDOM_CommentPrivate();
+
+ // Overloaded from QDOM_NodePrivate
+ virtual QDOM_NodePrivate* cloneNode( bool deep = TRUE );
+ bool isComment() { return TRUE; }
+ virtual void save( QTextStream& s, int ) const;
+
+ static QString* commentName;
+};
+
+QString* QDOM_CommentPrivate::commentName = 0;
+
+QDOM_CommentPrivate::QDOM_CommentPrivate( QDOM_DocumentPrivate* d, QDOM_NodePrivate* parent, const QString& value )
+ : QDOM_CharacterDataPrivate( d, parent, value )
+{
+ if ( !commentName )
+ commentName = new QString( "#comment" );
+ name = *commentName;
+}
+
+QDOM_CommentPrivate::QDOM_CommentPrivate( QDOM_CommentPrivate* n, bool deep )
+ : QDOM_CharacterDataPrivate( n, deep )
+{
+}
+
+QDOM_CommentPrivate::~QDOM_CommentPrivate()
+{
+}
+
+QDOM_NodePrivate* QDOM_CommentPrivate::cloneNode( bool deep)
+{
+ QDOM_NodePrivate* p = new QDOM_CommentPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+void QDOM_CommentPrivate::save( QTextStream& s, int ) const
+{
+ s << "<!--" << value << "-->";
+}
+
+/**************************************************************
+ *
+ * QDomComment
+ *
+ **************************************************************/
+
+#define IMPL ((QDOM_CommentPrivate*)impl)
+
+/*!
+ \class QDomComment qdom.h
+ \brief The QDomComment class represents an XML comment.
+
+ \module XML
+
+ A comment in the parsed XML such as
+ \code
+ <!-- this is a comment -->
+ \endcode
+ is represented by QDomComment objects in the parsed Dom tree.
+
+ For further information about the Document Objct Model see
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1/">http://www.w3.org/TR/REC-DOM-Level-1/</a>.
+ For a more general introduction of the DOM implementation see the
+ QDomDocument documentation.
+*/
+
+/*!
+ Constructs an empty comment. To construct a comment with content, use
+ the QDomDocument::createComment() function.
+*/
+QDomComment::QDomComment()
+ : QDomCharacterData()
+{
+}
+
+/*!
+ Copy constructor.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomComment::QDomComment( const QDomComment& x )
+ : QDomCharacterData( x )
+{
+}
+
+/*!
+ \internal
+*/
+QDomComment::QDomComment( QDOM_CommentPrivate* n )
+ : QDomCharacterData( n )
+{
+}
+
+/*!
+ Assignment operator.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomComment& QDomComment::operator= ( const QDomComment& x )
+{
+ return (QDomComment&) QDomNode::operator=( x );
+}
+
+/*!
+ Destructor.
+*/
+QDomComment::~QDomComment()
+{
+}
+
+/*!
+ Returns \c CommentNode.
+*/
+QDomNode::NodeType QDomComment::nodeType() const
+{
+ return CommentNode;
+}
+
+/*!
+ Returns TRUE.
+*/
+bool QDomComment::isComment() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/*==============================================================*/
+/* CDATASection */
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_CDATASectionPrivate
+ *
+ **************************************************************/
+
+class QDOM_CDATASectionPrivate : public QDOM_TextPrivate
+{
+public:
+ QDOM_CDATASectionPrivate( QDOM_DocumentPrivate*, QDOM_NodePrivate* parent, const QString& value );
+ QDOM_CDATASectionPrivate( QDOM_CDATASectionPrivate* n, bool deep );
+ ~QDOM_CDATASectionPrivate();
+
+ // Overloaded from QDOM_NodePrivate
+ virtual QDOM_NodePrivate* cloneNode( bool deep = TRUE );
+ virtual bool isCDATASection() { return TRUE; }
+ virtual void save( QTextStream& s, int ) const;
+
+ static QString* cdataName;
+};
+
+QString* QDOM_CDATASectionPrivate::cdataName = 0;
+
+QDOM_CDATASectionPrivate::QDOM_CDATASectionPrivate( QDOM_DocumentPrivate* d, QDOM_NodePrivate* parent,
+ const QString& value )
+ : QDOM_TextPrivate( d, parent, value )
+{
+ if ( !cdataName )
+ cdataName = new QString( "#cdata-section" );
+ name = *cdataName;
+}
+
+QDOM_CDATASectionPrivate::QDOM_CDATASectionPrivate( QDOM_CDATASectionPrivate* n, bool deep )
+ : QDOM_TextPrivate( n, deep )
+{
+}
+
+QDOM_CDATASectionPrivate::~QDOM_CDATASectionPrivate()
+{
+}
+
+QDOM_NodePrivate* QDOM_CDATASectionPrivate::cloneNode( bool deep)
+{
+ QDOM_NodePrivate* p = new QDOM_CDATASectionPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+void QDOM_CDATASectionPrivate::save( QTextStream& s, int ) const
+{
+ // #### How do we escape "]]>" ?
+ s << "<![CDATA[" << value << "]]>";
+}
+
+/**************************************************************
+ *
+ * QDomCDATASection
+ *
+ **************************************************************/
+
+#define IMPL ((QDOM_CDATASectionPrivate*)impl)
+
+/*!
+ \class QDomCDATASection qdom.h
+ \brief The QDomCDATASection class represents an XML CDATA section.
+
+ \module XML
+
+ CDATA sections are used to escape blocks of text containing
+ characters that would otherwise be regarded as markup. The only
+ delimiter that is recognized in a CDATA section is the "]]&gt;"
+ string that ends the CDATA section. CDATA sections can not be
+ nested. The primary purpose is for including material such as XML
+ fragments, without needing to escape all the delimiters.
+
+ Adjacent QDomCDATASection nodes are not merged by the
+ QDomElement.normalize() function.
+
+ For further information about the Document Objct Model see
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1/">http://www.w3.org/TR/REC-DOM-Level-1/</a>.
+ For a more general introduction of the DOM implementation see the
+ QDomDocument documentation.
+*/
+
+/*!
+ Constructs an empty CDATA section. To create a CDATA section with content,
+ use the QDomDocument::createCDATASection() function.
+*/
+QDomCDATASection::QDomCDATASection()
+ : QDomText()
+{
+}
+
+/*!
+ Copy constructor.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomCDATASection::QDomCDATASection( const QDomCDATASection& x )
+ : QDomText( x )
+{
+}
+
+/*!
+ \internal
+*/
+QDomCDATASection::QDomCDATASection( QDOM_CDATASectionPrivate* n )
+ : QDomText( n )
+{
+}
+
+/*!
+ Assigment operator.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomCDATASection& QDomCDATASection::operator= ( const QDomCDATASection& x )
+{
+ return (QDomCDATASection&) QDomNode::operator=( x );
+}
+
+/*!
+ Destructor.
+*/
+QDomCDATASection::~QDomCDATASection()
+{
+}
+
+/*!
+ Returns \c CDATASection.
+*/
+QDomNode::NodeType QDomCDATASection::nodeType() const
+{
+ return CDATASectionNode;
+}
+
+/*!
+ Returns TRUE
+*/
+bool QDomCDATASection::isCDATASection() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/*==============================================================*/
+/* Notation */
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_NotationPrivate
+ *
+ **************************************************************/
+
+class QDOM_NotationPrivate : public QDOM_NodePrivate
+{
+public:
+ QDOM_NotationPrivate( QDOM_DocumentPrivate*, QDOM_NodePrivate* parent, const QString& name,
+ const QString& pub, const QString& sys );
+ QDOM_NotationPrivate( QDOM_NotationPrivate* n, bool deep );
+ ~QDOM_NotationPrivate();
+
+ // Overloaded from QDOM_NodePrivate
+ virtual QDOM_NodePrivate* cloneNode( bool deep = TRUE );
+ virtual bool isNotation() { return TRUE; }
+ virtual void save( QTextStream& s, int ) const;
+
+ // Variables
+ QString m_sys;
+ QString m_pub;
+};
+
+QDOM_NotationPrivate::QDOM_NotationPrivate( QDOM_DocumentPrivate* d, QDOM_NodePrivate* parent,
+ const QString& aname,
+ const QString& pub, const QString& sys )
+ : QDOM_NodePrivate( d, parent )
+{
+ name = aname;
+ m_pub = pub;
+ m_sys = sys;
+}
+
+QDOM_NotationPrivate::QDOM_NotationPrivate( QDOM_NotationPrivate* n, bool deep )
+ : QDOM_NodePrivate( n, deep )
+{
+ m_sys = n->m_sys;
+ m_pub = n->m_pub;
+}
+
+QDOM_NotationPrivate::~QDOM_NotationPrivate()
+{
+}
+
+QDOM_NodePrivate* QDOM_NotationPrivate::cloneNode( bool deep)
+{
+ QDOM_NodePrivate* p = new QDOM_NotationPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+void QDOM_NotationPrivate::save( QTextStream& s, int ) const
+{
+ s << "<!NOTATION " << name << " ";
+ if ( !m_pub.isEmpty() ) {
+ s << "PUBLIC \"" << m_pub << "\"";
+ if ( !m_sys.isEmpty() )
+ s << " \"" << m_sys << "\"";
+ } else {
+ s << "SYSTEM \"" << m_sys << "\"";
+ }
+ s << ">";
+}
+
+/**************************************************************
+ *
+ * QDomNotation
+ *
+ **************************************************************/
+
+#define IMPL ((QDOM_NotationPrivate*)impl)
+
+/*!
+ \class QDomNotation qdom.h
+ \brief The QDomNotation class represents an XML notation.
+
+ \module XML
+
+ A notation either declares, by name, the format of an unparsed entity
+ (see section 4.7 of the XML 1.0 specification), or is used for
+ formal declaration of processing instruction targets (see section
+ 2.6 of the XML 1.0 specification).
+
+ DOM does not support editing notation nodes; they are therefore readonly.
+
+ A notation node does not have any parent.
+
+ For further information about the Document Objct Model see
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1/">http://www.w3.org/TR/REC-DOM-Level-1/</a>.
+ For a more general introduction of the DOM implementation see the
+ QDomDocument documentation.
+*/
+
+
+/*!
+ Constructor.
+*/
+QDomNotation::QDomNotation()
+ : QDomNode()
+{
+}
+
+/*!
+ Copy constructor.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomNotation::QDomNotation( const QDomNotation& x )
+ : QDomNode( x )
+{
+}
+
+/*!
+ \internal
+*/
+QDomNotation::QDomNotation( QDOM_NotationPrivate* n )
+ : QDomNode( n )
+{
+}
+
+/*!
+ Assignment operator.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomNotation& QDomNotation::operator= ( const QDomNotation& x )
+{
+ return (QDomNotation&) QDomNode::operator=( x );
+}
+
+/*!
+ Destructor.
+*/
+QDomNotation::~QDomNotation()
+{
+}
+
+/*!
+ Returns \c NotationNode.
+*/
+QDomNode::NodeType QDomNotation::nodeType() const
+{
+ return NotationNode;
+}
+
+/*!
+ Returns the public identifier of this notation.
+*/
+QString QDomNotation::publicId() const
+{
+ if ( !impl )
+ return QString::null;
+ return IMPL->m_pub;
+}
+
+/*!
+ Returns the system identifier of this notation.
+*/
+QString QDomNotation::systemId() const
+{
+ if ( !impl )
+ return QString::null;
+ return IMPL->m_sys;
+}
+
+/*!
+ Returns TRUE.
+*/
+bool QDomNotation::isNotation() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+
+/*==============================================================*/
+/* Entity */
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_EntityPrivate
+ *
+ **************************************************************/
+
+class QDOM_EntityPrivate : public QDOM_NodePrivate
+{
+public:
+ QDOM_EntityPrivate( QDOM_DocumentPrivate*, QDOM_NodePrivate* parent, const QString& name,
+ const QString& pub, const QString& sys, const QString& notation );
+ QDOM_EntityPrivate( QDOM_EntityPrivate* n, bool deep );
+ ~QDOM_EntityPrivate();
+
+ // Overloaded from QDOM_NodePrivate
+ virtual QDOM_NodePrivate* cloneNode( bool deep = TRUE );
+ virtual bool isEntity() { return TRUE; }
+ virtual void save( QTextStream& s, int ) const;
+
+ // Variables
+ QString m_sys;
+ QString m_pub;
+ QString m_notationName;
+};
+
+QDOM_EntityPrivate::QDOM_EntityPrivate( QDOM_DocumentPrivate* d, QDOM_NodePrivate* parent,
+ const QString& aname,
+ const QString& pub, const QString& sys, const QString& notation )
+ : QDOM_NodePrivate( d, parent )
+{
+ name = aname;
+ m_pub = pub;
+ m_sys = sys;
+ m_notationName = notation;
+}
+
+QDOM_EntityPrivate::QDOM_EntityPrivate( QDOM_EntityPrivate* n, bool deep )
+ : QDOM_NodePrivate( n, deep )
+{
+ m_sys = n->m_sys;
+ m_pub = n->m_pub;
+ m_notationName = n->m_notationName;
+}
+
+QDOM_EntityPrivate::~QDOM_EntityPrivate()
+{
+}
+
+QDOM_NodePrivate* QDOM_EntityPrivate::cloneNode( bool deep)
+{
+ QDOM_NodePrivate* p = new QDOM_EntityPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+/*
+ Encode an entity value upon saving.
+*/
+static QCString encodeEntity( const QCString& str )
+{
+ QCString tmp( str );
+ uint len = tmp.length();
+ uint i = 0;
+ const char* d = tmp.data();
+ while ( i < len ) {
+ if ( d[i] == '%' ){
+ tmp.replace( i, 1, "&#60;" );
+ d = tmp.data();
+ len += 4;
+ i += 5;
+ }
+ else if ( d[i] == '"' ) {
+ tmp.replace( i, 1, "&#34;" );
+ d = tmp.data();
+ len += 4;
+ i += 5;
+ } else if ( d[i] == '&' && i + 1 < len && d[i+1] == '#' ) {
+ // Dont encode &lt; or &quot; or &custom;.
+ // Only encode character references
+ tmp.replace( i, 1, "&#38;" );
+ d = tmp.data();
+ len += 4;
+ i += 5;
+ } else {
+ ++i;
+ }
+ }
+
+ return tmp;
+}
+
+void QDOM_EntityPrivate::save( QTextStream& s, int ) const
+{
+ if ( m_sys.isEmpty() && m_pub.isEmpty() ) {
+ s << "<!ENTITY " << name << " \"" << encodeEntity( value.utf8() ) << "\">";
+ } else {
+ s << "<!ENTITY " << name << " ";
+ if ( m_pub.isEmpty() )
+ s << "SYSTEM \"" << m_sys << "\"";
+ else
+ s << "PUBLIC \"" << m_pub << "\" \"" << m_sys << "\"";
+ if ( !m_notationName.isEmpty() )
+ s << "NDATA" << m_notationName;
+ s << ">";
+ }
+}
+
+/**************************************************************
+ *
+ * QDomEntity
+ *
+ **************************************************************/
+
+#define IMPL ((QDOM_EntityPrivate*)impl)
+
+/*!
+ \class QDomEntity qdom.h
+ \brief The QDomEntity class represents an XML entity.
+
+ \module XML
+
+ This class represents an entity in an XML document, either parsed or
+ unparsed. Note that this models the entity itself not the entity declaration.
+
+ DOM does not support editing entity nodes; if a user wants to make changes to
+ the contents of an entity, every related QDomEntityReference node has to be
+ replaced in the DOM tree by a clone of the entity's contents, and then
+ the desired changes must be made to each of those clones instead. All the
+ descendants of an entity node are readonly.
+
+ An entity node does not have any parent.
+
+ For further information about the Document Objct Model see
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1/">http://www.w3.org/TR/REC-DOM-Level-1/</a>.
+ For a more general introduction of the DOM implementation see the
+ QDomDocument documentation.
+*/
+
+
+/*!
+ Constructs an empty entity.
+*/
+QDomEntity::QDomEntity()
+ : QDomNode()
+{
+}
+
+
+/*!
+ Copy constructor.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomEntity::QDomEntity( const QDomEntity& x )
+ : QDomNode( x )
+{
+}
+
+/*!
+ \internal
+*/
+QDomEntity::QDomEntity( QDOM_EntityPrivate* n )
+ : QDomNode( n )
+{
+}
+
+/*!
+ Assignment operator.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomEntity& QDomEntity::operator= ( const QDomEntity& x )
+{
+ return (QDomEntity&) QDomNode::operator=( x );
+}
+
+/*!
+ Destructor.
+*/
+QDomEntity::~QDomEntity()
+{
+}
+
+/*!
+ Returns \c EntityNode.
+*/
+QDomNode::NodeType QDomEntity::nodeType() const
+{
+ return EntityNode;
+}
+
+/*!
+ Returns the public identifier associated with this entity.
+ If the public identifier was not specified QString::null is returned.
+*/
+QString QDomEntity::publicId() const
+{
+ if ( !impl )
+ return QString::null;
+ return IMPL->m_pub;
+}
+
+/*!
+ Returns the system identifier associated with this entity.
+ If the system identifier was not specified QString::null is returned.
+*/
+QString QDomEntity::systemId() const
+{
+ if ( !impl )
+ return QString::null;
+ return IMPL->m_sys;
+}
+
+/*!
+ For unparsed entities this function returns the name of the notation for the
+ entity. For parsed entities this function returns QString::null.
+*/
+QString QDomEntity::notationName() const
+{
+ if ( !impl )
+ return QString::null;
+ return IMPL->m_notationName;
+}
+
+/*!
+ Returns TRUE.
+*/
+bool QDomEntity::isEntity() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+
+/*==============================================================*/
+/* EntityReference */
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_EntityReferencePrivate
+ *
+ **************************************************************/
+
+class QDOM_EntityReferencePrivate : public QDOM_NodePrivate
+{
+public:
+ QDOM_EntityReferencePrivate( QDOM_DocumentPrivate*, QDOM_NodePrivate* parent, const QString& name );
+ QDOM_EntityReferencePrivate( QDOM_NodePrivate* n, bool deep );
+ ~QDOM_EntityReferencePrivate();
+
+ // Overloaded from QDOM_NodePrivate
+ virtual QDOM_NodePrivate* cloneNode( bool deep = TRUE );
+ virtual bool isEntityReference() { return TRUE; }
+ virtual void save( QTextStream& s, int ) const;
+};
+
+QDOM_EntityReferencePrivate::QDOM_EntityReferencePrivate( QDOM_DocumentPrivate* d, QDOM_NodePrivate* parent, const QString& aname )
+ : QDOM_NodePrivate( d, parent )
+{
+ name = aname;
+}
+
+QDOM_EntityReferencePrivate::QDOM_EntityReferencePrivate( QDOM_NodePrivate* n, bool deep )
+ : QDOM_NodePrivate( n, deep )
+{
+}
+
+QDOM_EntityReferencePrivate::~QDOM_EntityReferencePrivate()
+{
+}
+
+QDOM_NodePrivate* QDOM_EntityReferencePrivate::cloneNode( bool deep)
+{
+ QDOM_NodePrivate* p = new QDOM_EntityReferencePrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+void QDOM_EntityReferencePrivate::save( QTextStream& s, int ) const
+{
+ s << "&" << name << ";";
+}
+
+/**************************************************************
+ *
+ * QDomEntityReference
+ *
+ **************************************************************/
+
+#define IMPL ((QDOM_EntityReferencePrivate*)impl)
+
+/*!
+ \class QDomEntityReference qdom.h
+ \brief The QDomEntityReference class represents an XML entity reference.
+
+ \module XML
+
+ A QDomEntityReference object may be inserted into the
+ DOM tree when an entity reference is in the source document,
+ or when the user wishes to insert an entity reference.
+
+ Note that character references and references to predefined entities are
+ expanded by the XML processor so that characters are represented by their
+ Unicode equivalent rather than by an entity reference.
+
+ Moreover, the XML processor may completely expand references to entities
+ while building the DOM tree, instead of providing QDomEntityReference
+ objects.
+
+ If it does provide such objects, then for a given entity reference node, it
+ may be that there is no entity node representing the referenced entity; but
+ if such an entity exists, then the child list of the entity reference node is
+ the same as that of the entity node. As with the entity node, all
+ descendants of the entity reference are readonly.
+
+ For further information about the Document Objct Model see
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1/">http://www.w3.org/TR/REC-DOM-Level-1/</a>.
+ For a more general introduction of the DOM implementation see the
+ QDomDocument documentation.
+*/
+
+
+
+/*!
+ Constructs an empty entity reference. Use
+ QDomDocument::createEntityReference() to create a entity reference with
+ content.
+*/
+QDomEntityReference::QDomEntityReference()
+ : QDomNode()
+{
+}
+
+/*!
+ Copy constructor.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomEntityReference::QDomEntityReference( const QDomEntityReference& x )
+ : QDomNode( x )
+{
+}
+
+/*!
+ \internal
+*/
+QDomEntityReference::QDomEntityReference( QDOM_EntityReferencePrivate* n )
+ : QDomNode( n )
+{
+}
+
+/*!
+ Assignment operator.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomEntityReference& QDomEntityReference::operator= ( const QDomEntityReference& x )
+{
+ return (QDomEntityReference&) QDomNode::operator=( x );
+}
+
+/*!
+ Destructor.
+*/
+QDomEntityReference::~QDomEntityReference()
+{
+}
+
+/*!
+ Returns \c EntityReference.
+*/
+QDomNode::NodeType QDomEntityReference::nodeType() const
+{
+ return EntityReferenceNode;
+}
+
+/*!
+ Returns TRUE.
+*/
+bool QDomEntityReference::isEntityReference() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+
+/*==============================================================*/
+/* ProcessingInstruction */
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_ProcessingInstructionPrivate
+ *
+ **************************************************************/
+
+class QDOM_ProcessingInstructionPrivate : public QDOM_NodePrivate
+{
+public:
+ QDOM_ProcessingInstructionPrivate( QDOM_DocumentPrivate*, QDOM_NodePrivate* parent, const QString& target,
+ const QString& data);
+ QDOM_ProcessingInstructionPrivate( QDOM_ProcessingInstructionPrivate* n, bool deep );
+ ~QDOM_ProcessingInstructionPrivate();
+
+ // Overloaded from QDOM_NodePrivate
+ virtual QDOM_NodePrivate* cloneNode( bool deep = TRUE );
+ virtual bool isProcessingInstruction() { return TRUE; }
+ virtual void save( QTextStream& s, int ) const;
+};
+
+QDOM_ProcessingInstructionPrivate::QDOM_ProcessingInstructionPrivate( QDOM_DocumentPrivate* d,
+ QDOM_NodePrivate* parent,
+ const QString& target,
+ const QString& data )
+ : QDOM_NodePrivate( d, parent )
+{
+ name = target;
+ value = data;
+}
+
+QDOM_ProcessingInstructionPrivate::QDOM_ProcessingInstructionPrivate( QDOM_ProcessingInstructionPrivate* n, bool deep )
+ : QDOM_NodePrivate( n, deep )
+{
+}
+
+QDOM_ProcessingInstructionPrivate::~QDOM_ProcessingInstructionPrivate()
+{
+}
+
+QDOM_NodePrivate* QDOM_ProcessingInstructionPrivate::cloneNode( bool deep)
+{
+ QDOM_NodePrivate* p = new QDOM_ProcessingInstructionPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+void QDOM_ProcessingInstructionPrivate::save( QTextStream& s, int ) const
+{
+ s << "<?" << name << " " << value << "?>";
+}
+
+/**************************************************************
+ *
+ * QDomProcessingInstruction
+ *
+ **************************************************************/
+
+#define IMPL ((QDOM_ProcessingInstructionPrivate*)impl)
+
+/*!
+ \class QDomProcessingInstruction qdom.h
+ \brief The QDomProcessingInstruction class represents an XML processing
+ instruction.
+
+ \module XML
+
+ Processing instructions are used in XML as a way to keep processor-specific
+ information in the text of the document.
+
+ For further information about the Document Objct Model see
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1/">http://www.w3.org/TR/REC-DOM-Level-1/</a>.
+ For a more general introduction of the DOM implementation see the
+ QDomDocument documentation.
+*/
+
+/*!
+ Constructs an empty processing instruction. Use
+ QDomDocument::createProcessingInstruction() to create a processing
+ instruction with content.
+*/
+QDomProcessingInstruction::QDomProcessingInstruction()
+ : QDomNode()
+{
+}
+
+/*!
+ Copy constructor.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomProcessingInstruction::QDomProcessingInstruction( const QDomProcessingInstruction& x )
+ : QDomNode( x )
+{
+}
+
+/*!
+ \internal
+*/
+QDomProcessingInstruction::QDomProcessingInstruction( QDOM_ProcessingInstructionPrivate* n )
+ : QDomNode( n )
+{
+}
+
+/*!
+ Assignment operator.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomProcessingInstruction& QDomProcessingInstruction::operator= ( const QDomProcessingInstruction& x )
+{
+ return (QDomProcessingInstruction&) QDomNode::operator=( x );
+}
+
+/*!
+ Destructor.
+*/
+QDomProcessingInstruction::~QDomProcessingInstruction()
+{
+}
+
+/*!
+ Returns \c ProcessingInstructionNode.
+*/
+QDomNode::NodeType QDomProcessingInstruction::nodeType() const
+{
+ return ProcessingInstructionNode;
+}
+
+/*!
+ Returns the target of this processing instruction.
+
+ \sa data()
+*/
+QString QDomProcessingInstruction::target() const
+{
+ if ( !impl )
+ return QString::null;
+ return impl->nodeName();
+}
+
+/*!
+ Returns the content of this processing instruction.
+
+ \sa setData() target()
+*/
+QString QDomProcessingInstruction::data() const
+{
+ if ( !impl )
+ return QString::null;
+ return impl->nodeValue();
+}
+
+/*!
+ Sets the data contained in the processing instruction.
+
+ \sa data()
+*/
+void QDomProcessingInstruction::setData( const QString& d )
+{
+ if ( !impl )
+ return;
+ impl->setNodeValue( d );
+}
+
+/*!
+ Returns TRUE.
+*/
+bool QDomProcessingInstruction::isProcessingInstruction() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/*==============================================================*/
+/* Document */
+/*==============================================================*/
+
+/**************************************************************
+ *
+ * QDOM_DocumentPrivate
+ *
+ **************************************************************/
+
+class QDOM_DocumentPrivate : public QDOM_NodePrivate
+{
+public:
+ QDOM_DocumentPrivate();
+ QDOM_DocumentPrivate( const QString& name );
+ QDOM_DocumentPrivate( QDOM_DocumentPrivate* n, bool deep );
+ ~QDOM_DocumentPrivate();
+
+ bool setContent( QXmlInputSource& source );
+
+ // Attributes
+ QDOM_DocumentTypePrivate* doctype() { return type; };
+ QDOM_ImplementationPrivate* implementation() { return impl; };
+ QDOM_ElementPrivate* documentElement();
+
+ // Factories
+ QDOM_ElementPrivate* createElement( const QString& tagName );
+ QDOM_DocumentFragmentPrivate* createDocumentFragment();
+ QDOM_TextPrivate* createTextNode( const QString& data );
+ QDOM_CommentPrivate* createComment( const QString& data );
+ QDOM_CDATASectionPrivate* createCDATASection( const QString& data );
+ QDOM_ProcessingInstructionPrivate* createProcessingInstruction( const QString& target, const QString& data );
+ QDOM_AttrPrivate* createAttribute( const QString& name );
+ QDOM_EntityReferencePrivate* createEntityReference( const QString& name );
+ QDOM_NodeListPrivate* elementsByTagName( const QString& tagname );
+
+ // Overloaded from QDOM_NodePrivate
+ virtual QDOM_NodePrivate* cloneNode( bool deep = TRUE );
+ virtual bool isDocument() { return TRUE; }
+ virtual void clear();
+ virtual void save( QTextStream&, int ) const;
+
+ // Variables
+ QDOM_ImplementationPrivate* impl;
+ QDOM_DocumentTypePrivate* type;
+
+ static QString* docName;
+};
+
+QString* QDOM_DocumentPrivate::docName = 0;
+
+QDOM_DocumentPrivate::QDOM_DocumentPrivate()
+ : QDOM_NodePrivate( 0 )
+{
+ impl = new QDOM_ImplementationPrivate();
+ type = new QDOM_DocumentTypePrivate( this, this );
+
+ if ( !docName )
+ docName = new QString( "#document" );
+ name = *docName;
+}
+
+QDOM_DocumentPrivate::QDOM_DocumentPrivate( const QString& aname )
+ : QDOM_NodePrivate( 0 )
+{
+ impl = new QDOM_ImplementationPrivate();
+ type = new QDOM_DocumentTypePrivate( this, this );
+ type->name = aname;
+
+ if ( !docName )
+ docName = new QString( "#document" );
+ QDOM_DocumentPrivate::name = *docName;
+}
+
+QDOM_DocumentPrivate::QDOM_DocumentPrivate( QDOM_DocumentPrivate* n, bool deep )
+ : QDOM_NodePrivate( n, deep )
+{
+ impl = n->impl->clone();
+ // Reference count is down to 0, so we set it to 1 here.
+ impl->ref();
+ type = (QDOM_DocumentTypePrivate*)n->type->cloneNode();
+ type->setParent( this );
+ // Reference count is down to 0, so we set it to 1 here.
+ type->ref();
+}
+
+QDOM_DocumentPrivate::~QDOM_DocumentPrivate()
+{
+ // qDebug("~Document %x", this);
+ if ( impl->deref() ) delete impl;
+ if ( type->deref() ) delete type;
+}
+
+void QDOM_DocumentPrivate::clear()
+{
+ if ( impl->deref() ) delete impl;
+ if ( type->deref() ) delete type;
+ impl = 0;
+ type = 0;
+ QDOM_NodePrivate::clear();
+}
+
+bool QDOM_DocumentPrivate::setContent( QXmlInputSource& source )
+{
+ clear();
+ impl = new QDOM_ImplementationPrivate;
+ type = new QDOM_DocumentTypePrivate( this, this );
+
+ QXmlSimpleReader reader;
+ QDomHandler hnd( this );
+ reader.setContentHandler( &hnd );
+ reader.setErrorHandler( &hnd );
+ reader.setLexicalHandler( &hnd );
+ reader.setDeclHandler( &hnd );
+ reader.setDTDHandler( &hnd );
+#if defined(Q_BROKEN_ALPHA) // #### very ugly hack, ws should really be able to get rid of that
+ reader.setFeature( "http://xml.org/sax/features/namespaces", TRUE );
+#else
+ reader.setFeature( "http://xml.org/sax/features/namespaces", FALSE );
+#endif
+ reader.setFeature( "http://xml.org/sax/features/namespace-prefixes", TRUE );
+ reader.setFeature( "http://trolltech.com/xml/features/report-whitespace-only-CharData", FALSE );
+
+ if ( !reader.parse( source ) ) {
+ qWarning("Parsing error");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+QDOM_NodePrivate* QDOM_DocumentPrivate::cloneNode( bool deep)
+{
+ QDOM_NodePrivate* p = new QDOM_DocumentPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+QDOM_ElementPrivate* QDOM_DocumentPrivate::documentElement()
+{
+ QDOM_NodePrivate* p = first;
+ while ( p && !p->isElement() )
+ p = p->next;
+
+ return (QDOM_ElementPrivate*)p;
+}
+
+QDOM_ElementPrivate* QDOM_DocumentPrivate::createElement( const QString& tagName )
+{
+ QDOM_ElementPrivate* e = new QDOM_ElementPrivate( this, this, tagName );
+ e->deref();
+ return e;
+}
+
+QDOM_DocumentFragmentPrivate* QDOM_DocumentPrivate::createDocumentFragment()
+{
+ QDOM_DocumentFragmentPrivate* f = new QDOM_DocumentFragmentPrivate( this, this );
+ f->deref();
+ return f;
+}
+
+QDOM_TextPrivate* QDOM_DocumentPrivate::createTextNode( const QString& data )
+{
+ QDOM_TextPrivate* t = new QDOM_TextPrivate( this, this, data );
+ t->deref();
+ return t;
+}
+
+QDOM_CommentPrivate* QDOM_DocumentPrivate::createComment( const QString& data )
+{
+ QDOM_CommentPrivate* c = new QDOM_CommentPrivate( this, this, data );
+ c->deref();
+ return c;
+}
+
+QDOM_CDATASectionPrivate* QDOM_DocumentPrivate::createCDATASection( const QString& data )
+{
+ QDOM_CDATASectionPrivate* c = new QDOM_CDATASectionPrivate( this, this, data );
+ c->deref();
+ return c;
+}
+
+QDOM_ProcessingInstructionPrivate* QDOM_DocumentPrivate::createProcessingInstruction( const QString& target, const QString& data )
+{
+ QDOM_ProcessingInstructionPrivate* p = new QDOM_ProcessingInstructionPrivate( this, this, target, data );
+ p->deref();
+ return p;
+}
+
+QDOM_AttrPrivate* QDOM_DocumentPrivate::createAttribute( const QString& aname )
+{
+ QDOM_AttrPrivate* a = new QDOM_AttrPrivate( this, this, aname );
+ a->deref();
+ return a;
+}
+
+QDOM_EntityReferencePrivate* QDOM_DocumentPrivate::createEntityReference( const QString& aname )
+{
+ QDOM_EntityReferencePrivate* e = new QDOM_EntityReferencePrivate( this, this, aname );
+ e->deref();
+ return e;
+}
+
+void QDOM_DocumentPrivate::save( QTextStream& s, int ) const
+{
+ bool doc = FALSE;
+
+ QDOM_NodePrivate* n = first;
+ while ( n ) {
+ if ( !doc && !n->isProcessingInstruction() ) {
+ type->save( s, 0 );
+ doc = TRUE;
+ }
+ n->save( s, 0 );
+ n = n->next;
+ }
+}
+
+/**************************************************************
+ *
+ * QDomDocument
+ *
+ **************************************************************/
+
+#define IMPL ((QDOM_DocumentPrivate*)impl)
+
+/*!
+ \class QDomDocument qdom.h
+ \brief The QDomDocument class is the representation of an XML document.
+
+ \module XML
+
+ The QDomDocument class represents the entire XML document. Conceptually, it
+ is the root of the document tree, and provides the primary access to the
+ document's data.
+
+ Since elements, text nodes, comments, processing instructions, etc. cannot
+ exist outside the context of a document, the document class also contains the
+ factory functions needed to create these objects. The node objects created
+ have an ownerDocument() function which associates them with the document
+ within whose context they were created.
+
+ The parsed XML is represented internally by a tree of objects that can be
+ accessed using the various QDom classes. All QDom classes do only reference
+ objects in the internal tree. The internal objects in the DOM tree will get
+ deleted, once the last QDom object referencing them and the QDomDocument are
+ deleted.
+
+ Creation of elements, text nodes, etc. is done via the various factory
+ functions provided in this class. Using the default constructors of the QDom
+ classes will only result in empty objects, that can not be manipulated or
+ inserted into the Document.
+
+ The QDom classes are typically used as follows:
+ \code
+ QDomDocument doc( "mydocument" );
+ QFile f( "mydocument.xml" );
+ if ( !f.open( IO_ReadOnly ) )
+ return;
+ if ( !doc.setContent( &f ) ) {
+ f.close();
+ return;
+ }
+ f.close();
+
+ // print out the element names of all elements that are a direct child
+ // of the outermost element.
+ QDomElement docElem = doc.documentElement();
+
+ QDomNode n = docElem.firstChild();
+ while( !n.isNull() ) {
+ QDomElement e = n.toElement(); // try to convert the node to an element.
+ if( !e.isNull() ) { // the node was really an element.
+ cout << e.tagName() << endl;
+ }
+ n = n.nextSibling();
+ }
+
+ // lets append a new element to the end of the document
+ QDomElement elem = doc.createElement( "img" );
+ elem.setAttribute( "src", "myimage.png" );
+ docElem.appendChild( elem );
+ \endcode
+
+ Once \c doc and \c elem go out of scode, the whole internal tree representing
+ the XML document will get deleted.
+
+ For further information about the Document Objct Model see
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1/">http://www.w3.org/TR/REC-DOM-Level-1/</a>.
+*/
+
+
+/*!
+ Constructs an empty document.
+*/
+QDomDocument::QDomDocument()
+{
+}
+
+/*!
+ Creates a document with the name \a name.
+*/
+QDomDocument::QDomDocument( const QString& name )
+{
+ // We take over ownership
+ impl = new QDOM_DocumentPrivate( name );
+}
+
+/*!
+ Copy constructor.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomDocument::QDomDocument( const QDomDocument& x )
+ : QDomNode( x )
+{
+}
+
+/*!
+ \internal
+*/
+QDomDocument::QDomDocument( QDOM_DocumentPrivate* x )
+ : QDomNode( x )
+{
+}
+
+/*!
+ Assignment operator.
+
+ The data of the copy is shared: modifying one will also change the other. If
+ you want to make a real copy, use cloneNode() instead.
+*/
+QDomDocument& QDomDocument::operator= ( const QDomDocument& x )
+{
+ return (QDomDocument&) QDomNode::operator=( x );
+}
+
+/*!
+ Destructor.
+*/
+QDomDocument::~QDomDocument()
+{
+}
+
+/*!
+ This function parses the string \a text and sets it as the content of the
+ document.
+*/
+bool QDomDocument::setContent( const QString& text )
+{
+ if ( !impl )
+ impl = new QDOM_DocumentPrivate;
+ QXmlInputSource source;
+ source.setData( text );
+ return IMPL->setContent( source );
+}
+
+/*!
+ \overload
+*/
+bool QDomDocument::setContent( const QByteArray& buffer )
+{
+ if ( !impl )
+ impl = new QDOM_DocumentPrivate;
+ QTextStream ts( buffer, IO_ReadOnly );
+ QXmlInputSource source( ts );
+ return IMPL->setContent( source );
+}
+
+/*!
+ \overload
+*/
+bool QDomDocument::setContent( const QCString& buffer )
+{
+ return setContent( QString::fromUtf8( buffer, buffer.length() ) );
+}
+
+/*!
+ \overload
+*/
+bool QDomDocument::setContent( QIODevice* dev )
+{
+ if ( !impl )
+ impl = new QDOM_DocumentPrivate;
+ QTextStream ts( dev );
+ QXmlInputSource source( ts );
+ return IMPL->setContent( source );
+}
+
+/*!
+ Converts the parsed document back to its textual representation.
+*/
+QString QDomDocument::toString() const
+{
+ QString str;
+ QTextStream s( str, IO_WriteOnly );
+ s << *this;
+
+ return str;
+}
+
+/*!
+ \fn QCString QDomDocument::toCString() const
+
+ Converts the parsed document back to its textual representation.
+*/
+
+
+/*!
+ Returns the document type of this document.
+*/
+QDomDocumentType QDomDocument::doctype() const
+{
+ if ( !impl )
+ return QDomDocumentType();
+ return QDomDocumentType( IMPL->doctype() );
+}
+
+/*!
+ Returns a QDomImplementation object.
+*/
+QDomImplementation QDomDocument::implementation() const
+{
+ if ( !impl )
+ return QDomImplementation();
+ return QDomImplementation( IMPL->implementation() );
+}
+
+/*!
+ Returns the root element of the document.
+*/
+QDomElement QDomDocument::documentElement() const
+{
+ if ( !impl )
+ return QDomElement();
+ return QDomElement( IMPL->documentElement() );
+}
+
+/*!
+ Creates a new element with the name \a tagName that can be inserted into the
+ DOM tree.
+*/
+QDomElement QDomDocument::createElement( const QString& tagName )
+{
+ if ( !impl )
+ return QDomElement();
+ return QDomElement( IMPL->createElement( tagName ) );
+}
+
+/*!
+ Creates a new document fragment, that can be used to hold parts
+ of the document, when doing complex manipulations of the document tree.
+*/
+QDomDocumentFragment QDomDocument::createDocumentFragment()
+{
+ if ( !impl )
+ return QDomDocumentFragment();
+ return QDomDocumentFragment( IMPL->createDocumentFragment() );
+}
+
+/*!
+ Creates a text node that can be inserted into the document tree.
+*/
+QDomText QDomDocument::createTextNode( const QString& value )
+{
+ if ( !impl )
+ return QDomText();
+ return QDomText( IMPL->createTextNode( value ) );
+}
+
+/*!
+ Creates a new comment that can be inserted into the Document.
+*/
+QDomComment QDomDocument::createComment( const QString& value )
+{
+ if ( !impl )
+ return QDomComment();
+ return QDomComment( IMPL->createComment( value ) );
+}
+
+/*!
+ Creates a new CDATA section that can be inserted into the document.
+*/
+QDomCDATASection QDomDocument::createCDATASection( const QString& value )
+{
+ if ( !impl )
+ return QDomCDATASection();
+ return QDomCDATASection( IMPL->createCDATASection( value ) );
+}
+
+/*!
+ Creates a new processing instruction that can be inserted into the document.
+*/
+QDomProcessingInstruction QDomDocument::createProcessingInstruction( const QString& target,
+ const QString& data )
+{
+ if ( !impl )
+ return QDomProcessingInstruction();
+ return QDomProcessingInstruction( IMPL->createProcessingInstruction( target, data ) );
+}
+
+
+/*!
+ Creates a new attribute that can be inserted into an element.
+*/
+QDomAttr QDomDocument::createAttribute( const QString& name )
+{
+ if ( !impl )
+ return QDomAttr();
+ return QDomAttr( IMPL->createAttribute( name ) );
+}
+
+/*!
+ Creates a new entity reference.
+*/
+QDomEntityReference QDomDocument::createEntityReference( const QString& name )
+{
+ if ( !impl )
+ return QDomEntityReference();
+ return QDomEntityReference( IMPL->createEntityReference( name ) );
+}
+
+/*!
+ Returns a QDomNodeList, that contains all elements in the document
+ with the tag name \a tagname. The order of the node list, is the
+ order they are encountered in a preorder traversal of the element tree.
+*/
+QDomNodeList QDomDocument::elementsByTagName( const QString& tagname ) const
+{
+ return QDomNodeList( new QDOM_NodeListPrivate( impl, tagname ) );
+}
+
+/*!
+ Returns \c DocumentNode.
+*/
+QDomNode::NodeType QDomDocument::nodeType() const
+{
+ return DocumentNode;
+}
+
+/*!
+ Returns TRUE.
+*/
+bool QDomDocument::isDocument() const
+{
+ return TRUE;
+}
+
+
+#undef IMPL
+
+/*==============================================================*/
+/* Node casting functions */
+/*==============================================================*/
+
+/*!
+ Converts a QDomNode into a QDomAttr. If the node is not an attribute,
+ the returned object will be null.
+
+ \sa isAttr()
+*/
+QDomAttr QDomNode::toAttr()
+{
+ if ( impl && impl->isAttr() )
+ return QDomAttr( ((QDOM_AttrPrivate*)impl) );
+ return QDomAttr();
+}
+
+/*!
+ Converts a QDomNode into a QDomCDATASection. If the node is not a CDATA
+ section, the returned object will be null.
+
+ \sa isCDATASection()
+*/
+QDomCDATASection QDomNode::toCDATASection()
+{
+ if ( impl && impl->isCDATASection() )
+ return QDomCDATASection( ((QDOM_CDATASectionPrivate*)impl) );
+ return QDomCDATASection();
+}
+
+/*!
+ Converts a QDomNode into a QDomDocumentFragment. If the node is not a
+ document fragment the returned object will be null.
+
+ \sa isDocumentFragment()
+*/
+QDomDocumentFragment QDomNode::toDocumentFragment()
+{
+ if ( impl && impl->isDocumentFragment() )
+ return QDomDocumentFragment( ((QDOM_DocumentFragmentPrivate*)impl) );
+ return QDomDocumentFragment();
+}
+
+/*!
+ Converts a QDomNode into a QDomDocument. If the node is not a document
+ the returned object will be null.
+
+ \sa isDocument()
+*/
+QDomDocument QDomNode::toDocument()
+{
+ if ( impl && impl->isDocument() )
+ return QDomDocument( ((QDOM_DocumentPrivate*)impl) );
+ return QDomDocument();
+}
+
+/*!
+ Converts a QDomNode into a QDomDocumentType. If the node is not a document
+ type the returned object will be null.
+
+ \sa isDocumentType()
+*/
+QDomDocumentType QDomNode::toDocumentType()
+{
+ if ( impl && impl->isDocumentType() )
+ return QDomDocumentType( ((QDOM_DocumentTypePrivate*)impl) );
+ return QDomDocumentType();
+}
+
+/*!
+ Converts a QDomNode into a QDomElement. If the node is not an element
+ the returned object will be null.
+
+ \sa isElement()
+*/
+QDomElement QDomNode::toElement()
+{
+ if ( impl && impl->isElement() )
+ return QDomElement( ((QDOM_ElementPrivate*)impl) );
+ return QDomElement();
+}
+
+/*!
+ Converts a QDomNode into a QDomEntityReference. If the node is not an entity
+ reference, the returned object will be null.
+
+ \sa isEntityReference()
+*/
+QDomEntityReference QDomNode::toEntityReference()
+{
+ if ( impl && impl->isEntityReference() )
+ return QDomEntityReference( ((QDOM_EntityReferencePrivate*)impl) );
+ return QDomEntityReference();
+}
+
+/*!
+ Converts a QDomNode into a QDomText. If the node is not a text, the returned
+ object will be null.
+
+ \sa isText()
+*/
+QDomText QDomNode::toText()
+{
+ if ( impl && impl->isText() )
+ return QDomText( ((QDOM_TextPrivate*)impl) );
+ return QDomText();
+}
+
+/*!
+ Converts a QDomNode into a QDomEntity. If the node is not an entity the
+ returned object will be null.
+
+ \sa isEntity()
+*/
+QDomEntity QDomNode::toEntity()
+{
+ if ( impl && impl->isEntity() )
+ return QDomEntity( ((QDOM_EntityPrivate*)impl) );
+ return QDomEntity();
+}
+
+/*!
+ Converts a QDomNode into a QDomNotation. If the node is not a notation
+ the returned object will be null.
+
+ \sa isNotation()
+*/
+QDomNotation QDomNode::toNotation()
+{
+ if ( impl && impl->isNotation() )
+ return QDomNotation( ((QDOM_NotationPrivate*)impl) );
+ return QDomNotation();
+}
+
+/*!
+ Converts a QDomNode into a QDomProcessingInstruction. If the node is not a
+ processing instruction the returned object will be null.
+
+ \sa isProcessingInstruction()
+*/
+QDomProcessingInstruction QDomNode::toProcessingInstruction()
+{
+ if ( impl && impl->isProcessingInstruction() )
+ return QDomProcessingInstruction( ((QDOM_ProcessingInstructionPrivate*)impl) );
+ return QDomProcessingInstruction();
+}
+
+/*!
+ Converts a QDomNode into a QDomCharacterData. If the node is not a character
+ data node the returned object will be null.
+
+ \sa isCharacterData()
+*/
+QDomCharacterData QDomNode::toCharacterData()
+{
+ if ( impl && impl->isCharacterData() )
+ return QDomCharacterData( ((QDOM_CharacterDataPrivate*)impl) );
+ return QDomCharacterData();
+}
+
+/*!
+ Converts a QDomNode into a QDomComment. If the node is not a comment the
+ returned object will be null.
+
+ \sa isComment()
+*/
+QDomComment QDomNode::toComment()
+{
+ if ( impl && impl->isComment() )
+ return QDomComment( ((QDOM_CommentPrivate*)impl) );
+ return QDomComment();
+}
+
+/*==============================================================*/
+/* QDomHandler */
+/*==============================================================*/
+
+QDomHandler::QDomHandler( QDOM_DocumentPrivate* adoc )
+{
+ doc = adoc;
+ node = doc;
+ cdata = FALSE;
+}
+
+QDomHandler::~QDomHandler()
+{
+}
+
+void QDomHandler::setDocumentLocator( QXmlLocator* locator )
+{
+ loc = locator;
+}
+
+bool QDomHandler::endDocument()
+{
+ // ### is this really necessary? (rms)
+ if ( node != doc )
+ return FALSE;
+ return TRUE;
+}
+
+bool QDomHandler::startDTD( const QString& name, const QString&, const QString&)
+{
+ doc->doctype()->name = name;
+ return TRUE;
+}
+
+bool QDomHandler::startElement( const QString&, const QString&, const QString& qName, const QXmlAttributes& atts )
+{
+ // tag name
+#if 0
+ // ### do we really need this?
+ if ( node == doc ) {
+ // Has to be a special tag
+ if ( qName != doc->doctype()->nodeName() ) {
+ // TODO: Exception
+ return FALSE;
+ }
+ }
+#endif
+ QDOM_NodePrivate* n = doc->createElement( qName );
+ node->appendChild( n );
+ node = n;
+
+ // attributes
+ for ( int i=0; i<atts.length(); i++ )
+ {
+ if ( !node->isElement() ) {
+ // TODO: Exception
+ return FALSE;
+ }
+ ((QDOM_ElementPrivate*)node)->setAttribute( atts.qName(i), atts.value(i) );
+ }
+
+ return TRUE;
+}
+
+bool QDomHandler::endElement( const QString&, const QString&, const QString& )
+{
+ if ( node == doc )
+ return FALSE;
+ node = node->parent;
+
+ return TRUE;
+}
+
+bool QDomHandler::characters( const QString& ch )
+{
+ // No text as child of some document
+ if ( node == doc )
+ return FALSE;
+
+ if ( cdata ) {
+ node->appendChild( doc->createCDATASection( ch ) );
+ } else {
+ node->appendChild( doc->createTextNode( ch ) );
+ }
+
+ return TRUE;
+}
+
+bool QDomHandler::processingInstruction( const QString& target, const QString& data )
+{
+ node->appendChild( doc->createProcessingInstruction( target, data ) );
+ return TRUE;
+}
+
+bool QDomHandler::fatalError( const QXmlParseException& exception )
+{
+ qDebug( "fatal parsing error: " + exception.message() + " in line %d",
+ exception.lineNumber() );
+ return QXmlDefaultHandler::fatalError( exception );
+}
+
+bool QDomHandler::startCDATA()
+{
+ cdata = TRUE;
+ return TRUE;
+}
+
+bool QDomHandler::endCDATA()
+{
+ cdata = FALSE;
+ return TRUE;
+}
+
+bool QDomHandler::comment( const QString& ch )
+{
+ node->appendChild( doc->createComment( ch ) );
+ return TRUE;
+}
+
+bool QDomHandler::unparsedEntityDecl( const QString &name, const QString &publicId, const QString &systemId, const QString &notationName )
+{
+ QDOM_EntityPrivate* e = new QDOM_EntityPrivate( doc, 0, name,
+ publicId, systemId, notationName );
+ doc->doctype()->appendChild( e );
+ return TRUE;
+}
+
+bool QDomHandler::externalEntityDecl( const QString &name, const QString &publicId, const QString &systemId )
+{
+ return unparsedEntityDecl( name, publicId, systemId, QString::null );
+}
+
+bool QDomHandler::notationDecl( const QString & name, const QString & publicId, const QString & systemId )
+{
+ QDOM_NotationPrivate* n = new QDOM_NotationPrivate( doc, 0, name, publicId, systemId );
+ doc->doctype()->appendChild( n );
+ return TRUE;
+}
+
+#if 0
+bool QDomConsumer::entity( const QString& name, const QString& value )
+{
+ QDOM_EntityPrivate* e = new QDOM_EntityPrivate( doc, 0, name, QString::null, QString::null, QString::null );
+ e->value = value;
+ doc->doctype()->appendChild( e );
+
+ return TRUE;
+}
+
+bool QDomConsumer::entityRef( const QString& name )
+{
+ if ( node == doc )
+ return FALSE;
+
+ // TODO: Find corresponding entity
+ QDOM_NamedNodeMapPrivate* m = doc->doctype()->entities;
+ if ( !m )
+ return FALSE;
+ QDOM_NodePrivate* n = m->namedItem( name );
+ if ( !n || !n->isEntity() ) {
+ qWarning( "Entity of name %s unsupported", name.latin1() );
+ return FALSE;
+ }
+
+ node->appendChild( doc->createEntityReference( name ) );
+
+ return TRUE;
+}
+#endif
+
+//US #endif //QT_NO_DOM
diff --git a/qtcompat/xml/qdom.h b/qtcompat/xml/qdom.h
new file mode 100644
index 0000000..eb257ea
--- a/dev/null
+++ b/qtcompat/xml/qdom.h
@@ -0,0 +1,611 @@
+/****************************************************************************
+** $Id$
+**
+** Definition of QDomDocument and related classes.
+**
+** Created : 000518
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the XML module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+/******************************************
+ * DOM support is disabled in QT 2.3.7 for sharp zaurus.
+ * Because of that we copied the code from 2.3.7 into qtcompat and enabled it
+ * there.
+ * Copyright (c) 2004 Ulf Schenk
+ *
+ * $Id$
+ ******************************************/
+
+#ifndef QDOM_H
+#define QDOM_H
+
+#ifndef QT_H
+#include <qstring.h>
+#include <qdict.h>
+#include <qrect.h>
+#include <qfont.h>
+#include <qpen.h>
+#include <qpoint.h>
+#include <qsize.h>
+#include <qvariant.h>
+#include <qmime.h>
+#endif // QT_H
+
+#include <qmodules.h>
+
+//US #if !defined(QT_MODULE_XML)
+//US #define QM_EXPORT
+//US #else
+#define QM_EXPORT Q_EXPORT
+//US #endif
+
+//US #ifndef QT_NO_DOM
+class QWidget;
+class QLayout;
+class QIODevice;
+class QTextStream;
+
+class QDOM_DocumentPrivate;
+class QDOM_DocumentTypePrivate;
+class QDOM_DocumentFragmentPrivate;
+class QDOM_NodePrivate;
+class QDOM_NodeListPrivate;
+class QDOM_ImplementationPrivate;
+class QDOM_ElementPrivate;
+class QDOM_NotationPrivate;
+class QDOM_EntityPrivate;
+class QDOM_EntityReferencePrivate;
+class QDOM_ProcessingInstructionPrivate;
+class QDOM_AttrPrivate;
+class QDOM_CharacterDataPrivate;
+class QDOM_TextPrivate;
+class QDOM_CommentPrivate;
+class QDOM_CDATASectionPrivate;
+class QDOM_NamedNodeMapPrivate;
+class QDOM_ImplementationPrivate;
+
+class QDomNodeList;
+class QDomElement;
+class QDomText;
+class QDomComment;
+class QDomCDATASection;
+class QDomProcessingInstruction;
+class QDomAttr;
+class QDomEntityReference;
+class QDomDocument;
+class QDomNamedNodeMap;
+class QDomDocument;
+class QDomDocumentFragment;
+class QDomDocumentType;
+class QDomImplementation;
+class QDomNode;
+class QDomEntity;
+class QDomNotation;
+class QDomCharacterData;
+
+class QM_EXPORT QDomImplementation
+{
+public:
+ QDomImplementation();
+ QDomImplementation( const QDomImplementation& );
+ virtual ~QDomImplementation();
+ QDomImplementation& operator= ( const QDomImplementation& );
+ bool operator== ( const QDomImplementation& ) const;
+ bool operator!= ( const QDomImplementation& ) const;
+
+ virtual bool hasFeature( const QString& feature, const QString& version );
+
+ bool isNull();
+
+private:
+ QDomImplementation( QDOM_ImplementationPrivate* );
+
+ QDOM_ImplementationPrivate* impl;
+
+ friend class QDomDocument;
+};
+
+class QM_EXPORT QDomNode // Ok
+{
+public:
+ enum NodeType {
+ BaseNode = 0,
+ ElementNode = 1,
+ AttributeNode = 2,
+ TextNode = 3,
+ CDATASectionNode = 4,
+ EntityReferenceNode = 5,
+ EntityNode = 6,
+ ProcessingInstructionNode = 7,
+ CommentNode = 8,
+ DocumentNode = 9,
+ DocumentTypeNode = 10,
+ DocumentFragmentNode = 11,
+ NotationNode = 12,
+ CharacterDataNode = 13
+ };
+
+ QDomNode();
+ QDomNode( const QDomNode& );
+ QDomNode& operator= ( const QDomNode& );
+ bool operator== ( const QDomNode& ) const;
+ bool operator!= ( const QDomNode& ) const;
+ virtual ~QDomNode();
+
+ virtual QString nodeName() const;
+ virtual QString nodeValue() const;
+ virtual void setNodeValue( const QString& );
+ virtual QDomNode::NodeType nodeType() const;
+
+ virtual QDomNode parentNode() const;
+ virtual QDomNodeList childNodes() const;
+ virtual QDomNode firstChild() const;
+ virtual QDomNode lastChild() const;
+ virtual QDomNode previousSibling() const;
+ virtual QDomNode nextSibling() const;
+ virtual QDomNamedNodeMap attributes() const;
+ virtual QDomDocument ownerDocument() const;
+
+ virtual QDomNode insertBefore( const QDomNode& newChild, const QDomNode& refChild );
+ virtual QDomNode insertAfter( const QDomNode& newChild, const QDomNode& refChild );
+ virtual QDomNode replaceChild( const QDomNode& newChild, const QDomNode& oldChild );
+ virtual QDomNode removeChild( const QDomNode& oldChild );
+ virtual QDomNode appendChild( const QDomNode& newChild );
+ virtual QDomNode cloneNode( bool deep = TRUE ) const;
+
+ // Qt extension
+ virtual bool isAttr() const;
+ virtual bool isCDATASection() const;
+ virtual bool isDocumentFragment() const;
+ virtual bool isDocument() const;
+ virtual bool isDocumentType() const;
+ virtual bool isElement() const;
+ virtual bool isEntityReference() const;
+ virtual bool isText() const;
+ virtual bool isEntity() const;
+ virtual bool isNotation() const;
+ virtual bool isProcessingInstruction() const;
+ virtual bool isCharacterData() const;
+ virtual bool isComment() const;
+
+ /**
+ * Shortcut to avoid dealing with QDomNodeList
+ * all the time.
+ */
+ QDomNode namedItem( const QString& name ) const;
+
+ bool isNull() const;
+ void clear();
+
+ QDomAttr toAttr();
+ QDomCDATASection toCDATASection();
+ QDomDocumentFragment toDocumentFragment();
+ QDomDocument toDocument();
+ QDomDocumentType toDocumentType();
+ QDomElement toElement();
+ QDomEntityReference toEntityReference();
+ QDomText toText();
+ QDomEntity toEntity();
+ QDomNotation toNotation();
+ QDomProcessingInstruction toProcessingInstruction();
+ QDomCharacterData toCharacterData();
+ QDomComment toComment();
+
+ void save( QTextStream&, int ) const;
+
+protected:
+ QDOM_NodePrivate* impl;
+ QDomNode( QDOM_NodePrivate* );
+
+private:
+ friend class QDomDocument;
+ friend class QDomDocumentType;
+ friend class QDomNodeList;
+ friend class QDomNamedNodeMap;
+};
+
+class QM_EXPORT QDomNodeList // Ok
+{
+public:
+ QDomNodeList();
+ QDomNodeList( const QDomNodeList& );
+ QDomNodeList& operator= ( const QDomNodeList& );
+ bool operator== ( const QDomNodeList& ) const;
+ bool operator!= ( const QDomNodeList& ) const;
+ virtual ~QDomNodeList();
+
+ virtual QDomNode item( int index ) const;
+ virtual uint length() const;
+ uint count() const { return length(); } // Qt API consitancy
+
+ QDomNodeList( QDOM_NodeListPrivate* );
+private:
+ QDOM_NodeListPrivate* impl;
+};
+
+class QM_EXPORT QDomDocumentType : public QDomNode
+{
+public:
+ QDomDocumentType();
+ QDomDocumentType( const QDomDocumentType& x );
+ QDomDocumentType& operator= ( const QDomDocumentType& );
+ ~QDomDocumentType();
+
+ virtual QString name() const;
+ virtual QDomNamedNodeMap entities() const;
+ virtual QDomNamedNodeMap notations() const;
+
+ // Reimplemented from QDomNode
+ QDomNode::NodeType nodeType() const;
+ bool isDocumentType() const;
+
+private:
+ QDomDocumentType( QDOM_DocumentTypePrivate* );
+
+ friend class QDomDocument;
+ friend class QDomNode;
+};
+
+class QM_EXPORT QDomDocument : public QDomNode
+{
+public:
+ QDomDocument();
+ QDomDocument( const QString& name );
+ QDomDocument( const QDomDocument& x );
+ QDomDocument& operator= ( const QDomDocument& );
+ ~QDomDocument();
+
+ // Qt extensions
+ bool setContent( const QCString& text );
+ bool setContent( const QByteArray& text );
+ bool setContent( const QString& text );
+ bool setContent( QIODevice* dev );
+
+ // QDomAttributes
+ QDomDocumentType doctype() const;
+ QDomImplementation implementation() const;
+ QDomElement documentElement() const;
+
+ // Factories
+ QDomElement createElement( const QString& tagName );
+ QDomDocumentFragment createDocumentFragment();
+ QDomText createTextNode( const QString& data );
+ QDomComment createComment( const QString& data );
+ QDomCDATASection createCDATASection( const QString& data );
+ QDomProcessingInstruction createProcessingInstruction( const QString& target, const QString& data );
+ QDomAttr createAttribute( const QString& name );
+ QDomEntityReference createEntityReference( const QString& name );
+ QDomNodeList elementsByTagName( const QString& tagname ) const;
+
+ // Reimplemented from QDomNode
+ QDomNode::NodeType nodeType() const;
+ bool isDocument() const;
+
+ // Qt extensions
+ QString toString() const;
+ QCString toCString() const { return toString().utf8(); }
+
+private:
+ QDomDocument( QDOM_DocumentPrivate* );
+
+ friend class QDomNode;
+};
+
+class QM_EXPORT QDomNamedNodeMap
+{
+public:
+ QDomNamedNodeMap();
+ QDomNamedNodeMap( const QDomNamedNodeMap& );
+ QDomNamedNodeMap& operator= ( const QDomNamedNodeMap& );
+ bool operator== ( const QDomNamedNodeMap& ) const;
+ bool operator!= ( const QDomNamedNodeMap& ) const;
+ ~QDomNamedNodeMap();
+
+ QDomNode namedItem( const QString& name ) const;
+ QDomNode setNamedItem( const QDomNode& arg );
+ QDomNode removeNamedItem( const QString& name );
+ QDomNode item( int index ) const;
+ uint length() const;
+ bool contains( const QString& name ) const;
+
+private:
+ friend class QDomNode;
+ friend class QDomDocumentType;
+ friend class QDomElement;
+
+ QDomNamedNodeMap( QDOM_NamedNodeMapPrivate* );
+
+ QDOM_NamedNodeMapPrivate* impl;
+};
+
+class QM_EXPORT QDomDocumentFragment : public QDomNode
+{
+public:
+ QDomDocumentFragment();
+ QDomDocumentFragment( const QDomDocumentFragment& x );
+ QDomDocumentFragment& operator= ( const QDomDocumentFragment& );
+ ~QDomDocumentFragment();
+
+ // Reimplemented from QDomNode
+ QDomNode::NodeType nodeType() const;
+ bool isDocumentFragment() const;
+
+private:
+ QDomDocumentFragment( QDOM_DocumentFragmentPrivate* );
+
+ friend class QDomDocument;
+ friend class QDomNode;
+};
+
+class QM_EXPORT QDomCharacterData : public QDomNode
+{
+public:
+ QDomCharacterData();
+ QDomCharacterData( const QDomCharacterData& x );
+ QDomCharacterData& operator= ( const QDomCharacterData& );
+ ~QDomCharacterData();
+
+ virtual QString data() const;
+ virtual void setData( const QString& );
+ virtual uint length() const;
+
+ virtual QString substringData( unsigned long offset, unsigned long count );
+ virtual void appendData( const QString& arg );
+ virtual void insertData( unsigned long offset, const QString& arg );
+ virtual void deleteData( unsigned long offset, unsigned long count );
+ virtual void replaceData( unsigned long offset, unsigned long count, const QString& arg );
+
+ // Reimplemented from QDomNode
+ QDomNode::NodeType nodeType() const;
+ bool isCharacterData() const;
+
+private:
+ QDomCharacterData( QDOM_CharacterDataPrivate* );
+
+ friend class QDomDocument;
+ friend class QDomText;
+ friend class QDomComment;
+ friend class QDomNode;
+};
+
+class QM_EXPORT QDomAttr : public QDomNode
+{
+public:
+ QDomAttr();
+ QDomAttr( const QDomAttr& x );
+ QDomAttr& operator= ( const QDomAttr& );
+ ~QDomAttr();
+
+ virtual QString name() const;
+ virtual bool specified() const;
+ virtual QString value() const;
+ virtual void setValue( const QString& );
+
+ // Reimplemented from QDomNode
+ QDomNode::NodeType nodeType() const;
+ bool isAttr() const;
+
+private:
+ QDomAttr( QDOM_AttrPrivate* );
+
+ friend class QDomDocument;
+ friend class QDomElement;
+ friend class QDomNode;
+};
+
+class QM_EXPORT QDomElement : public QDomNode
+{
+public:
+ QDomElement();
+ QDomElement( const QDomElement& x );
+ QDomElement& operator= ( const QDomElement& );
+ ~QDomElement();
+
+ void setTagName( const QString& name );
+ QString tagName() const;
+ QString attribute( const QString& name, const QString& defValue = QString::null ) const;
+ void setAttribute( const QString& name, const QString& value );
+ void setAttribute( const QString& name, int value );
+ void setAttribute( const QString& name, uint value );
+ void setAttribute( const QString& name, double value );
+ void removeAttribute( const QString& name );
+ QDomAttr attributeNode( const QString& name);
+ QDomAttr setAttributeNode( const QDomAttr& newAttr );
+ QDomAttr removeAttributeNode( const QDomAttr& oldAttr );
+ bool hasAttribute( const QString& name ) const;
+ virtual QDomNodeList elementsByTagName( const QString& tagname ) const;
+ void normalize();
+
+ // Reimplemented from QDomNode
+ QDomNamedNodeMap attributes() const;
+ QDomNode::NodeType nodeType() const;
+ bool isElement() const;
+
+ QString text() const;
+
+private:
+ QDomElement( QDOM_ElementPrivate* );
+
+ friend class QDomDocument;
+ friend class QDomNode;
+};
+
+class QM_EXPORT QDomText : public QDomCharacterData
+{
+public:
+ QDomText();
+ QDomText( const QDomText& x );
+ QDomText& operator= ( const QDomText& );
+ ~QDomText();
+
+ QDomText splitText( int offset );
+
+ // Reimplemented from QDomNode
+ QDomNode::NodeType nodeType() const;
+ bool isText() const;
+
+private:
+ QDomText( QDOM_TextPrivate* );
+
+ friend class QDomCDATASection;
+ friend class QDomDocument;
+ friend class QDomNode;
+};
+
+class QM_EXPORT QDomComment : public QDomCharacterData
+{
+public:
+ QDomComment();
+ QDomComment( const QDomComment& x );
+ QDomComment& operator= ( const QDomComment& );
+ ~QDomComment();
+
+ // Reimplemented from QDomNode
+ QDomNode::NodeType nodeType() const;
+ bool isComment() const;
+
+private:
+ QDomComment( QDOM_CommentPrivate* );
+
+ friend class QDomDocument;
+ friend class QDomNode;
+};
+
+class QM_EXPORT QDomCDATASection : public QDomText
+{
+public:
+ QDomCDATASection();
+ QDomCDATASection( const QDomCDATASection& x );
+ QDomCDATASection& operator= ( const QDomCDATASection& );
+ ~QDomCDATASection();
+
+ // Reimplemented from QDomNode
+ QDomNode::NodeType nodeType() const;
+ bool isCDATASection() const;
+
+private:
+ QDomCDATASection( QDOM_CDATASectionPrivate* );
+
+ friend class QDomDocument;
+ friend class QDomNode;
+};
+
+class QM_EXPORT QDomNotation : public QDomNode
+{
+public:
+ QDomNotation();
+ QDomNotation( const QDomNotation& x );
+ QDomNotation& operator= ( const QDomNotation& );
+ ~QDomNotation();
+
+ QString publicId() const;
+ QString systemId() const;
+
+ // Reimplemented from QDomNode
+ QDomNode::NodeType nodeType() const;
+ bool isNotation() const;
+
+private:
+ QDomNotation( QDOM_NotationPrivate* );
+
+ friend class QDomDocument;
+ friend class QDomNode;
+};
+
+class QM_EXPORT QDomEntity : public QDomNode
+{
+public:
+ QDomEntity();
+ QDomEntity( const QDomEntity& x );
+ QDomEntity& operator= ( const QDomEntity& );
+ ~QDomEntity();
+
+ virtual QString publicId() const;
+ virtual QString systemId() const;
+ virtual QString notationName() const;
+
+ // Reimplemented from QDomNode
+ QDomNode::NodeType nodeType() const;
+ bool isEntity() const;
+
+private:
+ QDomEntity( QDOM_EntityPrivate* );
+
+ friend class QDomNode;
+};
+
+class QM_EXPORT QDomEntityReference : public QDomNode
+{
+public:
+ QDomEntityReference();
+ QDomEntityReference( const QDomEntityReference& x );
+ QDomEntityReference& operator= ( const QDomEntityReference& );
+ ~QDomEntityReference();
+
+ // Reimplemented from QDomNode
+ QDomNode::NodeType nodeType() const;
+ bool isEntityReference() const;
+
+private:
+ QDomEntityReference( QDOM_EntityReferencePrivate* );
+
+ friend class QDomDocument;
+ friend class QDomNode;
+};
+
+class QM_EXPORT QDomProcessingInstruction : public QDomNode
+{
+public:
+ QDomProcessingInstruction();
+ QDomProcessingInstruction( const QDomProcessingInstruction& x );
+ QDomProcessingInstruction& operator= ( const QDomProcessingInstruction& );
+ ~QDomProcessingInstruction();
+
+ virtual QString target() const;
+ virtual QString data() const;
+ virtual void setData( const QString& d );
+
+ // Reimplemented from QDomNode
+ QDomNode::NodeType nodeType() const;
+ bool isProcessingInstruction() const;
+
+private:
+ QDomProcessingInstruction( QDOM_ProcessingInstructionPrivate* );
+
+ friend class QDomDocument;
+ friend class QDomNode;
+};
+
+
+QM_EXPORT QTextStream& operator<<( QTextStream&, const QDomNode& );
+
+//US #endif //QT_NO_DOM
+#endif // QDOM_H
diff --git a/qtcompat/xml/qxml.cpp b/qtcompat/xml/qxml.cpp
new file mode 100644
index 0000000..e65bc59
--- a/dev/null
+++ b/qtcompat/xml/qxml.cpp
@@ -0,0 +1,6087 @@
+/****************************************************************************
+** $Id$
+**
+** Implementation of QXmlSimpleReader and related classes.
+**
+** Created : 000518
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the XML module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+/******************************************
+ * DOM support is disabled in QT 2.3.7 for sharp zaurus.
+ * Because of that we copied the code from 2.3.7 into qtcompat and enabled it
+ * there.
+ * Copyright (c) 2004 Ulf Schenk
+ *
+ * $Id$
+ ******************************************/
+
+#define QT_XML_CPP
+#include "qxml.h"
+#include "qtextcodec.h"
+#include "qbuffer.h"
+
+//US #ifndef QT_NO_XML
+// NOT REVISED
+
+// Error strings for the XML reader
+#define XMLERR_OK "no error occured"
+#define XMLERR_TAGMISMATCH "tag mismatch"
+#define XMLERR_UNEXPECTEDEOF "unexpected end of file"
+#define XMLERR_FINISHEDPARSINGWHILENOTEOF "parsing is finished but end of file is not reached"
+#define XMLERR_LETTEREXPECTED "letter is expected"
+#define XMLERR_ERRORPARSINGELEMENT "error while parsing element"
+#define XMLERR_ERRORPARSINGPROLOG "error while parsing prolog"
+#define XMLERR_ERRORPARSINGMAINELEMENT "error while parsing main element"
+#define XMLERR_ERRORPARSINGCONTENT "error while parsing content"
+#define XMLERR_ERRORPARSINGNAME "error while parsing name"
+#define XMLERR_ERRORPARSINGNMTOKEN "error while parsing Nmtoken"
+#define XMLERR_ERRORPARSINGATTRIBUTE "error while parsing attribute"
+#define XMLERR_ERRORPARSINGMISC "error while parsing misc"
+#define XMLERR_ERRORPARSINGCHOICE "error while parsing choice or seq"
+#define XMLERR_ERRORBYCONSUMER "error triggered by consumer"
+#define XMLERR_UNEXPECTEDCHARACTER "unexpected character"
+#define XMLERR_EQUALSIGNEXPECTED "expected '=' but not found"
+#define XMLERR_QUOTATIONEXPECTED "expected \" or ' but not found"
+#define XMLERR_ERRORPARSINGREFERENCE "error while parsing reference"
+#define XMLERR_ERRORPARSINGPI "error while parsing processing instruction"
+#define XMLERR_ERRORPARSINGATTLISTDECL "error while parsing attribute list declaration"
+#define XMLERR_ERRORPARSINGATTTYPE "error while parsing attribute type declaration"
+#define XMLERR_ERRORPARSINGATTVALUE "error while parsing attribute value declaration"
+#define XMLERR_ERRORPARSINGELEMENTDECL "error while parsing element declaration"
+#define XMLERR_ERRORPARSINGENTITYDECL "error while parsing entity declaration"
+#define XMLERR_ERRORPARSINGNOTATIONDECL "error while parsing notation declaration"
+#define XMLERR_ERRORPARSINGEXTERNALID "error while parsing external id"
+#define XMLERR_ERRORPARSINGCOMMENT "error while parsing comment"
+#define XMLERR_ERRORPARSINGENTITYVALUE "error while parsing entity value declaration"
+#define XMLERR_CDSECTHEADEREXPECTED "expected the header for a cdata section"
+#define XMLERR_MORETHANONEDOCTYPE "more than one document type definition"
+#define XMLERR_ERRORPARSINGDOCTYPE "error while parsing document type definition"
+#define XMLERR_INVALIDNAMEFORPI "invalid name for processing instruction"
+#define XMLERR_VERSIONEXPECTED "version expected while reading the XML declaration"
+#define XMLERR_EDECLORSDDECLEXPECTED "EDecl or SDDecl expected while reading the XML declaration"
+#define XMLERR_SDDECLEXPECTED "SDDecl expected while reading the XML declaration"
+#define XMLERR_WRONGVALUEFORSDECL "wrong value for standalone declaration"
+#define XMLERR_UNPARSEDENTITYREFERENCE "unparsed entity reference in wrong context"
+#define XMLERR_INTERNALGENERALENTITYINDTD "internal general entity reference not allowed in DTD"
+#define XMLERR_EXTERNALGENERALENTITYINDTD "external parsed general entity reference not allowed in DTD"
+#define XMLERR_EXTERNALGENERALENTITYINAV "external parsed general entity reference not allowed in attribute value"
+
+
+// the constants for the lookup table
+static const signed char cltWS = 0; // white space
+static const signed char cltPer = 1; // %
+static const signed char cltAmp = 2; // &
+static const signed char cltGt = 3; // >
+static const signed char cltLt = 4; // <
+static const signed char cltSlash = 5; // /
+static const signed char cltQm = 6; // ?
+static const signed char cltEm = 7; // !
+static const signed char cltDash = 8; // -
+static const signed char cltCB = 9; // ]
+static const signed char cltOB = 10; // [
+static const signed char cltEq = 11; // =
+static const signed char cltDq = 12; // "
+static const signed char cltSq = 13; // '
+static const signed char cltUnknown = 14;
+
+// character lookup table
+static const signed char charLookupTable[256]={
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x00 - 0x07
+ cltUnknown, // 0x08
+ cltWS, // 0x09 \t
+ cltWS, // 0x0A \n
+ cltUnknown, // 0x0B
+ cltUnknown, // 0x0C
+ cltWS, // 0x0D \r
+ cltUnknown, // 0x0E
+ cltUnknown, // 0x0F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x17 - 0x16
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x18 - 0x1F
+ cltWS, // 0x20 Space
+ cltEm, // 0x21 !
+ cltDq, // 0x22 "
+ cltUnknown, // 0x23
+ cltUnknown, // 0x24
+ cltPer, // 0x25 %
+ cltAmp, // 0x26 &
+ cltSq, // 0x27 '
+ cltUnknown, // 0x28
+ cltUnknown, // 0x29
+ cltUnknown, // 0x2A
+ cltUnknown, // 0x2B
+ cltUnknown, // 0x2C
+ cltDash, // 0x2D -
+ cltUnknown, // 0x2E
+ cltSlash, // 0x2F /
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x30 - 0x37
+ cltUnknown, // 0x38
+ cltUnknown, // 0x39
+ cltUnknown, // 0x3A
+ cltUnknown, // 0x3B
+ cltLt, // 0x3C <
+ cltEq, // 0x3D =
+ cltGt, // 0x3E >
+ cltQm, // 0x3F ?
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x40 - 0x47
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x48 - 0x4F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x50 - 0x57
+ cltUnknown, // 0x58
+ cltUnknown, // 0x59
+ cltUnknown, // 0x5A
+ cltOB, // 0x5B [
+ cltUnknown, // 0x5C
+ cltCB, // 0x5D ]
+ cltUnknown, // 0x5E
+ cltUnknown, // 0x5F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x60 - 0x67
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x68 - 0x6F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x70 - 0x77
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x78 - 0x7F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x80 - 0x87
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x88 - 0x8F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x90 - 0x97
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x98 - 0x9F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA0 - 0xA7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA8 - 0xAF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB0 - 0xB7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB8 - 0xBF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC0 - 0xC7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC8 - 0xCF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD0 - 0xD7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD8 - 0xDF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE0 - 0xE7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE8 - 0xEF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xF0 - 0xF7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown // 0xF8 - 0xFF
+};
+
+
+class QXmlNamespaceSupportPrivate
+{
+};
+class QXmlAttributesPrivate
+{
+};
+class QXmlInputSourcePrivate
+{
+};
+class QXmlParseExceptionPrivate
+{
+};
+class QXmlLocatorPrivate
+{
+};
+class QXmlDefaultHandlerPrivate
+{
+};
+
+#if defined(Q_FULL_TEMPLATE_INSTANTIATION)
+bool operator==( const QMap<QString, QString>, const QMap<QString, QString> )
+{
+ return FALSE;
+}
+#endif
+
+/*!
+ \class QXmlParseException qxml.h
+ \brief The QXmlParseException class is used to report errors with the
+ QXmlErrorHandler interface.
+
+ \module XML
+
+ \sa QXmlErrorHandler
+*/
+/*!
+ \fn QXmlParseException::QXmlParseException( const QString& name, int c, int l, const QString& p, const QString& s )
+
+ Constructs a parse exception with the error string \a name in the column
+ \a c and line \a l for the public identifier \a p and the system identifier
+ \a s.
+*/
+/*!
+ Returns the error message.
+*/
+QString QXmlParseException::message() const
+{
+ return msg;
+}
+/*!
+ Returns the column number the error occured.
+*/
+int QXmlParseException::columnNumber() const
+{
+ return column;
+}
+/*!
+ Returns the line number the error occured.
+*/
+int QXmlParseException::lineNumber() const
+{
+ return line;
+}
+/*!
+ Returns the public identifier the error occured.
+*/
+QString QXmlParseException::publicId() const
+{
+ return pub;
+}
+/*!
+ Returns the system identifier the error occured.
+*/
+QString QXmlParseException::systemId() const
+{
+ return sys;
+}
+
+
+/*!
+ \class QXmlLocator qxml.h
+ \brief The QXmlLocator class provides the XML handler classes with
+ information about the actual parsing position.
+
+ \module XML
+
+ The reader reports a QXmlLocator to the content handler before he starts to
+ parse the document. This is done with the
+ QXmlContentHandler::setDocumentLocator() function. The handler classes can
+ now use this locator to get the actual position the reader is at.
+*/
+/*!
+ \fn QXmlLocator::QXmlLocator( QXmlSimpleReader* parent )
+
+ Constructor.
+*/
+/*!
+ \fn QXmlLocator::~QXmlLocator()
+
+ Destructor.
+*/
+/*!
+ Gets the column number (starting with 1) or -1 if there is no column number
+ available.
+*/
+int QXmlLocator::columnNumber()
+{
+ return ( reader->columnNr == -1 ? -1 : reader->columnNr + 1 );
+}
+/*!
+ Gets the line number (starting with 1) or -1 if there is no line number
+ available.
+*/
+int QXmlLocator::lineNumber()
+{
+ return ( reader->lineNr == -1 ? -1 : reader->lineNr + 1 );
+}
+
+
+/*********************************************
+ *
+ * QXmlNamespaceSupport
+ *
+ *********************************************/
+
+/*!
+ \class QXmlNamespaceSupport qxml.h
+ \brief The QXmlNamespaceSupport class is a helper class for XML readers which
+ want to include namespace support.
+
+ \module XML
+
+ It provides some functions that makes it easy to handle namespaces. Its main
+ use is for subclasses of QXmlReader which want to provide namespace
+ support.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+
+/*!
+ Constructs a QXmlNamespaceSupport.
+*/
+QXmlNamespaceSupport::QXmlNamespaceSupport()
+{
+ reset();
+}
+
+/*!
+ Destructs a QXmlNamespaceSupport.
+*/
+QXmlNamespaceSupport::~QXmlNamespaceSupport()
+{
+}
+
+/*!
+ This function declares a prefix in the current namespace context; the prefix
+ will remain in force until this context is popped, unless it is shadowed in a
+ descendant context.
+
+ Note that there is an asymmetry in this library: while prefix() will not
+ return the default "" prefix, even if you have declared one; to check for a
+ default prefix, you have to look it up explicitly using uri(). This
+ asymmetry exists to make it easier to look up prefixes for attribute names,
+ where the default prefix is not allowed.
+*/
+void QXmlNamespaceSupport::setPrefix( const QString& pre, const QString& uri )
+{
+ if( pre.isNull() ) {
+ ns.insert( "", uri );
+ } else {
+ ns.insert( pre, uri );
+ }
+}
+
+/*!
+ Returns one of the prefixes mapped to a namespace URI.
+
+ If more than one prefix is currently mapped to the same URI, this function
+ will make an arbitrary selection; if you want all of the prefixes, use the
+ prefixes() function instead.
+
+ Note: this will never return the empty (default) prefix; to check for a
+ default prefix, use the uri() function with an argument of "".
+*/
+QString QXmlNamespaceSupport::prefix( const QString& uri ) const
+{
+ QMap<QString, QString>::ConstIterator itc, it = ns.begin();
+ while ( (itc=it) != ns.end() ) {
+ ++it;
+ if ( itc.data() == uri && !itc.key().isEmpty() )
+ return itc.key();
+ }
+ return "";
+}
+
+/*!
+ Looks up a prefix in the current context and returns the currently-mapped
+ namespace URI. Use the empty string ("") for the default namespace.
+*/
+QString QXmlNamespaceSupport::uri( const QString& prefix ) const
+{
+ const QString& returi = ns[ prefix ];
+ return returi;
+}
+
+/*!
+ Splits the name at the ':' and returns the prefix and the local name.
+*/
+void QXmlNamespaceSupport::splitName( const QString& qname,
+ QString& prefix, QString& localname ) const
+{
+ uint pos;
+ // search the ':'
+ for( pos=0; pos<qname.length(); pos++ ) {
+ if ( qname.at(pos) == ':' )
+ break;
+ }
+ // and split
+ prefix = qname.left( pos );
+ localname = qname.mid( pos+1 );
+}
+
+/*!
+ Processes a raw XML 1.0 name in the current context by removing the prefix
+ and looking it up among the prefixes currently declared.
+
+ First parameter is the raw XML 1.0 name to be processed. The second parameter
+ is a flag wheter the name is the name of an attribute (TRUE) or not (FALSE).
+
+ The return values will be stored in the last two parameters as follows:
+ <ul>
+ <li> The namespace URI, or an empty string if none is in use.
+ <li> The local name (without prefix).
+ </ul>
+
+ If the raw name has a prefix that has not been declared, then the return
+ value will be empty.
+
+ Note that attribute names are processed differently than element names: an
+ unprefixed element name will received the default namespace (if any), while
+ an unprefixed element name will not
+*/
+void QXmlNamespaceSupport::processName( const QString& qname,
+ bool isAttribute,
+ QString& nsuri, QString& localname ) const
+{
+ uint pos;
+ // search the ':'
+ for( pos=0; pos<qname.length(); pos++ ) {
+ if ( qname.at(pos) == ':' )
+ break;
+ }
+ if ( pos < qname.length() ) {
+ // there was a ':'
+ nsuri = uri( qname.left( pos ) );
+ localname = qname.mid( pos+1 );
+ } else {
+ // there was no ':'
+ if ( isAttribute ) {
+ nsuri = ""; // attributes don't take default namespace
+ } else {
+ nsuri = uri( "" ); // get default namespace
+ }
+ localname = qname;
+ }
+}
+
+/*!
+ Returns an enumeration of all prefixes currently declared.
+
+ Note: if there is a default prefix, it will not be returned in this
+ enumeration; check for the default prefix using uri() with an argument
+ of "".
+*/
+QStringList QXmlNamespaceSupport::prefixes() const
+{
+ QStringList list;
+
+ QMap<QString, QString>::ConstIterator itc, it = ns.begin();
+ while ( (itc=it) != ns.end() ) {
+ ++it;
+ if ( !itc.key().isEmpty() )
+ list.append( itc.key() );
+ }
+ return list;
+}
+
+/*!
+ Returns a list of all prefixes currently declared for a URI.
+
+ The xml: prefix will be included. If you want only one prefix that's
+ mapped to the namespace URI, and you don't care which one you get, use the
+ prefix() function instead.
+
+ Note: the empty (default) prefix is never included in this enumeration; to
+ check for the presence of a default namespace, use uri() with an
+ argument of "".
+*/
+QStringList QXmlNamespaceSupport::prefixes( const QString& uri ) const
+{
+ QStringList list;
+
+ QMap<QString, QString>::ConstIterator itc, it = ns.begin();
+ while ( (itc=it) != ns.end() ) {
+ ++it;
+ if ( itc.data() == uri && !itc.key().isEmpty() )
+ list.append( itc.key() );
+ }
+ return list;
+}
+
+/*!
+ Starts a new namespace context.
+
+ Normally, you should push a new context at the beginning of each XML element:
+ the new context will automatically inherit the declarations of its parent
+ context, but it will also keep track of which declarations were made within
+ this context.
+*/
+void QXmlNamespaceSupport::pushContext()
+{
+ nsStack.push( ns );
+}
+
+/*!
+ Reverts to the previous namespace context.
+
+ Normally, you should pop the context at the end of each XML element. After
+ popping the context, all namespace prefix mappings that were previously in
+ force are restored.
+*/
+void QXmlNamespaceSupport::popContext()
+{
+ if( !nsStack.isEmpty() )
+ ns = nsStack.pop();
+}
+
+/*!
+ Resets this namespace support object for reuse.
+*/
+void QXmlNamespaceSupport::reset()
+{
+ nsStack.clear();
+ ns.clear();
+ ns.insert( "xml", "http://www.w3.org/XML/1998/namespace" ); // the XML namespace
+}
+
+
+
+/*********************************************
+ *
+ * QXmlAttributes
+ *
+ *********************************************/
+
+/*!
+ \class QXmlAttributes qxml.h
+ \brief The QXmlAttributes class provides XML attributes.
+
+ \module XML
+
+ If attributes are reported by QXmlContentHandler::startElement() this
+ class is used to pass the attribute values. It provides you with different
+ functions to access the attribute names and values.
+*/
+/*!
+ \fn QXmlAttributes::QXmlAttributes()
+
+ Constructs an empty attribute list.
+*/
+/*!
+ \fn QXmlAttributes::~QXmlAttributes()
+
+ Destructs attributes.
+*/
+
+/*!
+ Look up the index of an attribute by an XML 1.0 qualified name.
+
+ Returns the index of the attribute (starting with 0) or -1 if it wasn't
+ found.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+int QXmlAttributes::index( const QString& qName ) const
+{
+ return qnameList.findIndex( qName );
+}
+
+/*!
+ Looks up the index of an attribute by a namespace name.
+
+ \a uri specifies the namespace URI, or the empty string if the name has no
+ namespace URI. \a localPart specifies the attribute's local name.
+
+ Returns the index of the attribute (starting with 0) or -1 if it wasn't
+ found.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+int QXmlAttributes::index( const QString& uri, const QString& localPart ) const
+{
+ uint count = uriList.count();
+ for ( uint i=0; i<count; i++ ) {
+ if ( uriList[i] == uri && localnameList[i] == localPart )
+ return i;
+ }
+ return -1;
+}
+
+/*!
+ Returns the number of attributes in the list.
+*/
+int QXmlAttributes::length() const
+{
+ return valueList.count();
+}
+
+/*!
+ Looks up an attribute's local name by index (starting with 0).
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::localName( int index ) const
+{
+ return localnameList[index];
+}
+
+/*!
+ Looks up an attribute's XML 1.0 qualified name by index (starting with 0).
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::qName( int index ) const
+{
+ return qnameList[index];
+}
+
+/*!
+ Looks up an attribute's namespace URI by index (starting with 0).
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::uri( int index ) const
+{
+ return uriList[index];
+}
+
+/*!
+ Looks up an attribute's type by index (starting with 0).
+
+ At the moment only 'CDATA' is returned.
+*/
+QString QXmlAttributes::type( int ) const
+{
+ return "CDATA";
+}
+
+/*!
+ Looks up an attribute's type by XML 1.0 qualified name.
+
+ At the moment only 'CDATA' is returned.
+*/
+QString QXmlAttributes::type( const QString& ) const
+{
+ return "CDATA";
+}
+
+/*!
+ Looks up an attribute's type by namespace name.
+
+ The first parameter specifies the namespace URI, or the empty string if
+ the name has no namespace URI. The second parameter specifies the
+ attribute's local name.
+
+ At the moment only 'CDATA' is returned.
+*/
+QString QXmlAttributes::type( const QString&, const QString& ) const
+{
+ return "CDATA";
+}
+
+/*!
+ Looks up an attribute's value by index (starting with 0).
+*/
+QString QXmlAttributes::value( int index ) const
+{
+ return valueList[index];
+}
+
+/*!
+ Looks up an attribute's value by XML 1.0 qualified name.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::value( const QString& qName ) const
+{
+ int i = index( qName );
+ if ( i == -1 )
+ return QString::null;
+ return valueList[ i ];
+}
+
+/*!
+ Looks up an attribute's value by namespace name.
+
+ \a uri specifies the namespace URI, or the empty string if the name has no
+ namespace URI. \a localName specifies the attribute's local name.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::value( const QString& uri, const QString& localName ) const
+{
+ int i = index( uri, localName );
+ if ( i == -1 )
+ return QString::null;
+ return valueList[ i ];
+}
+
+
+/*********************************************
+ *
+ * QXmlInputSource
+ *
+ *********************************************/
+
+/*!
+ \class QXmlInputSource qxml.h
+ \brief The QXmlInputSource class is the source where XML data is read from.
+
+ \module XML
+
+ All subclasses of QXmlReader read the input from this class.
+*/
+
+/*!
+ Returns all the data this input source contains.
+*/
+const QString& QXmlInputSource::data() const
+{
+ return input;
+}
+
+/*!
+ Constructs a input source which contains no data.
+*/
+QXmlInputSource::QXmlInputSource( )
+{
+ input = "";
+}
+
+/*!
+ Constructs a input source and get the data from the text stream.
+*/
+QXmlInputSource::QXmlInputSource( QTextStream& stream )
+{
+ QByteArray rawData;
+ if ( stream.device()->isDirectAccess() ) {
+ rawData = stream.device()->readAll();
+ } else {
+ int nread = 0;
+ const int bufsize = 512;
+ while ( !stream.device()->atEnd() ) {
+ rawData.resize( nread + bufsize );
+ nread += stream.device()->readBlock( rawData.data()+nread, bufsize );
+ }
+ rawData.resize( nread );
+ }
+ readInput( rawData );
+}
+
+/*!
+ Constructs a input source and get the data from a file. If the file cannot be
+ read the input source is empty.
+*/
+QXmlInputSource::QXmlInputSource( QFile& file )
+{
+ if ( !file.open(IO_ReadOnly) ) {
+ input = "";
+ return;
+ }
+ QByteArray rawData = file.readAll();
+ readInput( rawData );
+ file.close();
+}
+
+/*!
+ Destructor.
+*/
+QXmlInputSource::~QXmlInputSource()
+{
+}
+
+/*!
+ Sets the data of the input source to \a dat.
+*/
+void QXmlInputSource::setData( const QString& dat )
+{
+ input = dat;
+}
+
+/*!
+ Read the XML file from the byte array; try to recoginize the encoding.
+*/
+// ### The input source should not do the encoding detection!
+void QXmlInputSource::readInput( QByteArray& rawData )
+{
+ QBuffer buf( rawData );
+ buf.open( IO_ReadOnly );
+ QTextStream *stream = new QTextStream( &buf );
+ QChar tmp;
+ // assume UTF8 or UTF16 at first
+ stream->setEncoding( QTextStream::UnicodeUTF8 );
+ input = "";
+ // read the first 5 characters
+ for ( int i=0; i<5; i++ ) {
+ *stream >> tmp;
+ input += tmp;
+ }
+ // starts the document with an XML declaration?
+ if ( input == "<?xml" ) {
+ // read the whole XML declaration
+ do {
+ *stream >> tmp;
+ input += tmp;
+ } while( tmp != '>' );
+ // and try to find out if there is an encoding
+ int pos = input.find( "encoding" );
+ if ( pos != -1 ) {
+ QString encoding;
+ do {
+ pos++;
+ if ( pos > (int)input.length() )
+ goto finished;
+ } while( input[pos] != '"' && input[pos] != '\'' );
+ pos++;
+ while( input[pos] != '"' && input[pos] != '\'' ) {
+ encoding += input[pos];
+ pos++;
+ if ( pos > (int)input.length() )
+ goto finished;
+ }
+ delete stream;
+ stream = new QTextStream( &buf );
+ stream->setCodec( QTextCodec::codecForName( encoding ) );
+ buf.reset();
+ input = "";
+ }
+ }
+finished:
+ input += stream->read();
+ delete stream;
+ buf.close();
+}
+
+
+/*********************************************
+ *
+ * QXmlDefaultHandler
+ *
+ *********************************************/
+
+/*!
+ \class QXmlContentHandler qxml.h
+ \brief The QXmlContentHandler class provides an interface to report logical
+ content of XML data.
+
+ \module XML
+
+ If the application needs to be informed of basic parsing events, it
+ implements this interface and sets it with QXmlReader::setContentHandler().
+ The reader reports basic document-related events like the start and end of
+ elements and character data through this interface.
+
+ The order of events in this interface is very important, and mirrors the
+ order of information in the document itself. For example, all of an element's
+ content (character data, processing instructions, and/or subelements) will
+ appear, in order, between the startElement() event and the corresponding
+ endElement() event.
+
+ The class QXmlDefaultHandler gives a default implementation for this
+ interface; subclassing from this class is very convenient if you want only be
+ informed of some parsing events.
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlDeclHandler QXmlEntityResolver QXmlErrorHandler
+ QXmlLexicalHandler
+*/
+/*!
+ \fn void QXmlContentHandler::setDocumentLocator( QXmlLocator* locator )
+
+ The reader calls this function before he starts parsing the document. The
+ argument \a locator is a pointer to a QXmlLocator which allows the
+ application to get the actual position of the parsing in the document.
+
+ Do not destroy the \a locator; it is destroyed when the reader is destroyed
+ (do not use the \a locator after the reader got destroyed).
+*/
+/*!
+ \fn bool QXmlContentHandler::startDocument()
+
+ The reader calls this function when he starts parsing the document.
+ The reader will call this function only once before any other functions in
+ this class or in the QXmlDTDHandler class are called (except
+ QXmlContentHandler::setDocumentLocator()).
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa endDocument()
+*/
+/*!
+ \fn bool QXmlContentHandler::endDocument()
+
+ The reader calls this function after he has finished the parsing. It
+ is only called once. It is the last function of all handler functions that is
+ called. It is called after the reader has read all input or has abandoned
+ parsing because of a fatal error.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa startDocument()
+*/
+/*!
+ \fn bool QXmlContentHandler::startPrefixMapping( const QString& prefix, const QString& uri )
+
+ The reader calls this function to signal the begin of a prefix-URI
+ namespace mapping scope. This information is not necessary for normal
+ namespace processing since the reader automatically replaces prefixes for
+ element and attribute names.
+
+ Note that startPrefixMapping and endPrefixMapping calls are not guaranteed to
+ be properly nested relative to each-other: all startPrefixMapping events will
+ occur before the corresponding startElement event, and all endPrefixMapping
+ events will occur after the corresponding endElement event, but their order
+ is not otherwise guaranteed.
+
+ The argument \a prefix is the namespace prefix being declared and the
+ argument \a uri is the namespace URI the prefix is mapped to.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+ \sa endPrefixMapping()
+*/
+/*!
+ \fn bool QXmlContentHandler::endPrefixMapping( const QString& prefix )
+
+ The reader calls this function to signal the end of a prefix mapping.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+ \sa startPrefixMapping()
+*/
+/*!
+ \fn bool QXmlContentHandler::startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts )
+
+ The reader calls this function when he has parsed a start element tag.
+
+ There will be a corresponding endElement() call when the corresponding end
+ element tag was read. The startElement() and endElement() calls are always
+ nested correctly. Empty element tags (e.g. &lt;a/&gt;) are reported by
+ startElement() directly followed by a call to endElement().
+
+ The attribute list provided will contain only attributes with explicit
+ values. The attribute list will contain attributes used for namespace
+ declaration (i.e. attributes starting with xmlns) only if the
+ namespace-prefix property of the reader is TRUE.
+
+ The argument \a uri is the namespace URI, or the empty string if the element
+ has no namespace URI or if namespace processing is not being performed, \a
+ localName is the local name (without prefix), or the empty string if
+ namespace processing is not being performed, \a qName is the qualified name
+ (with prefix), or the empty string if qualified names are not available and
+ \a atts are the attributes attached to the element. If there are no
+ attributes, \a atts is an empty attributes object
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+ \sa endElement()
+*/
+/*!
+ \fn bool QXmlContentHandler::endElement( const QString& namespaceURI, const QString& localName, const QString& qName )
+
+ The reader calls this function when he has parsed an end element tag.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+ \sa startElement()
+*/
+/*!
+ \fn bool QXmlContentHandler::characters( const QString& ch )
+
+ The reader calls this function when he has parsed a chunk of character
+ data (either normal character data or character data inside a CDATA section;
+ if you have to distinguish between those two types you have to use
+ QXmlLexicalHandler::startCDATA() and QXmlLexicalHandler::endCDATA() in
+ addition).
+
+ Some readers will report whitespace in element content using the
+ ignorableWhitespace() function rather than this one (QXmlSimpleReader will
+ do it not though).
+
+ A reader is allowed to report the character data of an element in more than
+ one chunk; e.g. a reader might want to report "a &amp;lt; b" in three
+ characters() events ("a ", "<" and " b").
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlContentHandler::ignorableWhitespace( const QString& ch )
+
+ Some readers may use this function to report each chunk of whitespace in
+ element content (QXmlSimpleReader does not though).
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlContentHandler::processingInstruction( const QString& target, const QString& data )
+
+ The reader calls this function when he has parsed a processing
+ instruction.
+
+ \a target is the target name of the processing instruction and \a data is the
+ data of the processing instruction.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlContentHandler::skippedEntity( const QString& name )
+
+ Some readers may skip entities if they have not seen the declarations (e.g.
+ because they are in an external DTD). If they do so they will report it by
+ calling this function.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn QString QXmlContentHandler::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlErrorHandler qxml.h
+ \brief The QXmlErrorHandler class provides an interface to report errors in
+ XML data.
+
+ \module XML
+
+ If the application is interested in reporting errors to the user or any other
+ customized error handling, you should subclass this class.
+
+ You can set the error handler with QXmlReader::setErrorHandler().
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
+ QXmlLexicalHandler
+*/
+/*!
+ \fn bool QXmlErrorHandler::warning( const QXmlParseException& exception )
+
+ A reader might use this function to report a warning. Warnings are conditions
+ that are not errors or fatal errors as defined by the XML 1.0 specification.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlErrorHandler::error( const QXmlParseException& exception )
+
+ A reader might use this function to report a recoverable error. A recoverable
+ error corresponds to the definiton of "error" in section 1.2 of the XML 1.0
+ specification.
+
+ The reader must continue to provide normal parsing events after invoking this
+ function.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlErrorHandler::fatalError( const QXmlParseException& exception )
+
+ A reader must use this function to report a non-recoverable error.
+
+ If this function returns TRUE the reader might try to go on parsing and
+ reporting further errors; but no regular parsing events are reported.
+*/
+/*!
+ \fn QString QXmlErrorHandler::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlDTDHandler qxml.h
+ \brief The QXmlDTDHandler class provides an interface to report DTD content
+ of XML data.
+
+ \module XML
+
+ If an application needs information about notations and unparsed entities,
+ then the application implements this interface and registers an instance with
+ QXmlReader::setDTDHandler().
+
+ Note that this interface includes only those DTD events that the XML
+ recommendation requires processors to report: notation and unparsed entity
+ declarations.
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDeclHandler QXmlContentHandler QXmlEntityResolver QXmlErrorHandler
+ QXmlLexicalHandler
+*/
+/*!
+ \fn bool QXmlDTDHandler::notationDecl( const QString& name, const QString& publicId, const QString& systemId )
+
+ The reader calls this function when he has parsed a notation
+ declaration.
+
+ The argument \a name is the notation name, \a publicId is the notations's
+ public identifier and \a systemId is the notations's system identifier.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlDTDHandler::unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName )
+
+ The reader calls this function when he finds an unparsed entity declaration.
+
+ The argument \a name is the unparsed entity's name, \a publicId is the
+ entity's public identifier, \a systemId is the entity's system identifier and
+ \a notation is the name of the associated notation.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn QString QXmlDTDHandler::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlEntityResolver qxml.h
+ \brief The QXmlEntityResolver class provides an interface to resolve extern
+ entities contained in XML data.
+
+ \module XML
+
+ If an application needs to implement customized handling for external
+ entities, it must implement this interface and register it with
+ QXmlReader::setEntityResolver().
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlErrorHandler
+ QXmlLexicalHandler
+*/
+/*!
+ \fn bool QXmlEntityResolver::resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* ret )
+
+ The reader will call this function before he opens any external entity,
+ except the top-level document entity. The application may request the reader
+ to resolve the entity itself (\a ret is 0) or to use an entirely different
+ input source (\a ret points to the input source).
+
+ The reader will delete the input source \a ret when he no longer needs it. So
+ you should allocate it on the heap with \c new.
+
+ The argument \a publicId is the public identifier of the external entity, \a
+ systemId is the system identifier of the external entity and \a ret is the
+ return value of this function: if it is 0 the reader should resolve the
+ entity itself, if it is non-zero it must point to an input source which the
+ reader will use instead.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn QString QXmlEntityResolver::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlLexicalHandler qxml.h
+ \brief The QXmlLexicalHandler class provides an interface to report lexical
+ content of XML data.
+
+ \module XML
+
+ The events in the lexical handler apply to the entire document, not just to
+ the document element, and all lexical handler events appear between the
+ content handler's startDocument and endDocument events.
+
+ You can set the lexical handler with QXmlReader::setLexicalHandler().
+
+ This interface is designed after the SAX2 extension LexicalHandler. The
+ functions startEntity() and endEntity() are not included though.
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
+ QXmlErrorHandler
+*/
+/*!
+ \fn bool QXmlLexicalHandler::startDTD( const QString& name, const QString& publicId, const QString& systemId )
+
+ The reader calls this function to report the start of a DTD declaration, if
+ any.
+
+ All declarations reported through QXmlDTDHandler or QXmlDeclHandler appear
+ between the startDTD() and endDTD() calls.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa endDTD()
+*/
+/*!
+ \fn bool QXmlLexicalHandler::endDTD()
+
+ The reader calls this function to report the end of a DTD declaration, if
+ any.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa startDTD()
+*/
+/*!
+ \fn bool QXmlLexicalHandler::startCDATA()
+
+ The reader calls this function to report the start of a CDATA section. The
+ content of the CDATA section will be reported through the regular
+ QXmlContentHandler::characters(). This function is intended only to report
+ the boundary.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa endCDATA()
+*/
+/*!
+ \fn bool QXmlLexicalHandler::endCDATA()
+
+ The reader calls this function to report the end of a CDATA section.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa startCDATA()
+*/
+/*!
+ \fn bool QXmlLexicalHandler::comment( const QString& ch )
+
+ The reader calls this function to report an XML comment anywhere in the
+ document.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn QString QXmlLexicalHandler::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlDeclHandler qxml.h
+ \brief The QXmlDeclHandler class provides an interface to report declaration
+ content of XML data.
+
+ \module XML
+
+ You can set the declaration handler with QXmlReader::setDeclHandler().
+
+ This interface is designed after the SAX2 extension DeclHandler.
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlContentHandler QXmlEntityResolver QXmlErrorHandler
+ QXmlLexicalHandler
+*/
+/*!
+ \fn bool QXmlDeclHandler::attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value )
+
+ The reader calls this function to report an attribute type declaration. Only
+ the effective (first) declaration for an attribute will be reported.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlDeclHandler::internalEntityDecl( const QString& name, const QString& value )
+
+ The reader calls this function to report an internal entity declaration. Only
+ the effective (first) declaration will be reported.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlDeclHandler::externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId )
+
+ The reader calls this function to report a parsed external entity
+ declaration. Only the effective (first) declaration for each entity will be
+ reported.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn QString QXmlDeclHandler::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlDefaultHandler qxml.h
+ \brief The QXmlDefaultHandler class provides a default implementation of all
+ XML handler classes.
+
+ \module XML
+
+ Very often you are only interested in parts of the things that that the
+ reader reports to you. This class simply implements a default behaviour of
+ the handler classes (most of the time: do nothing). Normally this is the
+ class you subclass for implementing your customized handler.
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
+ QXmlErrorHandler QXmlLexicalHandler
+*/
+/*!
+ \fn QXmlDefaultHandler::QXmlDefaultHandler()
+
+ Constructor.
+*/
+/*!
+ \fn QXmlDefaultHandler::~QXmlDefaultHandler()
+
+ Destructor.
+*/
+
+/*!
+ Does nothing.
+*/
+void QXmlDefaultHandler::setDocumentLocator( QXmlLocator* )
+{
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startDocument()
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endDocument()
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startPrefixMapping( const QString&, const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endPrefixMapping( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startElement( const QString&, const QString&,
+ const QString&, const QXmlAttributes& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endElement( const QString&, const QString&,
+ const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::characters( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::ignorableWhitespace( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::processingInstruction( const QString&,
+ const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::skippedEntity( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::warning( const QXmlParseException& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::error( const QXmlParseException& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::fatalError( const QXmlParseException& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::notationDecl( const QString&, const QString&,
+ const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::unparsedEntityDecl( const QString&, const QString&,
+ const QString&, const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Always sets \a ret to 0, so that the reader will use the system identifier
+ provided in the XML document.
+*/
+bool QXmlDefaultHandler::resolveEntity( const QString&, const QString&,
+ QXmlInputSource* /* ret */ )
+{
+/* ### This doesn't set anything to 0!
+ ret = 0;
+*/
+ return TRUE;
+}
+
+/*!
+ Returns the default error string.
+*/
+QString QXmlDefaultHandler::errorString()
+{
+ return QString( XMLERR_ERRORBYCONSUMER );
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startDTD( const QString&, const QString&, const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endDTD()
+{
+ return TRUE;
+}
+
+#if 0
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startEntity( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endEntity( const QString& )
+{
+ return TRUE;
+}
+#endif
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startCDATA()
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endCDATA()
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::comment( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::attributeDecl( const QString&, const QString&, const QString&, const QString&, const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::internalEntityDecl( const QString&, const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::externalEntityDecl( const QString&, const QString&, const QString& )
+{
+ return TRUE;
+}
+
+
+/*********************************************
+ *
+ * QXmlSimpleReaderPrivate
+ *
+ *********************************************/
+
+class QXmlSimpleReaderPrivate
+{
+private:
+ // constructor
+ QXmlSimpleReaderPrivate()
+ { }
+
+
+ // used for entity declarations
+ struct ExternParameterEntity
+ {
+ ExternParameterEntity( ) {}
+ ExternParameterEntity( const QString &p, const QString &s )
+ : publicId(p), systemId(s) {}
+ QString publicId;
+ QString systemId;
+ };
+ struct ExternEntity
+ {
+ ExternEntity( ) {}
+ ExternEntity( const QString &p, const QString &s, const QString &n )
+ : publicId(p), systemId(s), notation(n) {}
+ QString publicId;
+ QString systemId;
+ QString notation;
+ };
+ QMap<QString,ExternParameterEntity> externParameterEntities;
+ QMap<QString,QString> parameterEntities;
+ QMap<QString,ExternEntity> externEntities;
+ QMap<QString,QString> entities;
+
+ // used for standalone declaration
+ enum Standalone { Yes, No, Unknown };
+
+ QString doctype; // only used for the doctype
+ QString xmlVersion; // only used to store the version information
+ QString encoding; // only used to store the encoding
+ Standalone standalone; // used to store the value of the standalone declaration
+
+ QString publicId; // used by parseExternalID() to store the public ID
+ QString systemId; // used by parseExternalID() to store the system ID
+ QString attDeclEName; // use by parseAttlistDecl()
+ QString attDeclAName; // use by parseAttlistDecl()
+
+ // flags for some features support
+ bool useNamespaces;
+ bool useNamespacePrefixes;
+ bool reportWhitespaceCharData;
+ bool reportEntities;
+
+ // used to build the attribute list
+ QXmlAttributes attList;
+
+ // helper classes
+ QXmlLocator *locator;
+ QXmlNamespaceSupport namespaceSupport;
+
+ // error string
+ QString error;
+
+ // friend declarations
+ friend class QXmlSimpleReader;
+};
+
+
+/*********************************************
+ *
+ * QXmlSimpleReader
+ *
+ *********************************************/
+
+/*!
+ \class QXmlReader qxml.h
+ \brief The QXmlReader class provides an interface for XML readers (i.e.
+ parsers).
+
+ \module XML
+
+ This abstract class describes an interface for all XML readers in Qt. At the
+ moment there is only one implementation of a reader included in the XML
+ module of Qt (QXmlSimpleReader). In future releases there might be more
+ readers with different properties available (e.g. a validating parser).
+
+ The design of the XML classes follow the
+ <a href="http://www.megginson.com/SAX/">SAX2 java interface</a>.
+ It was adopted to fit into the Qt naming conventions; so it should be very
+ easy for anybody who has worked with SAX2 to get started with the Qt XML
+ classes.
+
+ All readers use the class QXmlInputSource to read the input document from.
+ Since you are normally interested in certain contents of the XML document,
+ the reader reports those contents through special handler classes
+ (QXmlDTDHandler, QXmlDeclHandler, QXmlContentHandler, QXmlEntityResolver,
+ QXmlErrorHandler and QXmlLexicalHandler).
+
+ You have to subclass these classes. Since the handler classes describe only
+ interfaces you must implement all functions; there is a class
+ (QXmlDefaultHandler) to make this easier; it implements a default behaviour
+ (do nothing) for all functions.
+
+ For getting started see also the
+ <a href="xml-sax.html#quickStart">Quick start</a>.
+
+ \sa QXmlSimpleReader
+*/
+/*!
+ \fn bool QXmlReader::feature( const QString& name, bool *ok ) const
+
+ If the reader has the feature \a name, this function returns the value of the
+ feature.
+
+ If the reader has not the feature \a name, the return value may be anything.
+
+ If \a ok is not 0, then \a ok is set to TRUE if the reader has the feature
+ \a name, otherwise \a ok is set to FALSE.
+
+ \sa setFeature() hasFeature()
+*/
+/*!
+ \fn void QXmlReader::setFeature( const QString& name, bool value )
+
+ Sets the feature \a name to \a value. If the reader has not the feature \a
+ name, this value is ignored.
+
+ \sa feature() hasFeature()
+*/
+/*!
+ \fn bool QXmlReader::hasFeature( const QString& name ) const
+
+ Returns \c TRUE if the reader has the feature \a name, otherwise FALSE.
+
+ \sa feature() setFeature()
+*/
+/*!
+ \fn void* QXmlReader::property( const QString& name, bool *ok ) const
+
+ If the reader has the property \a name, this function returns the value of
+ the property.
+
+ If the reader has not the property \a name, the return value is 0.
+
+ If \a ok is not 0, then \a ok is set to TRUE if the reader has the property
+ \a name, otherwise \a ok is set to FALSE.
+
+ \sa setProperty() hasProperty()
+*/
+/*!
+ \fn void QXmlReader::setProperty( const QString& name, void* value )
+
+ Sets the property \a name to \a value. If the reader has not the property \a
+ name, this value is ignored.
+
+ \sa property() hasProperty()
+*/
+/*!
+ \fn bool QXmlReader::hasProperty( const QString& name ) const
+
+ Returns TRUE if the reader has the property \a name, otherwise FALSE.
+
+ \sa property() setProperty()
+*/
+/*!
+ \fn void QXmlReader::setEntityResolver( QXmlEntityResolver* handler )
+
+ Sets the entity resolver to \a handler.
+
+ \sa entityResolver()
+*/
+/*!
+ \fn QXmlEntityResolver* QXmlReader::entityResolver() const
+
+ Returns the entity resolver or 0 if none was set.
+
+ \sa setEntityResolver()
+*/
+/*!
+ \fn void QXmlReader::setDTDHandler( QXmlDTDHandler* handler )
+
+ Sets the DTD handler to \a handler.
+
+ \sa DTDHandler()
+*/
+/*!
+ \fn QXmlDTDHandler* QXmlReader::DTDHandler() const
+
+ Returns the DTD handler or 0 if none was set.
+
+ \sa setDTDHandler()
+*/
+/*!
+ \fn void QXmlReader::setContentHandler( QXmlContentHandler* handler )
+
+ Sets the content handler to \a handler.
+
+ \sa contentHandler()
+*/
+/*!
+ \fn QXmlContentHandler* QXmlReader::contentHandler() const
+
+ Returns the content handler or 0 if none was set.
+
+ \sa setContentHandler()
+*/
+/*!
+ \fn void QXmlReader::setErrorHandler( QXmlErrorHandler* handler )
+
+ Sets the error handler to \a handler.
+
+ \sa errorHandler()
+*/
+/*!
+ \fn QXmlErrorHandler* QXmlReader::errorHandler() const
+
+ Returns the error handler or 0 if none was set
+
+ \sa setErrorHandler()
+*/
+/*!
+ \fn void QXmlReader::setLexicalHandler( QXmlLexicalHandler* handler )
+
+ Sets the lexical handler to \a handler.
+
+ \sa lexicalHandler()
+*/
+/*!
+ \fn QXmlLexicalHandler* QXmlReader::lexicalHandler() const
+
+ Returns the lexical handler or 0 if none was set.
+
+ \sa setLexicalHandler()
+*/
+/*!
+ \fn void QXmlReader::setDeclHandler( QXmlDeclHandler* handler )
+
+ Sets the declaration handler to \a handler.
+
+ \sa declHandler()
+*/
+/*!
+ \fn QXmlDeclHandler* QXmlReader::declHandler() const
+
+ Returns the declaration handler or 0 if none was set.
+
+ \sa setDeclHandler()
+*/
+/*!
+ \fn bool QXmlReader::parse( const QXmlInputSource& input )
+
+ Parses the XML document \a input. Returns TRUE if the parsing was successful,
+ otherwise FALSE.
+*/
+/*!
+ \fn bool QXmlReader::parse( const QString& systemId )
+
+ Parses the XML document at the location \a systemId. Returns TRUE if the
+ parsing was successful, otherwise FALSE.
+*/
+
+
+/*!
+ \class QXmlSimpleReader qxml.h
+ \brief The QXmlSimpleReader class provides an implementation of a simple XML
+ reader (i.e. parser).
+
+ \module XML
+
+ This XML reader is sufficient for simple parsing tasks. Here is a short list
+ of the properties of this reader:
+ <ul>
+ <li> well-formed parser
+ <li> does not parse any external entities
+ <li> can do namespace processing
+ </ul>
+
+ For getting started see also the
+ <a href="xml-sax.html#quickStart">Quick start</a>.
+*/
+
+//guaranteed not to be a characater
+const QChar QXmlSimpleReader::QEOF = QChar((ushort)0xffff);
+
+/*!
+ Constructs a simple XML reader.
+*/
+QXmlSimpleReader::QXmlSimpleReader()
+{
+ d = new QXmlSimpleReaderPrivate();
+ d->locator = new QXmlLocator( this );
+
+ entityRes = 0;
+ dtdHnd = 0;
+ contentHnd = 0;
+ errorHnd = 0;
+ lexicalHnd = 0;
+ declHnd = 0;
+
+ // default feature settings
+ d->useNamespaces = TRUE;
+ d->useNamespacePrefixes = FALSE;
+ d->reportWhitespaceCharData = TRUE;
+ d->reportEntities = FALSE;
+}
+
+/*!
+ Destroys a simple XML reader.
+*/
+QXmlSimpleReader::~QXmlSimpleReader()
+{
+ delete d->locator;
+ delete d;
+}
+
+/*!
+ Gets the state of a feature.
+
+ \sa setFeature() hasFeature()
+*/
+bool QXmlSimpleReader::feature( const QString& name, bool *ok ) const
+{
+ if ( ok != 0 )
+ *ok = TRUE;
+ if ( name == "http://xml.org/sax/features/namespaces" ) {
+ return d->useNamespaces;
+ } else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) {
+ return d->useNamespacePrefixes;
+ } else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
+ return d->reportWhitespaceCharData;
+ } else if ( name == "http://trolltech.com/xml/features/report-start-end-entity" ) {
+ return d->reportEntities;
+ } else {
+ qWarning( "Unknown feature " + name );
+ if ( ok != 0 )
+ *ok = FALSE;
+ }
+ return FALSE;
+}
+
+/*!
+ Sets the state of a feature.
+
+ Supported features are:
+ <ul>
+ <li> http://xml.org/sax/features/namespaces:
+ if this feature is TRUE, namespace processing is performed
+ <li> http://xml.org/sax/features/namespace-prefixes:
+ if this feature is TRUE, the the original prefixed names and attributes
+ used for namespace declarations are reported
+ <li> http://trolltech.com/xml/features/report-whitespace-only-CharData:
+ if this feature is TRUE, CharData that consists only of whitespace (and
+ no other characters) is not reported via
+ QXmlContentHandler::characters()
+ </ul>
+
+ \sa feature() hasFeature()
+*/
+void QXmlSimpleReader::setFeature( const QString& name, bool value )
+{
+ if ( name == "http://xml.org/sax/features/namespaces" ) {
+ d->useNamespaces = value;
+ } else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) {
+ d->useNamespacePrefixes = value;
+ } else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
+ d->reportWhitespaceCharData = value;
+ } else if ( name == "http://trolltech.com/xml/features/report-start-end-entity" ) {
+ d->reportEntities = value;
+ } else {
+ qWarning( "Unknown feature " + name );
+ }
+}
+
+/*!
+ Returns TRUE if the class has a feature named \a feature, otherwise FALSE.
+
+ \sa setFeature() feature()
+*/
+bool QXmlSimpleReader::hasFeature( const QString& name ) const
+{
+ if ( name == "http://xml.org/sax/features/namespaces" ||
+ name == "http://xml.org/sax/features/namespace-prefixes" ||
+ name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/*!
+ Returns 0 since this class does not support any properties.
+*/
+void* QXmlSimpleReader::property( const QString&, bool *ok ) const
+{
+ if ( ok != 0 )
+ *ok = FALSE;
+ return 0;
+}
+
+/*!
+ Does nothing since this class does not support any properties.
+*/
+void QXmlSimpleReader::setProperty( const QString&, void* )
+{
+}
+
+/*!
+ Returns FALSE since this class does not support any properties.
+*/
+bool QXmlSimpleReader::hasProperty( const QString& ) const
+{
+ return FALSE;
+}
+
+/*! \reimp */
+void QXmlSimpleReader::setEntityResolver( QXmlEntityResolver* handler )
+{ entityRes = handler; }
+
+/*! \reimp */
+QXmlEntityResolver* QXmlSimpleReader::entityResolver() const
+{ return entityRes; }
+
+/*! \reimp */
+void QXmlSimpleReader::setDTDHandler( QXmlDTDHandler* handler )
+{ dtdHnd = handler; }
+
+/*! \reimp */
+QXmlDTDHandler* QXmlSimpleReader::DTDHandler() const
+{ return dtdHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setContentHandler( QXmlContentHandler* handler )
+{ contentHnd = handler; }
+
+/*! \reimp */
+QXmlContentHandler* QXmlSimpleReader::contentHandler() const
+{ return contentHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setErrorHandler( QXmlErrorHandler* handler )
+{ errorHnd = handler; }
+
+/*! \reimp */
+QXmlErrorHandler* QXmlSimpleReader::errorHandler() const
+{ return errorHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setLexicalHandler( QXmlLexicalHandler* handler )
+{ lexicalHnd = handler; }
+
+/*! \reimp */
+QXmlLexicalHandler* QXmlSimpleReader::lexicalHandler() const
+{ return lexicalHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setDeclHandler( QXmlDeclHandler* handler )
+{ declHnd = handler; }
+
+/*! \reimp */
+QXmlDeclHandler* QXmlSimpleReader::declHandler() const
+{ return declHnd; }
+
+
+
+/*! \reimp */
+bool QXmlSimpleReader::parse( const QXmlInputSource& input )
+{
+ init( input );
+ // call the handler
+ if ( contentHnd ) {
+ contentHnd->setDocumentLocator( d->locator );
+ if ( !contentHnd->startDocument() ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ // parse prolog
+ if ( !parseProlog() ) {
+ d->error = XMLERR_ERRORPARSINGPROLOG;
+ goto parseError;
+ }
+ // parse element
+ if ( !parseElement() ) {
+ d->error = XMLERR_ERRORPARSINGMAINELEMENT;
+ goto parseError;
+ }
+ // parse Misc*
+ while ( !atEnd() ) {
+ if ( !parseMisc() ) {
+ d->error = XMLERR_ERRORPARSINGMISC;
+ goto parseError;
+ }
+ }
+ // is stack empty?
+ if ( !tags.isEmpty() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ // call the handler
+ if ( contentHnd ) {
+ if ( !contentHnd->endDocument() ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+
+ return TRUE;
+
+ // error handling
+
+parseError:
+ reportParseError();
+ tags.clear();
+ return FALSE;
+}
+
+/*!
+ Parses the prolog [22].
+*/
+bool QXmlSimpleReader::parseProlog()
+{
+ bool xmldecl_possible = TRUE;
+ bool doctype_read = FALSE;
+
+ const signed char Init = 0;
+ const signed char EatWS = 1; // eat white spaces
+ const signed char Lt = 2; // '<' read
+ const signed char Em = 3; // '!' read
+ const signed char DocType = 4; // read doctype
+ const signed char Comment = 5; // read comment
+ const signed char PI = 6; // read PI
+ const signed char Done = 7;
+
+ const signed char InpWs = 0;
+ const signed char InpLt = 1; // <
+ const signed char InpQm = 2; // ?
+ const signed char InpEm = 3; // !
+ const signed char InpD = 4; // D
+ const signed char InpDash = 5; // -
+ const signed char InpUnknown = 6;
+
+ // use some kind of state machine for parsing
+ static const signed char table[7][7] = {
+ /* InpWs InpLt InpQm InpEm InpD InpDash InpUnknown */
+ { EatWS, Lt, -1, -1, -1, -1, -1 }, // Init
+ { -1, Lt, -1, -1, -1, -1, -1 }, // EatWS
+ { -1, -1, PI, Em, Done, -1, Done }, // Lt
+ { -1, -1, -1, -1, DocType, Comment, -1 }, // Em
+ { EatWS, Lt, -1, -1, -1, -1, -1 }, // DocType
+ { EatWS, Lt, -1, -1, -1, -1, -1 }, // Comment
+ { EatWS, Lt, -1, -1, -1, -1, -1 } // PI
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // read input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '<' ) {
+ input = InpLt;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else if ( c == '!' ) {
+ input = InpEm;
+ } else if ( c == 'D' ) {
+ input = InpD;
+ } else if ( c == '-' ) {
+ input = InpDash;
+ } else {
+ input = InpUnknown;
+ }
+ // get new state
+ state = table[state][input];
+
+ // in some cases do special actions depending on state
+ switch ( state ) {
+ case EatWS:
+ // XML declaration only on first position possible
+ xmldecl_possible = FALSE;
+ // eat white spaces
+ eat_ws();
+ break;
+ case Lt:
+ // next character
+ next();
+ break;
+ case Em:
+ // XML declaration only on first position possible
+ xmldecl_possible = FALSE;
+ // next character
+ next();
+ break;
+ case DocType:
+ parseOk = parseDoctype();
+ break;
+ case Comment:
+ parseOk = parseComment();
+ break;
+ case PI:
+ parseOk = parsePI( xmldecl_possible );
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case DocType:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPROLOG;
+ goto parseError;
+ }
+ if ( doctype_read ) {
+ d->error = XMLERR_MORETHANONEDOCTYPE;
+ goto parseError;
+ } else {
+ doctype_read = FALSE;
+ }
+ break;
+ case Comment:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPROLOG;
+ goto parseError;
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ break;
+ case PI:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPROLOG;
+ goto parseError;
+ }
+ // call the handler
+ if ( contentHnd ) {
+ if ( xmldecl_possible && !d->xmlVersion.isEmpty() ) {
+ QString value( "version = '" );
+ value += d->xmlVersion;
+ value += "'";
+ if ( !d->encoding.isEmpty() ) {
+ value += " encoding = '";
+ value += d->encoding;
+ value += "'";
+ }
+ if ( d->standalone == QXmlSimpleReaderPrivate::Yes ) {
+ value += " standalone = 'yes'";
+ } else if ( d->standalone == QXmlSimpleReaderPrivate::No ) {
+ value += " standalone = 'no'";
+ }
+ if ( !contentHnd->processingInstruction( "xml", value ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ } else {
+ if ( !contentHnd->processingInstruction( name(), string() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ // XML declaration only on first position possible
+ xmldecl_possible = FALSE;
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ d->error = XMLERR_ERRORPARSINGELEMENT;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse an element [39].
+
+ Precondition: the opening '<' is already read.
+*/
+bool QXmlSimpleReader::parseElement()
+{
+ QString uri, lname, prefix;
+ bool t;
+
+ const signed char Init = 0;
+ const signed char ReadName = 1;
+ const signed char Ws1 = 2;
+ const signed char STagEnd = 3;
+ const signed char STagEnd2 = 4;
+ const signed char ETagBegin = 5;
+ const signed char ETagBegin2 = 6;
+ const signed char Ws2 = 7;
+ const signed char EmptyTag = 8;
+ const signed char Attribute = 9;
+ const signed char Ws3 = 10;
+ const signed char Done = 11;
+
+ const signed char InpWs = 0; // whitespace
+ const signed char InpNameBe = 1; // is_NameBeginning()
+ const signed char InpGt = 2; // >
+ const signed char InpSlash = 3; // /
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static const signed char table[11][5] = {
+ /* InpWs InpNameBe InpGt InpSlash InpUnknown */
+ { -1, ReadName, -1, -1, -1 }, // Init
+ { Ws1, Attribute, STagEnd, EmptyTag, -1 }, // ReadName
+ { -1, Attribute, STagEnd, EmptyTag, -1 }, // Ws1
+ { STagEnd2, STagEnd2, STagEnd2, STagEnd2, STagEnd2 }, // STagEnd
+ { -1, -1, -1, ETagBegin, -1 }, // STagEnd2
+ { -1, ETagBegin2, -1, -1, -1 }, // ETagBegin
+ { Ws2, -1, Done, -1, -1 }, // ETagBegin2
+ { -1, -1, Done, -1, -1 }, // Ws2
+ { -1, -1, Done, -1, -1 }, // EmptyTag
+ { Ws3, Attribute, STagEnd, EmptyTag, -1 }, // Attribute
+ { -1, Attribute, STagEnd, EmptyTag, -1 } // Ws3
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // read input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( is_NameBeginning(c) ) {
+ input = InpNameBe;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == '/' ) {
+ input = InpSlash;
+ } else {
+ input = InpUnknown;
+ }
+ // get new state
+//qDebug( "%d -%d(%c)-> %d", state, input, c.latin1(), table[state][input] );
+ state = table[state][input];
+
+ // in some cases do special actions depending on state
+ switch ( state ) {
+ case ReadName:
+ parseOk = parseName();
+ break;
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ eat_ws();
+ break;
+ case STagEnd:
+ // call the handler
+ if ( contentHnd ) {
+ if ( d->useNamespaces ) {
+ d->namespaceSupport.processName( tags.top(), FALSE, uri, lname );
+ t = contentHnd->startElement( uri, lname, tags.top(), d->attList );
+ } else {
+ t = contentHnd->startElement( "", "", tags.top(), d->attList );
+ }
+ if ( !t ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ next();
+ break;
+ case STagEnd2:
+ parseOk = parseContent();
+ break;
+ case ETagBegin:
+ next();
+ break;
+ case ETagBegin2:
+ // get the name of the tag
+ parseOk = parseName();
+ break;
+ case EmptyTag:
+ if ( tags.isEmpty() ) {
+ d->error = XMLERR_TAGMISMATCH;
+ goto parseError;
+ }
+ if ( !parseElementEmptyTag( t, uri, lname ) )
+ goto parseError;
+ // next character
+ next();
+ break;
+ case Attribute:
+ // get name and value of attribute
+ parseOk = parseAttribute();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case ReadName:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ // store it on the stack
+ tags.push( name() );
+ // empty the attributes
+ d->attList.qnameList.clear();
+ d->attList.uriList.clear();
+ d->attList.localnameList.clear();
+ d->attList.valueList.clear();
+ // namespace support?
+ if ( d->useNamespaces ) {
+ d->namespaceSupport.pushContext();
+ }
+ break;
+ case STagEnd2:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCONTENT;
+ goto parseError;
+ }
+ break;
+ case ETagBegin2:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ if ( !parseElementETagBegin2() )
+ goto parseError;
+ break;
+ case Attribute:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGATTRIBUTE;
+ goto parseError;
+ }
+ if ( !parseElementAttribute( prefix, uri, lname ) )
+ goto parseError;
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ d->error = XMLERR_ERRORPARSINGELEMENT;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+/*!
+ Helper to break down the size of the code in the case statement.
+ Return FALSE on error, otherwise TRUE.
+*/
+// ### Remove t argument in Qt 3.0 -- I don't need it. The same should be true for uri and lname.
+bool QXmlSimpleReader::parseElementEmptyTag( bool &, QString &uri, QString &lname )
+{
+ // pop the stack and call the handler
+ if ( contentHnd ) {
+ if ( d->useNamespaces ) {
+ // report startElement first...
+ d->namespaceSupport.processName( tags.top(), FALSE, uri, lname );
+ if ( !contentHnd->startElement( uri, lname, tags.top(), d->attList ) ) {
+ goto error;
+ }
+ // ... followed by endElement...
+ if ( !contentHnd->endElement( uri, lname, tags.pop() ) ) {
+ goto error;
+ }
+ // ... followed by endPrefixMapping
+ QStringList prefixesBefore, prefixesAfter;
+ if ( contentHnd ) {
+ prefixesBefore = d->namespaceSupport.prefixes();
+ }
+ d->namespaceSupport.popContext();
+ // call the handler for prefix mapping
+ prefixesAfter = d->namespaceSupport.prefixes();
+ for ( QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it ) {
+ if ( prefixesAfter.contains(*it) == 0 ) {
+ if ( !contentHnd->endPrefixMapping( *it ) ) {
+ goto error;
+ }
+ }
+ }
+ } else {
+ // report startElement first...
+ if ( !contentHnd->startElement( "", "", tags.top(), d->attList ) ) {
+ goto error;
+ }
+ // ... followed by endElement
+ if ( !contentHnd->endElement( "","",tags.pop() ) ) {
+ goto error;
+ }
+ }
+ } else {
+ tags.pop();
+ d->namespaceSupport.popContext();
+ }
+ return TRUE;
+error:
+ d->error = contentHnd->errorString();
+ return FALSE;
+}
+/*!
+ Helper to break down the size of the code in the case statement.
+ Return FALSE on error, otherwise TRUE.
+*/
+bool QXmlSimpleReader::parseElementETagBegin2()
+{
+
+ // pop the stack and compare it with the name
+ if ( tags.pop() != name() ) {
+ d->error = XMLERR_TAGMISMATCH;
+ return FALSE;
+ }
+ // call the handler
+ if ( contentHnd ) {
+ if ( d->useNamespaces ) {
+ QString uri, lname;
+ d->namespaceSupport.processName( name(), FALSE, uri, lname );
+ if ( !contentHnd->endElement( uri, lname, name() ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ } else {
+ if ( !contentHnd->endElement("","",name()) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ }
+ }
+ if ( d->useNamespaces ) {
+ QStringList prefixesBefore, prefixesAfter;
+ if ( contentHnd ) {
+ prefixesBefore = d->namespaceSupport.prefixes();
+ }
+ d->namespaceSupport.popContext();
+ // call the handler for prefix mapping
+ if ( contentHnd ) {
+ prefixesAfter = d->namespaceSupport.prefixes();
+ for ( QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it ) {
+ if ( prefixesAfter.contains(*it) == 0 ) {
+ if ( !contentHnd->endPrefixMapping( *it ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+/*!
+ Helper to break down the size of the code in the case statement.
+ Return FALSE on error, otherwise TRUE.
+*/
+// ### Remove arguments in Qt 3.0? I think, I don't need them.
+bool QXmlSimpleReader::parseElementAttribute( QString &prefix, QString &uri, QString &lname )
+{
+ // add the attribute to the list
+ if ( d->useNamespaces ) {
+ // is it a namespace declaration?
+ d->namespaceSupport.splitName( name(), prefix, lname );
+ if ( prefix == "xmlns" ) {
+ // namespace declaration
+ d->namespaceSupport.setPrefix( lname, string() );
+ if ( d->useNamespacePrefixes ) {
+ d->attList.qnameList.append( name() );
+ d->attList.uriList.append( "" );
+ d->attList.localnameList.append( "" );
+ d->attList.valueList.append( string() );
+ }
+ // call the handler for prefix mapping
+ if ( contentHnd ) {
+ if ( !contentHnd->startPrefixMapping( lname, string() ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ }
+ } else {
+ // no namespace delcaration
+ d->namespaceSupport.processName( name(), TRUE, uri, lname );
+ d->attList.qnameList.append( name() );
+ d->attList.uriList.append( uri );
+ d->attList.localnameList.append( lname );
+ d->attList.valueList.append( string() );
+ }
+ } else {
+ // no namespace support
+ d->attList.qnameList.append( name() );
+ d->attList.uriList.append( "" );
+ d->attList.localnameList.append( "" );
+ d->attList.valueList.append( string() );
+ }
+ return TRUE;
+}
+
+/*!
+ Parse a content [43].
+
+ A content is only used between tags. If a end tag is found the < is already
+ read and the head stand on the '/' of the end tag '</name>'.
+*/
+bool QXmlSimpleReader::parseContent()
+{
+ bool charDataRead = FALSE;
+
+ const signed char Init = 0;
+ const signed char ChD = 1; // CharData
+ const signed char ChD1 = 2; // CharData help state
+ const signed char ChD2 = 3; // CharData help state
+ const signed char Ref = 4; // Reference
+ const signed char Lt = 5; // '<' read
+ const signed char PI = 6; // PI
+ const signed char Elem = 7; // Element
+ const signed char Em = 8; // '!' read
+ const signed char Com = 9; // Comment
+ const signed char CDS = 10; // CDSect
+ const signed char CDS1 = 11; // read a CDSect
+ const signed char CDS2 = 12; // read a CDSect (help state)
+ const signed char CDS3 = 13; // read a CDSect (help state)
+ const signed char Done = 14; // finished reading content
+
+ const signed char InpLt = 0; // <
+ const signed char InpGt = 1; // >
+ const signed char InpSlash = 2; // /
+ const signed char InpQMark = 3; // ?
+ const signed char InpEMark = 4; // !
+ const signed char InpAmp = 5; // &
+ const signed char InpDash = 6; // -
+ const signed char InpOpenB = 7; // [
+ const signed char InpCloseB = 8; // ]
+ const signed char InpUnknown = 9;
+
+ static const signed char mapCLT2FSMChar[] = {
+ InpUnknown, // white space
+ InpUnknown, // %
+ InpAmp, // &
+ InpGt, // >
+ InpLt, // <
+ InpSlash, // /
+ InpQMark, // ?
+ InpEMark, // !
+ InpDash, // -
+ InpCloseB, // ]
+ InpOpenB, // [
+ InpUnknown, // =
+ InpUnknown, // "
+ InpUnknown, // '
+ InpUnknown // unknown
+ };
+
+ // use some kind of state machine for parsing
+ static const signed char table[14][10] = {
+ /* InpLt InpGt InpSlash InpQMark InpEMark InpAmp InpDash InpOpenB InpCloseB InpUnknown */
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // Init
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // ChD
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD1
+ { Lt, -1, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD2
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Ref (same as Init)
+ { -1, -1, Done, PI, Em, -1, -1, -1, -1, Elem }, // Lt
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // PI (same as Init)
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Elem (same as Init)
+ { -1, -1, -1, -1, -1, -1, Com, CDS, -1, -1 }, // Em
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Com (same as Init)
+ { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS
+ { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS1
+ { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 }, // CDS2
+ { CDS1, Init, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 } // CDS3
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // get input (use lookup-table instead of nested ifs for performance
+ // reasons)
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c.row() ) {
+ input = InpUnknown;
+ } else {
+ input = mapCLT2FSMChar[ charLookupTable[ c.cell() ] ];
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Init:
+ // next character
+ next();
+ break;
+ case ChD:
+ // on first call: clear string
+ if ( !charDataRead ) {
+ charDataRead = TRUE;
+ stringClear();
+ }
+ stringAddC();
+ next();
+ break;
+ case ChD1:
+ // on first call: clear string
+ if ( !charDataRead ) {
+ charDataRead = TRUE;
+ stringClear();
+ }
+ stringAddC();
+ next();
+ break;
+ case ChD2:
+ stringAddC();
+ next();
+ break;
+ case Ref:
+ if ( !charDataRead) {
+ // reference may be CharData; so clear string to be safe
+ stringClear();
+ parseOk = parseReference( charDataRead, InContent );
+ } else {
+ if ( d->reportEntities ) {
+ // this is undocumented so far; do this right in Qt 3.0
+ if ( contentHnd ) {
+ if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
+ if ( !contentHnd->characters( string() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ stringClear();
+ }
+ bool tmp;
+ parseOk = parseReference( tmp, InContent );
+ }
+ break;
+ case Lt:
+ // call the handler for CharData
+ if ( contentHnd ) {
+ if ( charDataRead ) {
+ if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
+ if ( !contentHnd->characters( string() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ }
+ charDataRead = FALSE;
+ // next character
+ next();
+ break;
+ case PI:
+ parseOk = parsePI();
+ break;
+ case Elem:
+ parseOk = parseElement();
+ break;
+ case Em:
+ // next character
+ next();
+ break;
+ case Com:
+ parseOk = parseComment();
+ break;
+ case CDS:
+ parseOk = parseString( "[CDATA[" );
+ break;
+ case CDS1:
+ // read one character and add it
+ stringAddC();
+ next();
+ break;
+ case CDS2:
+ // skip ']'
+ next();
+ break;
+ case CDS3:
+ // skip ']'...
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Ref:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+ break;
+ case PI:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPI;
+ goto parseError;
+ }
+ // call the handler
+ if ( contentHnd ) {
+ if ( !contentHnd->processingInstruction(name(),string()) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ break;
+ case Elem:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGELEMENT;
+ goto parseError;
+ }
+ break;
+ case Com:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCOMMENT;
+ goto parseError;
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ break;
+ case CDS:
+ if( !parseOk ) {
+ d->error = XMLERR_CDSECTHEADEREXPECTED;
+ goto parseError;
+ }
+ // empty string
+ stringClear();
+ break;
+ case CDS2:
+ if (c != ']') {
+ stringAddC( ']' );
+ }
+ break;
+ case CDS3:
+ // test if this skipping was legal
+ if ( c == '>' ) {
+ // the end of the CDSect
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->startCDATA() ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ if ( contentHnd ) {
+ if ( !contentHnd->characters( string() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->endCDATA() ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ } else if (c == ']') {
+ // three or more ']'
+ stringAddC( ']' );
+ } else {
+ // after ']]' comes another character
+ stringAddC( ']' );
+ stringAddC( ']' );
+ }
+ break;
+ case Done:
+ // call the handler for CharData
+ if ( contentHnd ) {
+ if ( charDataRead ) {
+ if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
+ if ( !contentHnd->characters( string() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ }
+ // Done
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_ERRORPARSINGCONTENT;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse Misc [27].
+*/
+bool QXmlSimpleReader::parseMisc()
+{
+ const signed char Init = 0;
+ const signed char Lt = 1; // '<' was read
+ const signed char Comment = 2; // read comment
+ const signed char eatWS = 3; // eat whitespaces
+ const signed char PI = 4; // read PI
+ const signed char Comment2 = 5; // read comment
+
+ const signed char InpWs = 0; // S
+ const signed char InpLt = 1; // <
+ const signed char InpQm = 2; // ?
+ const signed char InpEm = 3; // !
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static const signed char table[3][5] = {
+ /* InpWs InpLt InpQm InpEm InpUnknown */
+ { eatWS, Lt, -1, -1, -1 }, // Init
+ { -1, -1, PI, Comment, -1 }, // Lt
+ { -1, -1, -1, -1, Comment2 } // Comment
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '<' ) {
+ input = InpLt;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else if ( c == '!' ) {
+ input = InpEm;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case eatWS:
+ eat_ws();
+ break;
+ case Lt:
+ next();
+ break;
+ case PI:
+ parseOk = parsePI();
+ break;
+ case Comment:
+ next();
+ break;
+ case Comment2:
+ parseOk = parseComment();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case eatWS:
+ return TRUE;
+ case PI:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPI;
+ goto parseError;
+ }
+ if ( contentHnd ) {
+ if ( !contentHnd->processingInstruction(name(),string()) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ return TRUE;
+ case Comment2:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCOMMENT;
+ goto parseError;
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a processing instruction [16].
+
+ If xmldec is TRUE, it tries to parse a PI or a XML declaration [23].
+
+ Precondition: the beginning '<' of the PI is already read and the head stand
+ on the '?' of '<?'.
+
+ If this funktion was successful, the head-position is on the first
+ character after the PI.
+*/
+bool QXmlSimpleReader::parsePI( bool xmldecl )
+{
+ const signed char Init = 0;
+ const signed char QmI = 1; // ? was read
+ const signed char Name = 2; // read Name
+ const signed char XMLDecl = 3; // read XMLDecl
+ const signed char Ws1 = 4; // eat ws after "xml" of XMLDecl
+ const signed char PI = 5; // read PI
+ const signed char Ws2 = 6; // eat ws after Name of PI
+ const signed char Version = 7; // read versionInfo
+ const signed char Ws3 = 8; // eat ws after versionInfo
+ const signed char EorSD = 9; // read EDecl or SDDecl
+ const signed char Ws4 = 10; // eat ws after EDecl or SDDecl
+ const signed char SD = 11; // read SDDecl
+ const signed char Ws5 = 12; // eat ws after SDDecl
+ const signed char ADone = 13; // almost done
+ const signed char Char = 14; // Char was read
+ const signed char Qm = 15; // Qm was read
+ const signed char Done = 16; // finished reading content
+
+ const signed char InpWs = 0; // whitespace
+ const signed char InpNameBe = 1; // is_nameBeginning()
+ const signed char InpGt = 2; // >
+ const signed char InpQm = 3; // ?
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static const signed char table[16][5] = {
+ /* InpWs, InpNameBe InpGt InpQm InpUnknown */
+ { -1, -1, -1, QmI, -1 }, // Init
+ { -1, Name, -1, -1, -1 }, // QmI
+ { -1, -1, -1, -1, -1 }, // Name (this state is left not through input)
+ { Ws1, -1, -1, -1, -1 }, // XMLDecl
+ { -1, Version, -1, -1, -1 }, // Ws1
+ { Ws2, -1, -1, Qm, -1 }, // PI
+ { Char, Char, Char, Qm, Char }, // Ws2
+ { Ws3, -1, -1, ADone, -1 }, // Version
+ { -1, EorSD, -1, ADone, -1 }, // Ws3
+ { Ws4, -1, -1, ADone, -1 }, // EorSD
+ { -1, SD, -1, ADone, -1 }, // Ws4
+ { Ws5, -1, -1, ADone, -1 }, // SD
+ { -1, -1, -1, ADone, -1 }, // Ws5
+ { -1, -1, Done, -1, -1 }, // ADone
+ { Char, Char, Char, Qm, Char }, // Char
+ { Char, Char, Done, Qm, Char }, // Qm
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( is_NameBeginning(c) ) {
+ input = InpNameBe;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case QmI:
+ next();
+ break;
+ case Name:
+ parseOk = parseName();
+ break;
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ case Ws4:
+ case Ws5:
+ eat_ws();
+ break;
+ case Version:
+ parseOk = parseAttribute();
+ break;
+ case EorSD:
+ parseOk = parseAttribute();
+ break;
+ case SD:
+ // get the SDDecl (syntax like an attribute)
+ if ( d->standalone != QXmlSimpleReaderPrivate::Unknown ) {
+ // already parsed the standalone declaration
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ parseOk = parseAttribute();
+ break;
+ case ADone:
+ next();
+ break;
+ case Char:
+ stringAddC();
+ next();
+ break;
+ case Qm:
+ // skip the '?'
+ next();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Name:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ // test what name was read and determine the next state
+ // (not very beautiful, I admit)
+ if ( name().lower() == "xml" ) {
+ if ( xmldecl && name()=="xml" ) {
+ state = XMLDecl;
+ } else {
+ d->error = XMLERR_INVALIDNAMEFORPI;
+ goto parseError;
+ }
+ } else {
+ state = PI;
+ stringClear();
+ }
+ break;
+ case Version:
+ // get version (syntax like an attribute)
+ if ( !parseOk ) {
+ d->error = XMLERR_VERSIONEXPECTED;
+ goto parseError;
+ }
+ if ( name() != "version" ) {
+ d->error = XMLERR_VERSIONEXPECTED;
+ goto parseError;
+ }
+ d->xmlVersion = string();
+ break;
+ case EorSD:
+ // get the EDecl or SDDecl (syntax like an attribute)
+ if ( !parseOk ) {
+ d->error = XMLERR_EDECLORSDDECLEXPECTED;
+ goto parseError;
+ }
+ if ( name() == "standalone" ) {
+ if ( string()=="yes" ) {
+ d->standalone = QXmlSimpleReaderPrivate::Yes;
+ } else if ( string()=="no" ) {
+ d->standalone = QXmlSimpleReaderPrivate::No;
+ } else {
+ d->error = XMLERR_WRONGVALUEFORSDECL;
+ goto parseError;
+ }
+ } else if ( name() == "encoding" ) {
+ d->encoding = string();
+ } else {
+ d->error = XMLERR_EDECLORSDDECLEXPECTED;
+ goto parseError;
+ }
+ break;
+ case SD:
+ if ( !parseOk ) {
+ d->error = XMLERR_SDDECLEXPECTED;
+ goto parseError;
+ }
+ if ( name() != "standalone" ) {
+ d->error = XMLERR_SDDECLEXPECTED;
+ goto parseError;
+ }
+ if ( string()=="yes" ) {
+ d->standalone = QXmlSimpleReaderPrivate::Yes;
+ } else if ( string()=="no" ) {
+ d->standalone = QXmlSimpleReaderPrivate::No;
+ } else {
+ d->error = XMLERR_WRONGVALUEFORSDECL;
+ goto parseError;
+ }
+ break;
+ case Qm:
+ // test if the skipping was legal
+ if ( c != '>' ) {
+ stringAddC( '?' );
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a document type definition (doctypedecl [28]).
+
+ Precondition: the beginning '<!' of the doctype is already read the head
+ stands on the 'D' of '<!DOCTYPE'.
+
+ If this funktion was successful, the head-position is on the first
+ character after the document type definition.
+*/
+bool QXmlSimpleReader::parseDoctype()
+{
+ // some init-stuff
+ d->systemId = QString::null;
+ d->publicId = QString::null;
+
+ const signed char Init = 0;
+ const signed char Doctype = 1; // read the doctype
+ const signed char Ws1 = 2; // eat_ws
+ const signed char Doctype2 = 3; // read the doctype, part 2
+ const signed char Ws2 = 4; // eat_ws
+ const signed char Sys = 5; // read SYSTEM
+ const signed char Ws3 = 6; // eat_ws
+ const signed char MP = 7; // markupdecl or PEReference
+ const signed char PER = 8; // PERReference
+ const signed char Mup = 9; // markupdecl
+ const signed char Ws4 = 10; // eat_ws
+ const signed char MPE = 11; // end of markupdecl or PEReference
+ const signed char Done = 12;
+
+ const signed char InpWs = 0;
+ const signed char InpD = 1; // 'D'
+ const signed char InpS = 2; // 'S' or 'P'
+ const signed char InpOB = 3; // [
+ const signed char InpCB = 4; // ]
+ const signed char InpPer = 5; // %
+ const signed char InpGt = 6; // >
+ const signed char InpUnknown = 7;
+
+ // use some kind of state machine for parsing
+ static const signed char table[12][8] = {
+ /* InpWs, InpD InpS InpOB InpCB InpPer InpGt InpUnknown */
+ { -1, Doctype, -1, -1, -1, -1, -1, -1 }, // Init
+ { Ws1, Doctype2, Doctype2, -1, -1, -1, -1, Doctype2 }, // Doctype
+ { -1, Doctype2, Doctype2, -1, -1, -1, -1, Doctype2 }, // Ws1
+ { Ws2, -1, Sys, MP, -1, -1, Done, -1 }, // Doctype2
+ { -1, -1, Sys, MP, -1, -1, Done, -1 }, // Ws2
+ { Ws3, -1, -1, MP, -1, -1, Done, -1 }, // Sys
+ { -1, -1, -1, MP, -1, -1, Done, -1 }, // Ws3
+ { -1, -1, -1, -1, MPE, PER, -1, Mup }, // MP
+ { Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // PER
+ { Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // Mup
+ { -1, -1, -1, -1, MPE, PER, -1, Mup }, // Ws4
+ { -1, -1, -1, -1, -1, -1, Done, -1 } // MPE
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == 'D' ) {
+ input = InpD;
+ } else if ( c == 'S' ) {
+ input = InpS;
+ } else if ( c == 'P' ) {
+ input = InpS;
+ } else if ( c == '[' ) {
+ input = InpOB;
+ } else if ( c == ']' ) {
+ input = InpCB;
+ } else if ( c == '%' ) {
+ input = InpPer;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Doctype:
+ parseOk = parseString( "DOCTYPE" );
+ break;
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ case Ws4:
+ eat_ws();
+ break;
+ case Doctype2:
+ parseName();
+ break;
+ case Sys:
+ parseOk = parseExternalID();
+ break;
+ case MP:
+ next_eat_ws();
+ break;
+ case PER:
+ parseOk = parsePEReference( InDTD );
+ break;
+ case Mup:
+ parseOk = parseMarkupdecl();
+ break;
+ case MPE:
+ next_eat_ws();
+ break;
+ case Done:
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->endDTD() ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Doctype:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ if ( !is_S(c) ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ break;
+ case Doctype2:
+ d->doctype = name();
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->startDTD( d->doctype, d->publicId, d->systemId ) ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ break;
+ case Sys:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ break;
+ case PER:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ break;
+ case Mup:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a ExternalID [75].
+
+ If allowPublicID is TRUE parse ExternalID [75] or PublicID [83].
+*/
+bool QXmlSimpleReader::parseExternalID( bool allowPublicID )
+{
+ // some init-stuff
+ d->systemId = QString::null;
+ d->publicId = QString::null;
+
+ const signed char Init = 0;
+ const signed char Sys = 1; // parse 'SYSTEM'
+ const signed char SysWS = 2; // parse the whitespace after 'SYSTEM'
+ const signed char SysSQ = 3; // parse SystemLiteral with '
+ const signed char SysSQ2 = 4; // parse SystemLiteral with '
+ const signed char SysDQ = 5; // parse SystemLiteral with "
+ const signed char SysDQ2 = 6; // parse SystemLiteral with "
+ const signed char Pub = 7; // parse 'PUBLIC'
+ const signed char PubWS = 8; // parse the whitespace after 'PUBLIC'
+ const signed char PubSQ = 9; // parse PubidLiteral with '
+ const signed char PubSQ2 = 10; // parse PubidLiteral with '
+ const signed char PubDQ = 11; // parse PubidLiteral with "
+ const signed char PubDQ2 = 12; // parse PubidLiteral with "
+ const signed char PubE = 13; // finished parsing the PubidLiteral
+ const signed char PubWS2 = 14; // parse the whitespace after the PubidLiteral
+ const signed char PDone = 15; // done if allowPublicID is TRUE
+ const signed char Done = 16;
+
+ const signed char InpSQ = 0; // '
+ const signed char InpDQ = 1; // "
+ const signed char InpS = 2; // S
+ const signed char InpP = 3; // P
+ const signed char InpWs = 4; // white space
+ const signed char InpUnknown = 5;
+
+ // use some kind of state machine for parsing
+ static const signed char table[15][6] = {
+ /* InpSQ InpDQ InpS InpP InpWs InpUnknown */
+ { -1, -1, Sys, Pub, -1, -1 }, // Init
+ { -1, -1, -1, -1, SysWS, -1 }, // Sys
+ { SysSQ, SysDQ, -1, -1, -1, -1 }, // SysWS
+ { Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ
+ { Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ2
+ { SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ
+ { SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ2
+ { -1, -1, -1, -1, PubWS, -1 }, // Pub
+ { PubSQ, PubDQ, -1, -1, -1, -1 }, // PubWS
+ { PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ
+ { PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ2
+ { -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ
+ { -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ2
+ { PDone, PDone, PDone, PDone, PubWS2, PDone }, // PubE
+ { SysSQ, SysDQ, PDone, PDone, PDone, PDone } // PubWS2
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '\'' ) {
+ input = InpSQ;
+ } else if ( c == '"' ) {
+ input = InpDQ;
+ } else if ( c == 'S' ) {
+ input = InpS;
+ } else if ( c == 'P' ) {
+ input = InpP;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Sys:
+ parseOk = parseString( "SYSTEM" );
+ break;
+ case SysWS:
+ eat_ws();
+ break;
+ case SysSQ:
+ case SysDQ:
+ stringClear();
+ next();
+ break;
+ case SysSQ2:
+ case SysDQ2:
+ stringAddC();
+ next();
+ break;
+ case Pub:
+ parseOk = parseString( "PUBLIC" );
+ break;
+ case PubWS:
+ eat_ws();
+ break;
+ case PubSQ:
+ case PubDQ:
+ stringClear();
+ next();
+ break;
+ case PubSQ2:
+ case PubDQ2:
+ stringAddC();
+ next();
+ break;
+ case PubE:
+ next();
+ break;
+ case PubWS2:
+ d->publicId = string();
+ eat_ws();
+ break;
+ case Done:
+ d->systemId = string();
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Sys:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Pub:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case PDone:
+ if ( allowPublicID ) {
+ d->publicId = string();
+ return TRUE;
+ } else {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a markupdecl [29].
+*/
+bool QXmlSimpleReader::parseMarkupdecl()
+{
+ const signed char Init = 0;
+ const signed char Lt = 1; // < was read
+ const signed char Em = 2; // ! was read
+ const signed char CE = 3; // E was read
+ const signed char Qm = 4; // ? was read
+ const signed char Dash = 5; // - was read
+ const signed char CA = 6; // A was read
+ const signed char CEL = 7; // EL was read
+ const signed char CEN = 8; // EN was read
+ const signed char CN = 9; // N was read
+ const signed char Done = 10;
+
+ const signed char InpLt = 0; // <
+ const signed char InpQm = 1; // ?
+ const signed char InpEm = 2; // !
+ const signed char InpDash = 3; // -
+ const signed char InpA = 4; // A
+ const signed char InpE = 5; // E
+ const signed char InpL = 6; // L
+ const signed char InpN = 7; // N
+ const signed char InpUnknown = 8;
+
+ // use some kind of state machine for parsing
+ static const signed char table[4][9] = {
+ /* InpLt InpQm InpEm InpDash InpA InpE InpL InpN InpUnknown */
+ { Lt, -1, -1, -1, -1, -1, -1, -1, -1 }, // Init
+ { -1, Qm, Em, -1, -1, -1, -1, -1, -1 }, // Lt
+ { -1, -1, -1, Dash, CA, CE, -1, CN, -1 }, // Em
+ { -1, -1, -1, -1, -1, -1, CEL, CEN, -1 } // CE
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == '<' ) {
+ input = InpLt;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else if ( c == '!' ) {
+ input = InpEm;
+ } else if ( c == '-' ) {
+ input = InpDash;
+ } else if ( c == 'A' ) {
+ input = InpA;
+ } else if ( c == 'E' ) {
+ input = InpE;
+ } else if ( c == 'L' ) {
+ input = InpL;
+ } else if ( c == 'N' ) {
+ input = InpN;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Lt:
+ next();
+ break;
+ case Em:
+ next();
+ break;
+ case CE:
+ next();
+ break;
+ case Qm:
+ parseOk = parsePI();
+ break;
+ case Dash:
+ parseOk = parseComment();
+ break;
+ case CA:
+ parseOk = parseAttlistDecl();
+ break;
+ case CEL:
+ parseOk = parseElementDecl();
+ break;
+ case CEN:
+ parseOk = parseEntityDecl();
+ break;
+ case CN:
+ parseOk = parseNotationDecl();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Qm:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPI;
+ goto parseError;
+ }
+ if ( contentHnd ) {
+ if ( !contentHnd->processingInstruction(name(),string()) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ return TRUE;
+ case Dash:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCOMMENT;
+ goto parseError;
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ return TRUE;
+ case CA:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGATTLISTDECL;
+ goto parseError;
+ }
+ return TRUE;
+ case CEL:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGELEMENTDECL;
+ goto parseError;
+ }
+ return TRUE;
+ case CEN:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGENTITYDECL;
+ goto parseError;
+ }
+ return TRUE;
+ case CN:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNOTATIONDECL;
+ goto parseError;
+ }
+ return TRUE;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a PEReference [69]
+*/
+bool QXmlSimpleReader::parsePEReference( EntityRecognitionContext context )
+{
+ const signed char Init = 0;
+ const signed char Next = 1;
+ const signed char Name = 2;
+ const signed char Done = 3;
+
+ const signed char InpSemi = 0; // ;
+ const signed char InpPer = 1; // %
+ const signed char InpUnknown = 2;
+
+ // use some kind of state machine for parsing
+ static const signed char table[3][3] = {
+ /* InpSemi InpPer InpUnknown */
+ { -1, Next, -1 }, // Init
+ { -1, -1, Name }, // Next
+ { Done, -1, -1 } // Name
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == ';' ) {
+ input = InpSemi;
+ } else if ( c == '%' ) {
+ input = InpPer;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Next:
+ next();
+ break;
+ case Name:
+ parseOk = parseName( TRUE );
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Name:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ if ( d->parameterEntities.find( ref() ) == d->parameterEntities.end() ) {
+ // ### skip it???
+ if ( contentHnd ) {
+ if ( !contentHnd->skippedEntity( QString("%") + ref() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ } else {
+ if ( context == InEntityValue ) {
+ // Included in literal
+ xmlRef = d->parameterEntities.find( ref() )
+ .data().replace( QRegExp("\""), "&quot;" ).replace( QRegExp("'"), "&apos;" )
+ + xmlRef;
+ } else if ( context == InDTD ) {
+ // Included as PE
+ xmlRef = QString(" ") +
+ d->parameterEntities.find( ref() ).data() +
+ QString(" ") + xmlRef;
+ }
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a AttlistDecl [52].
+
+ Precondition: the beginning '<!' is already read and the head
+ stands on the 'A' of '<!ATTLIST'
+*/
+bool QXmlSimpleReader::parseAttlistDecl()
+{
+ const signed char Init = 0;
+ const signed char Attlist = 1; // parse the string "ATTLIST"
+ const signed char Ws = 2; // whitespace read
+ const signed char Name = 3; // parse name
+ const signed char Ws1 = 4; // whitespace read
+ const signed char Attdef = 5; // parse the AttDef
+ const signed char Ws2 = 6; // whitespace read
+ const signed char Atttype = 7; // parse the AttType
+ const signed char Ws3 = 8; // whitespace read
+ const signed char DDecH = 9; // DefaultDecl with #
+ const signed char DefReq = 10; // parse the string "REQUIRED"
+ const signed char DefImp = 11; // parse the string "IMPLIED"
+ const signed char DefFix = 12; // parse the string "FIXED"
+ const signed char Attval = 13; // parse the AttValue
+ const signed char Ws4 = 14; // whitespace read
+ const signed char Done = 15;
+
+ const signed char InpWs = 0; // white space
+ const signed char InpGt = 1; // >
+ const signed char InpHash = 2; // #
+ const signed char InpA = 3; // A
+ const signed char InpI = 4; // I
+ const signed char InpF = 5; // F
+ const signed char InpR = 6; // R
+ const signed char InpUnknown = 7;
+
+ // use some kind of state machine for parsing
+ static const signed char table[15][8] = {
+ /* InpWs InpGt InpHash InpA InpI InpF InpR InpUnknown */
+ { -1, -1, -1, Attlist, -1, -1, -1, -1 }, // Init
+ { Ws, -1, -1, -1, -1, -1, -1, -1 }, // Attlist
+ { -1, -1, -1, Name, Name, Name, Name, Name }, // Ws
+ { Ws1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Name
+ { -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Ws1
+ { Ws2, -1, -1, -1, -1, -1, -1, -1 }, // Attdef
+ { -1, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype }, // Ws2
+ { Ws3, -1, -1, -1, -1, -1, -1, -1 }, // Attype
+ { -1, Attval, DDecH, Attval, Attval, Attval, Attval, Attval }, // Ws3
+ { -1, -1, -1, -1, DefImp, DefFix, DefReq, -1 }, // DDecH
+ { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefReq
+ { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefImp
+ { Ws3, -1, -1, -1, -1, -1, -1, -1 }, // DefFix
+ { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // Attval
+ { -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef } // Ws4
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == '#' ) {
+ input = InpHash;
+ } else if ( c == 'A' ) {
+ input = InpA;
+ } else if ( c == 'I' ) {
+ input = InpI;
+ } else if ( c == 'F' ) {
+ input = InpF;
+ } else if ( c == 'R' ) {
+ input = InpR;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Attlist:
+ parseOk = parseString( "ATTLIST" );
+ break;
+ case Ws:
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ eat_ws();
+ break;
+ case Name:
+ parseOk = parseName();
+ break;
+ case Attdef:
+ parseOk = parseName();
+ break;
+ case Atttype:
+ parseOk = parseAttType();
+ break;
+ case DDecH:
+ next();
+ break;
+ case DefReq:
+ parseOk = parseString( "REQUIRED" );
+ break;
+ case DefImp:
+ parseOk = parseString( "IMPLIED" );
+ break;
+ case DefFix:
+ parseOk = parseString( "FIXED" );
+ break;
+ case Attval:
+ parseOk = parseAttValue();
+ break;
+ case Ws4:
+ if ( declHnd ) {
+ // TODO: not all values are computed yet...
+ if ( !declHnd->attributeDecl( d->attDeclEName, d->attDeclAName, "", "", "" ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ eat_ws();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Attlist:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Name:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ d->attDeclEName = name();
+ break;
+ case Attdef:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ d->attDeclAName = name();
+ break;
+ case Atttype:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGATTTYPE;
+ goto parseError;
+ }
+ break;
+ case DefReq:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case DefImp:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case DefFix:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Attval:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGATTVALUE;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a AttType [54]
+*/
+bool QXmlSimpleReader::parseAttType()
+{
+ const signed char Init = 0;
+ const signed char ST = 1; // StringType
+ const signed char TTI = 2; // TokenizedType starting with 'I'
+ const signed char TTI2 = 3; // TokenizedType helpstate
+ const signed char TTI3 = 4; // TokenizedType helpstate
+ const signed char TTE = 5; // TokenizedType starting with 'E'
+ const signed char TTEY = 6; // TokenizedType starting with 'ENTITY'
+ const signed char TTEI = 7; // TokenizedType starting with 'ENTITI'
+ const signed char N = 8; // N read (TokenizedType or Notation)
+ const signed char TTNM = 9; // TokenizedType starting with 'NM'
+ const signed char TTNM2 = 10; // TokenizedType helpstate
+ const signed char NO = 11; // Notation
+ const signed char NO2 = 12; // Notation helpstate
+ const signed char NO3 = 13; // Notation helpstate
+ const signed char NOName = 14; // Notation, read name
+ const signed char NO4 = 15; // Notation helpstate
+ const signed char EN = 16; // Enumeration
+ const signed char ENNmt = 17; // Enumeration, read Nmtoken
+ const signed char EN2 = 18; // Enumeration helpstate
+ const signed char ADone = 19; // almost done (make next and accept)
+ const signed char Done = 20;
+
+ const signed char InpWs = 0; // whitespace
+ const signed char InpOp = 1; // (
+ const signed char InpCp = 2; // )
+ const signed char InpPipe = 3; // |
+ const signed char InpC = 4; // C
+ const signed char InpE = 5; // E
+ const signed char InpI = 6; // I
+ const signed char InpM = 7; // M
+ const signed char InpN = 8; // N
+ const signed char InpO = 9; // O
+ const signed char InpR = 10; // R
+ const signed char InpS = 11; // S
+ const signed char InpY = 12; // Y
+ const signed char InpUnknown = 13;
+
+ // use some kind of state machine for parsing
+ static const signed char table[19][14] = {
+ /* InpWs InpOp InpCp InpPipe InpC InpE InpI InpM InpN InpO InpR InpS InpY InpUnknown */
+ { -1, EN, -1, -1, ST, TTE, TTI, -1, N, -1, -1, -1, -1, -1 }, // Init
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // ST
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI2, Done, Done, Done }, // TTI
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI3, Done, Done }, // TTI2
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTI3
+ { -1, -1, -1, -1, -1, -1, TTEI, -1, -1, -1, -1, -1, TTEY, -1 }, // TTE
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEY
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEI
+ { -1, -1, -1, -1, -1, -1, -1, TTNM, -1, NO, -1, -1, -1, -1 }, // N
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTNM2, Done, Done }, // TTNM
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTNM2
+ { NO2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO
+ { -1, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO2
+ { NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName }, // NO3
+ { NO4, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NOName
+ { -1, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO4
+ { -1, -1, ENNmt, -1, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt }, // EN
+ { EN2, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // ENNmt
+ { -1, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // EN2
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '(' ) {
+ input = InpOp;
+ } else if ( c == ')' ) {
+ input = InpCp;
+ } else if ( c == '|' ) {
+ input = InpPipe;
+ } else if ( c == 'C' ) {
+ input = InpC;
+ } else if ( c == 'E' ) {
+ input = InpE;
+ } else if ( c == 'I' ) {
+ input = InpI;
+ } else if ( c == 'M' ) {
+ input = InpM;
+ } else if ( c == 'N' ) {
+ input = InpN;
+ } else if ( c == 'O' ) {
+ input = InpO;
+ } else if ( c == 'R' ) {
+ input = InpR;
+ } else if ( c == 'S' ) {
+ input = InpS;
+ } else if ( c == 'Y' ) {
+ input = InpY;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case ST:
+ parseOk = parseString( "CDATA" );
+ break;
+ case TTI:
+ parseOk = parseString( "ID" );
+ break;
+ case TTI2:
+ parseOk = parseString( "REF" );
+ break;
+ case TTI3:
+ next(); // S
+ break;
+ case TTE:
+ parseOk = parseString( "ENTIT" );
+ break;
+ case TTEY:
+ next(); // Y
+ break;
+ case TTEI:
+ parseOk = parseString( "IES" );
+ break;
+ case N:
+ next(); // N
+ break;
+ case TTNM:
+ parseOk = parseString( "MTOKEN" );
+ break;
+ case TTNM2:
+ next(); // S
+ break;
+ case NO:
+ parseOk = parseString( "OTATION" );
+ break;
+ case NO2:
+ eat_ws();
+ break;
+ case NO3:
+ next_eat_ws();
+ break;
+ case NOName:
+ parseOk = parseName();
+ break;
+ case NO4:
+ eat_ws();
+ break;
+ case EN:
+ next_eat_ws();
+ break;
+ case ENNmt:
+ parseOk = parseNmtoken();
+ break;
+ case EN2:
+ eat_ws();
+ break;
+ case ADone:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case ST:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case TTI:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case TTI2:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case TTE:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case TTEI:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case TTNM:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case NO:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case NOName:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case ENNmt:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNMTOKEN;
+ goto parseError;
+ }
+ break;
+ case ADone:
+ return TRUE;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a AttValue [10]
+
+ Precondition: the head stands on the beginning " or '
+
+ If this function was successful, the head stands on the first
+ character after the closing " or ' and the value of the attribute
+ is in string().
+*/
+bool QXmlSimpleReader::parseAttValue()
+{
+ bool tmp;
+
+ const signed char Init = 0;
+ const signed char Dq = 1; // double quotes were read
+ const signed char DqRef = 2; // read references in double quotes
+ const signed char DqC = 3; // signed character read in double quotes
+ const signed char Sq = 4; // single quotes were read
+ const signed char SqRef = 5; // read references in single quotes
+ const signed char SqC = 6; // signed character read in single quotes
+ const signed char Done = 7;
+
+ const signed char InpDq = 0; // "
+ const signed char InpSq = 1; // '
+ const signed char InpAmp = 2; // &
+ const signed char InpLt = 3; // <
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static const signed char table[7][5] = {
+ /* InpDq InpSq InpAmp InpLt InpUnknown */
+ { Dq, Sq, -1, -1, -1 }, // Init
+ { Done, DqC, DqRef, -1, DqC }, // Dq
+ { Done, DqC, DqRef, -1, DqC }, // DqRef
+ { Done, DqC, DqRef, -1, DqC }, // DqC
+ { SqC, Done, SqRef, -1, SqC }, // Sq
+ { SqC, Done, SqRef, -1, SqC }, // SqRef
+ { SqC, Done, SqRef, -1, SqC } // SqRef
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == '"' ) {
+ input = InpDq;
+ } else if ( c == '\'' ) {
+ input = InpSq;
+ } else if ( c == '&' ) {
+ input = InpAmp;
+ } else if ( c == '<' ) {
+ input = InpLt;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Dq:
+ case Sq:
+ stringClear();
+ next();
+ break;
+ case DqRef:
+ case SqRef:
+ parseOk = parseReference( tmp, InAttributeValue );
+ break;
+ case DqC:
+ case SqC:
+ stringAddC();
+ next();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case DqRef:
+ case SqRef:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a elementdecl [45].
+
+ Precondition: the beginning '<!E' is already read and the head
+ stands on the 'L' of '<!ELEMENT'
+*/
+bool QXmlSimpleReader::parseElementDecl()
+{
+ const signed char Init = 0;
+ const signed char Elem = 1; // parse the beginning string
+ const signed char Ws1 = 2; // whitespace required
+ const signed char Nam = 3; // parse Name
+ const signed char Ws2 = 4; // whitespace required
+ const signed char Empty = 5; // read EMPTY
+ const signed char Any = 6; // read ANY
+ const signed char Cont = 7; // read contentspec (except ANY or EMPTY)
+ const signed char Mix = 8; // read Mixed
+ const signed char Mix2 = 9; //
+ const signed char Mix3 = 10; //
+ const signed char MixN1 = 11; //
+ const signed char MixN2 = 12; //
+ const signed char MixN3 = 13; //
+ const signed char MixN4 = 14; //
+ const signed char Cp = 15; // parse cp
+ const signed char Cp2 = 16; //
+ const signed char WsD = 17; // eat whitespace before Done
+ const signed char Done = 18;
+
+ const signed char InpWs = 0;
+ const signed char InpGt = 1; // >
+ const signed char InpPipe = 2; // |
+ const signed char InpOp = 3; // (
+ const signed char InpCp = 4; // )
+ const signed char InpHash = 5; // #
+ const signed char InpQm = 6; // ?
+ const signed char InpAst = 7; // *
+ const signed char InpPlus = 8; // +
+ const signed char InpA = 9; // A
+ const signed char InpE = 10; // E
+ const signed char InpL = 11; // L
+ const signed char InpUnknown = 12;
+
+ // use some kind of state machine for parsing
+ static const signed char table[18][13] = {
+ /* InpWs InpGt InpPipe InpOp InpCp InpHash InpQm InpAst InpPlus InpA InpE InpL InpUnknown */
+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, Elem, -1 }, // Init
+ { Ws1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Elem
+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, Nam, Nam, Nam, Nam }, // Ws1
+ { Ws2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Nam
+ { -1, -1, -1, Cont, -1, -1, -1, -1, -1, Any, Empty, -1, -1 }, // Ws2
+ { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Empty
+ { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Any
+ { -1, -1, -1, Cp, Cp, Mix, -1, -1, -1, Cp, Cp, Cp, Cp }, // Cont
+ { Mix2, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix
+ { -1, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix2
+ { WsD, Done, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // Mix3
+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, MixN2, MixN2, MixN2, MixN2 }, // MixN1
+ { MixN3, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN2
+ { -1, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN3
+ { -1, -1, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // MixN4
+ { WsD, Done, -1, -1, -1, -1, Cp2, Cp2, Cp2, -1, -1, -1, -1 }, // Cp
+ { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Cp2
+ { -1, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // WsD
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // read input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == '|' ) {
+ input = InpPipe;
+ } else if ( c == '(' ) {
+ input = InpOp;
+ } else if ( c == ')' ) {
+ input = InpCp;
+ } else if ( c == '#' ) {
+ input = InpHash;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else if ( c == '*' ) {
+ input = InpAst;
+ } else if ( c == '+' ) {
+ input = InpPlus;
+ } else if ( c == 'A' ) {
+ input = InpA;
+ } else if ( c == 'E' ) {
+ input = InpE;
+ } else if ( c == 'L' ) {
+ input = InpL;
+ } else {
+ input = InpUnknown;
+ }
+ // get new state
+//qDebug( "%d -%d(%c)-> %d", state, input, c.latin1(), table[state][input] );
+ state = table[state][input];
+
+ // in some cases do special actions depending on state
+ switch ( state ) {
+ case Elem:
+ parseOk = parseString( "LEMENT" );
+ break;
+ case Ws1:
+ eat_ws();
+ break;
+ case Nam:
+ parseOk = parseName();
+ break;
+ case Ws2:
+ eat_ws();
+ break;
+ case Empty:
+ parseOk = parseString( "EMPTY" );
+ break;
+ case Any:
+ parseOk = parseString( "ANY" );
+ break;
+ case Cont:
+ next_eat_ws();
+ break;
+ case Mix:
+ parseOk = parseString( "#PCDATA" );
+ break;
+ case Mix2:
+ eat_ws();
+ break;
+ case Mix3:
+ next();
+ break;
+ case MixN1:
+ next_eat_ws();
+ break;
+ case MixN2:
+ parseOk = parseName();
+ break;
+ case MixN3:
+ eat_ws();
+ break;
+ case MixN4:
+ next();
+ break;
+ case Cp:
+ parseOk = parseChoiceSeq();
+ break;
+ case Cp2:
+ next();
+ break;
+ case WsD:
+ next_eat_ws();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Elem:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Nam:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case Empty:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Any:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Mix:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case MixN2:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case Cp:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCHOICE;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a NotationDecl [82].
+
+ Precondition: the beginning '<!' is already read and the head
+ stands on the 'N' of '<!NOTATION'
+*/
+bool QXmlSimpleReader::parseNotationDecl()
+{
+ const signed char Init = 0;
+ const signed char Not = 1; // read NOTATION
+ const signed char Ws1 = 2; // eat whitespaces
+ const signed char Nam = 3; // read Name
+ const signed char Ws2 = 4; // eat whitespaces
+ const signed char ExtID = 5; // parse ExternalID
+ const signed char Ws3 = 6; // eat whitespaces
+ const signed char Done = 7;
+
+ const signed char InpWs = 0;
+ const signed char InpGt = 1; // >
+ const signed char InpN = 2; // N
+ const signed char InpUnknown = 3;
+
+ // use some kind of state machine for parsing
+ static const signed char table[7][4] = {
+ /* InpWs InpGt InpN InpUnknown */
+ { -1, -1, Not, -1 }, // Init
+ { Ws1, -1, -1, -1 }, // Not
+ { -1, -1, Nam, Nam }, // Ws1
+ { Ws2, Done, -1, -1 }, // Nam
+ { -1, Done, ExtID, ExtID }, // Ws2
+ { Ws3, Done, -1, -1 }, // ExtID
+ { -1, Done, -1, -1 } // Ws3
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == 'N' ) {
+ input = InpN;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Not:
+ parseOk = parseString( "NOTATION" );
+ break;
+ case Ws1:
+ eat_ws();
+ break;
+ case Nam:
+ parseOk = parseName();
+ break;
+ case Ws2:
+ eat_ws();
+ break;
+ case ExtID:
+ parseOk = parseExternalID( TRUE );
+ break;
+ case Ws3:
+ eat_ws();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Not:
+ if ( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Nam:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case ExtID:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGEXTERNALID;
+ goto parseError;
+ }
+ // call the handler
+ if ( dtdHnd ) {
+ if ( !dtdHnd->notationDecl( name(), d->publicId, d->systemId ) ) {
+ d->error = dtdHnd->errorString();
+ goto parseError;
+ }
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse choice [49] or seq [50].
+
+ Precondition: the beginning '('S? is already read and the head
+ stands on the first non-whitespace character after it.
+*/
+bool QXmlSimpleReader::parseChoiceSeq()
+{
+ const signed char Init = 0;
+ const signed char Ws1 = 1; // eat whitespace
+ const signed char CS = 2; // choice or set
+ const signed char Ws2 = 3; // eat whitespace
+ const signed char More = 4; // more cp to read
+ const signed char Name = 5; // read name
+ const signed char Done = 6; //
+
+ const signed char InpWs = 0; // S
+ const signed char InpOp = 1; // (
+ const signed char InpCp = 2; // )
+ const signed char InpQm = 3; // ?
+ const signed char InpAst = 4; // *
+ const signed char InpPlus = 5; // +
+ const signed char InpPipe = 6; // |
+ const signed char InpComm = 7; // ,
+ const signed char InpUnknown = 8;
+
+ // use some kind of state machine for parsing
+ static const signed char table[6][9] = {
+ /* InpWs InpOp InpCp InpQm InpAst InpPlus InpPipe InpComm InpUnknown */
+ { -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // Init
+ { -1, CS, -1, -1, -1, -1, -1, -1, CS }, // Ws1
+ { Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 }, // CS
+ { -1, -1, Done, -1, -1, -1, More, More, -1 }, // Ws2
+ { -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // More (same as Init)
+ { Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 } // Name (same as CS)
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '(' ) {
+ input = InpOp;
+ } else if ( c == ')' ) {
+ input = InpCp;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else if ( c == '*' ) {
+ input = InpAst;
+ } else if ( c == '+' ) {
+ input = InpPlus;
+ } else if ( c == '|' ) {
+ input = InpPipe;
+ } else if ( c == ',' ) {
+ input = InpComm;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Ws1:
+ next_eat_ws();
+ break;
+ case CS:
+ parseOk = parseChoiceSeq();
+ break;
+ case Ws2:
+ next_eat_ws();
+ break;
+ case More:
+ next_eat_ws();
+ break;
+ case Name:
+ parseOk = parseName();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case CS:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCHOICE;
+ goto parseError;
+ }
+ break;
+ case Name:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a EntityDecl [70].
+
+ Precondition: the beginning '<!E' is already read and the head
+ stand on the 'N' of '<!ENTITY'
+*/
+bool QXmlSimpleReader::parseEntityDecl()
+{
+ const signed char Init = 0;
+ const signed char Ent = 1; // parse "ENTITY"
+ const signed char Ws1 = 2; // white space read
+ const signed char Name = 3; // parse name
+ const signed char Ws2 = 4; // white space read
+ const signed char EValue = 5; // parse entity value
+ const signed char ExtID = 6; // parse ExternalID
+ const signed char Ws3 = 7; // white space read
+ const signed char Ndata = 8; // parse "NDATA"
+ const signed char Ws4 = 9; // white space read
+ const signed char NNam = 10; // parse name
+ const signed char PEDec = 11; // parse PEDecl
+ const signed char Ws6 = 12; // white space read
+ const signed char PENam = 13; // parse name
+ const signed char Ws7 = 14; // white space read
+ const signed char PEVal = 15; // parse entity value
+ const signed char PEEID = 16; // parse ExternalID
+ const signed char WsE = 17; // white space read
+ const signed char EDDone = 19; // done, but also report an external, unparsed entity decl
+ const signed char Done = 18;
+
+ const signed char InpWs = 0; // white space
+ const signed char InpPer = 1; // %
+ const signed char InpQuot = 2; // " or '
+ const signed char InpGt = 3; // >
+ const signed char InpN = 4; // N
+ const signed char InpUnknown = 5;
+
+ // use some kind of state machine for parsing
+ static const signed char table[18][6] = {
+ /* InpWs InpPer InpQuot InpGt InpN InpUnknown */
+ { -1, -1, -1, -1, Ent, -1 }, // Init
+ { Ws1, -1, -1, -1, -1, -1 }, // Ent
+ { -1, PEDec, -1, -1, Name, Name }, // Ws1
+ { Ws2, -1, -1, -1, -1, -1 }, // Name
+ { -1, -1, EValue, -1, -1, ExtID }, // Ws2
+ { WsE, -1, -1, Done, -1, -1 }, // EValue
+ { Ws3, -1, -1, EDDone,-1, -1 }, // ExtID
+ { -1, -1, -1, EDDone,Ndata, -1 }, // Ws3
+ { Ws4, -1, -1, -1, -1, -1 }, // Ndata
+ { -1, -1, -1, -1, NNam, NNam }, // Ws4
+ { WsE, -1, -1, Done, -1, -1 }, // NNam
+ { Ws6, -1, -1, -1, -1, -1 }, // PEDec
+ { -1, -1, -1, -1, PENam, PENam }, // Ws6
+ { Ws7, -1, -1, -1, -1, -1 }, // PENam
+ { -1, -1, PEVal, -1, -1, PEEID }, // Ws7
+ { WsE, -1, -1, Done, -1, -1 }, // PEVal
+ { WsE, -1, -1, Done, -1, -1 }, // PEEID
+ { -1, -1, -1, Done, -1, -1 } // WsE
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '%' ) {
+ input = InpPer;
+ } else if ( c == '"' || c == '\'' ) {
+ input = InpQuot;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == 'N' ) {
+ input = InpN;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Ent:
+ parseOk = parseString( "NTITY" );
+ break;
+ case Ws1:
+ eat_ws();
+ break;
+ case Name:
+ parseOk = parseName();
+ break;
+ case Ws2:
+ eat_ws();
+ break;
+ case EValue:
+ parseOk = parseEntityValue();
+ break;
+ case ExtID:
+ parseOk = parseExternalID();
+ break;
+ case Ws3:
+ eat_ws();
+ break;
+ case Ndata:
+ parseOk = parseString( "NDATA" );
+ break;
+ case Ws4:
+ eat_ws();
+ break;
+ case NNam:
+ parseOk = parseName( TRUE );
+ break;
+ case PEDec:
+ next();
+ break;
+ case Ws6:
+ eat_ws();
+ break;
+ case PENam:
+ parseOk = parseName();
+ break;
+ case Ws7:
+ eat_ws();
+ break;
+ case PEVal:
+ parseOk = parseEntityValue();
+ break;
+ case PEEID:
+ parseOk = parseExternalID();
+ break;
+ case WsE:
+ eat_ws();
+ break;
+ case EDDone:
+ next();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Ent:
+ if ( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Name:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case EValue:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGENTITYVALUE;
+ goto parseError;
+ }
+ if ( !entityExist( name() ) ) {
+ d->entities.insert( name(), string() );
+ if ( declHnd ) {
+ if ( !declHnd->internalEntityDecl( name(), string() ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ break;
+ case ExtID:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGEXTERNALID;
+ goto parseError;
+ }
+ break;
+ case Ndata:
+ if ( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case NNam:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ if ( !entityExist( name() ) ) {
+ d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, ref() ) );
+ if ( dtdHnd ) {
+ if ( !dtdHnd->unparsedEntityDecl( name(), d->publicId, d->systemId, ref() ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ break;
+ case PENam:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case PEVal:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGENTITYVALUE;
+ goto parseError;
+ }
+ if ( !entityExist( name() ) ) {
+ d->parameterEntities.insert( name(), string() );
+ if ( declHnd ) {
+ if ( !declHnd->internalEntityDecl( QString("%")+name(), string() ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ break;
+ case PEEID:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGEXTERNALID;
+ goto parseError;
+ }
+ if ( !entityExist( name() ) ) {
+ d->externParameterEntities.insert( name(), QXmlSimpleReaderPrivate::ExternParameterEntity( d->publicId, d->systemId ) );
+ if ( declHnd ) {
+ if ( !declHnd->externalEntityDecl( QString("%")+name(), d->publicId, d->systemId ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ break;
+ case EDDone:
+ if ( !entityExist( name() ) ) {
+ d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, QString::null ) );
+ if ( declHnd ) {
+ if ( !declHnd->externalEntityDecl( name(), d->publicId, d->systemId ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ return TRUE;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a EntityValue [9]
+*/
+bool QXmlSimpleReader::parseEntityValue()
+{
+ bool tmp;
+
+ const signed char Init = 0;
+ const signed char Dq = 1; // EntityValue is double quoted
+ const signed char DqC = 2; // signed character
+ const signed char DqPER = 3; // PERefence
+ const signed char DqRef = 4; // Reference
+ const signed char Sq = 5; // EntityValue is double quoted
+ const signed char SqC = 6; // signed character
+ const signed char SqPER = 7; // PERefence
+ const signed char SqRef = 8; // Reference
+ const signed char Done = 9;
+
+ const signed char InpDq = 0; // "
+ const signed char InpSq = 1; // '
+ const signed char InpAmp = 2; // &
+ const signed char InpPer = 3; // %
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static const signed char table[9][5] = {
+ /* InpDq InpSq InpAmp InpPer InpUnknown */
+ { Dq, Sq, -1, -1, -1 }, // Init
+ { Done, DqC, DqRef, DqPER, DqC }, // Dq
+ { Done, DqC, DqRef, DqPER, DqC }, // DqC
+ { Done, DqC, DqRef, DqPER, DqC }, // DqPER
+ { Done, DqC, DqRef, DqPER, DqC }, // DqRef
+ { SqC, Done, SqRef, SqPER, SqC }, // Sq
+ { SqC, Done, SqRef, SqPER, SqC }, // SqC
+ { SqC, Done, SqRef, SqPER, SqC }, // SqPER
+ { SqC, Done, SqRef, SqPER, SqC } // SqRef
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == '"' ) {
+ input = InpDq;
+ } else if ( c == '\'' ) {
+ input = InpSq;
+ } else if ( c == '&' ) {
+ input = InpAmp;
+ } else if ( c == '%' ) {
+ input = InpPer;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Dq:
+ case Sq:
+ stringClear();
+ next();
+ break;
+ case DqC:
+ case SqC:
+ stringAddC();
+ next();
+ break;
+ case DqPER:
+ case SqPER:
+ parseOk = parsePEReference( InEntityValue );
+ break;
+ case DqRef:
+ case SqRef:
+ parseOk = parseReference( tmp, InEntityValue );
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case DqPER:
+ case SqPER:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ break;
+ case DqRef:
+ case SqRef:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a comment [15].
+
+ Precondition: the beginning '<!' of the comment is already read and the head
+ stands on the first '-' of '<!--'.
+
+ If this funktion was successful, the head-position is on the first
+ character after the comment.
+*/
+bool QXmlSimpleReader::parseComment()
+{
+ const signed char Init = 0;
+ const signed char Dash1 = 1; // the first dash was read
+ const signed char Dash2 = 2; // the second dash was read
+ const signed char Com = 3; // read comment
+ const signed char Com2 = 4; // read comment (help state)
+ const signed char ComE = 5; // finished reading comment
+ const signed char Done = 6;
+
+ const signed char InpDash = 0; // -
+ const signed char InpGt = 1; // >
+ const signed char InpUnknown = 2;
+
+ // use some kind of state machine for parsing
+ static const signed char table[6][3] = {
+ /* InpDash InpGt InpUnknown */
+ { Dash1, -1, -1 }, // Init
+ { Dash2, -1, -1 }, // Dash1
+ { Com2, Com, Com }, // Dash2
+ { Com2, Com, Com }, // Com
+ { ComE, Com, Com }, // Com2
+ { -1, Done, -1 } // ComE
+ };
+ signed char state = Init;
+ signed char input;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == '-' ) {
+ input = InpDash;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Dash1:
+ next();
+ break;
+ case Dash2:
+ next();
+ break;
+ case Com:
+ stringAddC();
+ next();
+ break;
+ case Com2:
+ next();
+ break;
+ case ComE:
+ next();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Dash2:
+ stringClear();
+ break;
+ case Com2:
+ // if next character is not a dash than don't skip it
+ if ( c != '-' ) {
+ stringAddC( '-' );
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_ERRORPARSINGCOMMENT;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a Attribute [41].
+
+ Precondition: the head stands on the first character of the name of the
+ attribute (i.e. all whitespaces are already parsed).
+
+ The head stand on the next character after the end quotes. The variable name
+ contains the name of the attribute and the variable string contains the value
+ of the attribute.
+*/
+bool QXmlSimpleReader::parseAttribute()
+{
+ const signed char Init = 0;
+ const signed char PName = 1; // parse name
+ const signed char Ws = 2; // eat ws
+ const signed char Eq = 3; // the '=' was read
+ const signed char Quotes = 4; // " or ' were read
+
+ const signed char InpNameBe = 0;
+ const signed char InpEq = 1; // =
+ const signed char InpDq = 2; // "
+ const signed char InpSq = 3; // '
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static const signed char table[4][5] = {
+ /* InpNameBe InpEq InpDq InpSq InpUnknown */
+ { PName, -1, -1, -1, -1 }, // Init
+ { -1, Eq, -1, -1, Ws }, // PName
+ { -1, Eq, -1, -1, -1 }, // Ws
+ { -1, -1, Quotes, Quotes, -1 } // Eq
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_NameBeginning(c) ) {
+ input = InpNameBe;
+ } else if ( c == '=' ) {
+ input = InpEq;
+ } else if ( c == '"' ) {
+ input = InpDq;
+ } else if ( c == '\'' ) {
+ input = InpSq;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case PName:
+ parseOk = parseName();
+ break;
+ case Ws:
+ eat_ws();
+ break;
+ case Eq:
+ next_eat_ws();
+ break;
+ case Quotes:
+ parseOk = parseAttValue();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case PName:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case Quotes:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGATTVALUE;
+ goto parseError;
+ }
+ // Done
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a Name [5] and store the name in name or ref (if useRef is TRUE).
+*/
+bool QXmlSimpleReader::parseName( bool useRef )
+{
+ const signed char Init = 0;
+ const signed char Name1 = 1; // parse first signed character of the name
+ const signed char Name = 2; // parse name
+ const signed char Done = 3;
+
+ const signed char InpNameBe = 0; // name beginning signed characters
+ const signed char InpNameCh = 1; // NameChar without InpNameBe
+ const signed char InpUnknown = 2;
+
+ // use some kind of state machine for parsing
+ static const signed char table[3][3] = {
+ /* InpNameBe InpNameCh InpUnknown */
+ { Name1, -1, -1 }, // Init
+ { Name, Name, Done }, // Name1
+ { Name, Name, Done } // Name
+ };
+ signed char state = Init;
+ signed char input;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_NameBeginning(c) ) {
+ input = InpNameBe;
+ } else if ( is_NameChar(c) ) {
+ input = InpNameCh;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Name1:
+ if ( useRef ) {
+ refClear();
+ refAddC();
+ } else {
+ nameClear();
+ nameAddC();
+ }
+ next();
+ break;
+ case Name:
+ if ( useRef ) {
+ refAddC();
+ } else {
+ nameAddC();
+ }
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a Nmtoken [7] and store the name in name.
+*/
+bool QXmlSimpleReader::parseNmtoken()
+{
+ const signed char Init = 0;
+ const signed char NameF = 1;
+ const signed char Name = 2;
+ const signed char Done = 3;
+
+ const signed char InpNameCh = 0; // NameChar without InpNameBe
+ const signed char InpUnknown = 1;
+
+ // use some kind of state machine for parsing
+ static const signed char table[3][2] = {
+ /* InpNameCh InpUnknown */
+ { NameF, -1 }, // Init
+ { Name, Done }, // NameF
+ { Name, Done } // Name
+ };
+ signed char state = Init;
+ signed char input;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_NameChar(c) ) {
+ input = InpNameCh;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case NameF:
+ nameClear();
+ nameAddC();
+ next();
+ break;
+ case Name:
+ nameAddC();
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a Reference [67].
+
+ charDataRead is set to TRUE if the reference must not be parsed. The
+ character(s) which the reference mapped to are appended to string. The
+ head stands on the first character after the reference.
+
+ charDataRead is set to FALSE if the reference must be parsed. The
+ charachter(s) which the reference mapped to are inserted at the reference
+ position. The head stands on the first character of the replacement).
+*/
+bool QXmlSimpleReader::parseReference( bool &charDataRead, EntityRecognitionContext context )
+{
+ // temporary variables
+ uint tmp;
+ bool ok;
+
+ const signed char Init = 0;
+ const signed char SRef = 1; // start of a reference
+ const signed char ChRef = 2; // parse CharRef
+ const signed char ChDec = 3; // parse CharRef decimal
+ const signed char ChHexS = 4; // start CharRef hexadecimal
+ const signed char ChHex = 5; // parse CharRef hexadecimal
+ const signed char Name = 6; // parse name
+ const signed char DoneD = 7; // done CharRef decimal
+ const signed char DoneH = 8; // done CharRef hexadecimal
+ const signed char DoneN = 9; // done EntityRef
+
+ const signed char InpAmp = 0; // &
+ const signed char InpSemi = 1; // ;
+ const signed char InpHash = 2; // #
+ const signed char InpX = 3; // x
+ const signed char InpNum = 4; // 0-9
+ const signed char InpHex = 5; // a-f A-F
+ const signed char InpUnknown = 6;
+
+ // use some kind of state machine for parsing
+ static const signed char table[8][7] = {
+ /* InpAmp InpSemi InpHash InpX InpNum InpHex InpUnknown */
+ { SRef, -1, -1, -1, -1, -1, -1 }, // Init
+ { -1, -1, ChRef, Name, Name, Name, Name }, // SRef
+ { -1, -1, -1, ChHexS, ChDec, -1, -1 }, // ChRef
+ { -1, DoneD, -1, -1, ChDec, -1, -1 }, // ChDec
+ { -1, -1, -1, -1, ChHex, ChHex, -1 }, // ChHexS
+ { -1, DoneH, -1, -1, ChHex, ChHex, -1 }, // ChHex
+ { -1, DoneN, -1, -1, -1, -1, -1 } // Name
+ };
+ signed char state = Init;
+ signed char input;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c.row() ) {
+ input = InpUnknown;
+ } else if ( c.cell() == '&' ) {
+ input = InpAmp;
+ } else if ( c.cell() == ';' ) {
+ input = InpSemi;
+ } else if ( c.cell() == '#' ) {
+ input = InpHash;
+ } else if ( c.cell() == 'x' ) {
+ input = InpX;
+ } else if ( '0' <= c.cell() && c.cell() <= '9' ) {
+ input = InpNum;
+ } else if ( 'a' <= c.cell() && c.cell() <= 'f' ) {
+ input = InpHex;
+ } else if ( 'A' <= c.cell() && c.cell() <= 'F' ) {
+ input = InpHex;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case SRef:
+ refClear();
+ next();
+ break;
+ case ChRef:
+ next();
+ break;
+ case ChDec:
+ refAddC();
+ next();
+ break;
+ case ChHexS:
+ next();
+ break;
+ case ChHex:
+ refAddC();
+ next();
+ break;
+ case Name:
+ // read the name into the ref
+ parseName( TRUE );
+ break;
+ case DoneD:
+ tmp = ref().toUInt( &ok, 10 );
+ if ( ok ) {
+ stringAddC( QChar(tmp) );
+ } else {
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+ charDataRead = TRUE;
+ next();
+ break;
+ case DoneH:
+ tmp = ref().toUInt( &ok, 16 );
+ if ( ok ) {
+ stringAddC( QChar(tmp) );
+ } else {
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+ charDataRead = TRUE;
+ next();
+ break;
+ case DoneN:
+ if ( !processReference( charDataRead, context ) )
+ goto parseError;
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case DoneD:
+ return TRUE;
+ case DoneH:
+ return TRUE;
+ case DoneN:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Helper function for parseReference()
+*/
+bool QXmlSimpleReader::processReference( bool &charDataRead, EntityRecognitionContext context )
+{
+ QString reference = ref();
+ if ( reference == "amp" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'm' ); stringAddC( 'p' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '&' );
+ }
+ charDataRead = TRUE;
+ } else if ( reference == "lt" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'l' ); stringAddC( 't' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '<' );
+ }
+ charDataRead = TRUE;
+ } else if ( reference == "gt" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'g' ); stringAddC( 't' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '>' );
+ }
+ charDataRead = TRUE;
+ } else if ( reference == "apos" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'p' ); stringAddC( 'o' ); stringAddC( 's' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '\'' );
+ }
+ charDataRead = TRUE;
+ } else if ( reference == "quot" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'q' ); stringAddC( 'u' ); stringAddC( 'o' ); stringAddC( 't' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '"' );
+ }
+ charDataRead = TRUE;
+ } else {
+ QMap<QString,QString>::Iterator it;
+ it = d->entities.find( reference );
+ if ( it != d->entities.end() ) {
+ // "Internal General"
+ switch ( context ) {
+ case InContent:
+ // Included
+ xmlRef = it.data() + xmlRef;
+ charDataRead = FALSE;
+ break;
+ case InAttributeValue:
+ // Included in literal
+ xmlRef = it.data().replace( QRegExp("\""), "&quot;" ).replace( QRegExp("'"), "&apos;" )
+ + xmlRef;
+ charDataRead = FALSE;
+ break;
+ case InEntityValue:
+ {
+ // Bypassed
+ stringAddC( '&' );
+ for ( int i=0; i<(int)reference.length(); i++ ) {
+ stringAddC( reference[i] );
+ }
+ stringAddC( ';');
+ charDataRead = TRUE;
+ }
+ break;
+ case InDTD:
+ // Forbidden
+ d->error = XMLERR_INTERNALGENERALENTITYINDTD;
+ charDataRead = FALSE;
+ break;
+ }
+ } else {
+ QMap<QString,QXmlSimpleReaderPrivate::ExternEntity>::Iterator itExtern;
+ itExtern = d->externEntities.find( reference );
+ if ( itExtern == d->externEntities.end() ) {
+ // entity not declared
+ // ### check this case for conformance
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' );
+ for ( int i=0; i<(int)reference.length(); i++ ) {
+ stringAddC( reference[i] );
+ }
+ stringAddC( ';');
+ charDataRead = TRUE;
+ } else {
+ if ( contentHnd ) {
+ if ( !contentHnd->skippedEntity( reference ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE; // error
+ }
+ }
+ }
+ } else if ( (*itExtern).notation.isNull() ) {
+ // "External Parsed General"
+ switch ( context ) {
+ case InContent:
+ // Included if validating
+ if ( contentHnd ) {
+ if ( !contentHnd->skippedEntity( reference ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE; // error
+ }
+ }
+ charDataRead = FALSE;
+ break;
+ case InAttributeValue:
+ // Forbidden
+ d->error = XMLERR_EXTERNALGENERALENTITYINAV;
+ charDataRead = FALSE;
+ break;
+ case InEntityValue:
+ {
+ // Bypassed
+ stringAddC( '&' );
+ for ( int i=0; i<(int)reference.length(); i++ ) {
+ stringAddC( reference[i] );
+ }
+ stringAddC( ';');
+ charDataRead = TRUE;
+ }
+ break;
+ case InDTD:
+ // Forbidden
+ d->error = XMLERR_EXTERNALGENERALENTITYINDTD;
+ charDataRead = FALSE;
+ break;
+ }
+ } else {
+ // "Unparsed"
+ // ### notify for "Occurs as Attribute Value" missing (but this is no refence, anyway)
+ // Forbidden
+ d->error = XMLERR_UNPARSEDENTITYREFERENCE;
+ charDataRead = FALSE;
+ return FALSE; // error
+ }
+ }
+ }
+ return TRUE; // no error
+}
+
+
+/*!
+ Parse over a simple string.
+
+ After the string was successfully parsed, the head is on the first
+ character after the string.
+*/
+bool QXmlSimpleReader::parseString( const QString& s )
+{
+ signed char Done = s.length();
+
+ const signed char InpCharExpected = 0; // the character that was expected
+ const signed char InpUnknown = 1;
+
+ signed char state = 0; // state in this function is the position in the string s
+ signed char input;
+
+ for (;;) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == s[(int)state] ) {
+ input = InpCharExpected;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ if ( input == InpCharExpected ) {
+ state++;
+ } else {
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ // do some actions according to state
+ next();
+ // no input is read after this
+ if ( state == Done ) {
+ return TRUE;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+
+/*!
+ Inits the data values.
+*/
+void QXmlSimpleReader::init( const QXmlInputSource& i )
+{
+ xml = i.data();
+ xmlLength = xml.length();
+ xmlRef = "";
+
+ d->externParameterEntities.clear();
+ d->parameterEntities.clear();
+ d->externEntities.clear();
+ d->entities.clear();
+
+ tags.clear();
+
+ d->doctype = "";
+ d->xmlVersion = "";
+ d->encoding = "";
+ d->standalone = QXmlSimpleReaderPrivate::Unknown;
+
+ lineNr = 0;
+ columnNr = -1;
+ pos = 0;
+ next();
+ d->error = XMLERR_OK;
+}
+
+/*!
+ Returns TRUE if a entity with the name \a e exists,
+ otherwise returns FALSE.
+*/
+bool QXmlSimpleReader::entityExist( const QString& e ) const
+{
+ if ( d->parameterEntities.find(e) == d->parameterEntities.end() &&
+ d->externParameterEntities.find(e) == d->externParameterEntities.end() ) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+void QXmlSimpleReader::reportParseError()
+{
+ if ( errorHnd )
+ errorHnd->fatalError( QXmlParseException( d->error, columnNr+1, lineNr+1 ) );
+}
+
+//US #endif //QT_NO_XML
diff --git a/qtcompat/xml/qxml.h b/qtcompat/xml/qxml.h
new file mode 100644
index 0000000..b772df9
--- a/dev/null
+++ b/qtcompat/xml/qxml.h
@@ -0,0 +1,674 @@
+/****************************************************************************
+** $Id$
+**
+** Definition of QXmlSimpleReader and related classes.
+**
+** Created : 000518
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the XML module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+/******************************************
+ * DOM support is disabled in QT 2.3.7 for sharp zaurus.
+ * Because of that we copied the code from 2.3.7 into qtcompat and enabled it
+ * there.
+ * Copyright (c) 2004 Ulf Schenk
+ *
+ * $Id$
+ ******************************************/
+
+#ifndef QXML_H
+#define QXML_H
+
+#include <qmodules.h>
+
+//US #if !defined(QT_MODULE_XML)
+//US #define QM_EXPORT
+//US #else
+#define QM_EXPORT Q_EXPORT
+//US #endif
+
+#ifndef QT_H
+#include <qtextstream.h>
+#include <qfile.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qvaluestack.h>
+#include <qmap.h>
+#endif // QT_H
+
+//US #ifndef QT_NO_XML
+
+class QXmlNamespaceSupport;
+class QXmlAttributes;
+class QXmlContentHandler;
+class QXmlDefaultHandler;
+class QXmlDTDHandler;
+class QXmlEntityResolver;
+class QXmlErrorHandler;
+class QXmlLexicalHandler;
+class QXmlDeclHandler;
+class QXmlInputSource;
+class QXmlLocator;
+class QXmlNamespaceSupport;
+class QXmlParseException;
+
+class QXmlReader;
+class QXmlSimpleReader;
+
+class QXmlSimpleReaderPrivate;
+class QXmlNamespaceSupportPrivate;
+class QXmlAttributesPrivate;
+class QXmlInputSourcePrivate;
+class QXmlParseExceptionPrivate;
+class QXmlLocatorPrivate;
+class QXmlDefaultHandlerPrivate;
+
+
+//
+// SAX Namespace Support
+//
+
+#if defined(Q_TEMPLATEDLL)
+// MOC_SKIP_BEGIN
+template class QM_EXPORT QMap<QString, QString>;
+template class QM_EXPORT QValueStack<QMap<QString, QString> >;
+template class QM_EXPORT QValueStack<QString>;
+// MOC_SKIP_END
+#endif
+
+class QM_EXPORT QXmlNamespaceSupport
+{
+public:
+ QXmlNamespaceSupport();
+ ~QXmlNamespaceSupport();
+
+ void setPrefix( const QString&, const QString& );
+
+ QString prefix( const QString& ) const;
+ QString uri( const QString& ) const;
+ void splitName( const QString&, QString&, QString& ) const;
+ void processName( const QString&, bool, QString&, QString& ) const;
+ QStringList prefixes() const;
+ QStringList prefixes( const QString& ) const;
+
+ void pushContext();
+ void popContext();
+ void reset();
+private:
+ QValueStack<QMap<QString, QString> > nsStack;
+ QMap<QString, QString> ns;
+
+ QXmlNamespaceSupportPrivate *d;
+};
+
+
+//
+// SAX Attributes
+//
+
+class QM_EXPORT QXmlAttributes
+{
+public:
+ QXmlAttributes() {}
+ virtual ~QXmlAttributes() {}
+
+ int index( const QString& qName ) const;
+ int index( const QString& uri, const QString& localPart ) const;
+ int length() const;
+ QString localName( int index ) const;
+ QString qName( int index ) const;
+ QString uri( int index ) const;
+ QString type( int index ) const;
+ QString type( const QString& qName ) const;
+ QString type( const QString& uri, const QString& localName ) const;
+ QString value( int index ) const;
+ QString value( const QString& qName ) const;
+ QString value( const QString& uri, const QString& localName ) const;
+
+private:
+ QStringList qnameList;
+ QStringList uriList;
+ QStringList localnameList;
+ QStringList valueList;
+
+ QXmlAttributesPrivate *d;
+
+ friend class QXmlSimpleReader;
+};
+
+//
+// SAX Input Source
+//
+
+class QM_EXPORT QXmlInputSource
+{
+public:
+ QXmlInputSource();
+ QXmlInputSource( QTextStream& stream );
+ QXmlInputSource( QFile& file );
+ virtual ~QXmlInputSource();
+
+ virtual const QString& data() const;
+ virtual void setData( const QString& d );
+
+private:
+ void readInput( QByteArray& rawData );
+
+ QString input;
+
+ QXmlInputSourcePrivate *d;
+};
+
+//
+// SAX Exception Classes
+//
+
+class QM_EXPORT QXmlParseException
+{
+public:
+ QXmlParseException( const QString& name="", int c=-1, int l=-1, const QString& p="", const QString& s="" )
+ : msg( name ), column( c ), line( l ), pub( p ), sys( s )
+ { }
+
+ int columnNumber() const;
+ int lineNumber() const;
+ QString publicId() const;
+ QString systemId() const;
+ QString message() const;
+
+private:
+ QString msg;
+ int column;
+ int line;
+ QString pub;
+ QString sys;
+
+ QXmlParseExceptionPrivate *d;
+};
+
+
+//
+// XML Reader
+//
+
+class QM_EXPORT QXmlReader
+{
+public:
+ virtual bool feature( const QString& name, bool *ok = 0 ) const = 0;
+ virtual void setFeature( const QString& name, bool value ) = 0;
+ virtual bool hasFeature( const QString& name ) const = 0;
+ virtual void* property( const QString& name, bool *ok = 0 ) const = 0;
+ virtual void setProperty( const QString& name, void* value ) = 0;
+ virtual bool hasProperty( const QString& name ) const = 0;
+ virtual void setEntityResolver( QXmlEntityResolver* handler ) = 0;
+ virtual QXmlEntityResolver* entityResolver() const = 0;
+ virtual void setDTDHandler( QXmlDTDHandler* handler ) = 0;
+ virtual QXmlDTDHandler* DTDHandler() const = 0;
+ virtual void setContentHandler( QXmlContentHandler* handler ) = 0;
+ virtual QXmlContentHandler* contentHandler() const = 0;
+ virtual void setErrorHandler( QXmlErrorHandler* handler ) = 0;
+ virtual QXmlErrorHandler* errorHandler() const = 0;
+ virtual void setLexicalHandler( QXmlLexicalHandler* handler ) = 0;
+ virtual QXmlLexicalHandler* lexicalHandler() const = 0;
+ virtual void setDeclHandler( QXmlDeclHandler* handler ) = 0;
+ virtual QXmlDeclHandler* declHandler() const = 0;
+ virtual bool parse( const QXmlInputSource& input ) = 0;
+};
+
+class QM_EXPORT QXmlSimpleReader : public QXmlReader
+{
+public:
+ QXmlSimpleReader();
+ virtual ~QXmlSimpleReader();
+
+ bool feature( const QString& name, bool *ok = 0 ) const;
+ void setFeature( const QString& name, bool value );
+ bool hasFeature( const QString& name ) const;
+
+ void* property( const QString& name, bool *ok = 0 ) const;
+ void setProperty( const QString& name, void* value );
+ bool hasProperty( const QString& name ) const;
+
+ void setEntityResolver( QXmlEntityResolver* handler );
+ QXmlEntityResolver* entityResolver() const;
+ void setDTDHandler( QXmlDTDHandler* handler );
+ QXmlDTDHandler* DTDHandler() const;
+ void setContentHandler( QXmlContentHandler* handler );
+ QXmlContentHandler* contentHandler() const;
+ void setErrorHandler( QXmlErrorHandler* handler );
+ QXmlErrorHandler* errorHandler() const;
+ void setLexicalHandler( QXmlLexicalHandler* handler );
+ QXmlLexicalHandler* lexicalHandler() const;
+ void setDeclHandler( QXmlDeclHandler* handler );
+ QXmlDeclHandler* declHandler() const;
+
+ bool parse( const QXmlInputSource& input );
+
+private:
+ // variables
+ QXmlContentHandler* contentHnd;
+ QXmlErrorHandler* errorHnd;
+ QXmlDTDHandler* dtdHnd;
+ QXmlEntityResolver* entityRes;
+ QXmlLexicalHandler* lexicalHnd;
+ QXmlDeclHandler* declHnd;
+
+ QChar c; // the character at reading position
+ int lineNr; // number of line
+ int columnNr; // position in line
+ int pos; // position in string
+
+ int namePos;
+ QChar nameArray[256]; // only used for names
+ QString nameValue; // only used for names
+ int refPos;
+ QChar refArray[256]; // only used for references
+ QString refValue; // only used for references
+ int stringPos;
+ QChar stringArray[256]; // used for any other strings that are parsed
+ QString stringValue; // used for any other strings that are parsed
+
+ QString xml;
+ int xmlLength;
+ QString xmlRef; // used for parsing of entity references
+
+ QValueStack<QString> tags;
+
+ QXmlSimpleReaderPrivate* d;
+
+ static const QChar QEOF;
+
+ // inlines
+ virtual bool is_S( const QChar& );
+ virtual bool is_Letter( const QChar& );
+ virtual bool is_NameBeginning( const QChar& );
+ virtual bool is_Digit( const QChar& );
+ virtual bool is_CombiningChar( const QChar& );
+ virtual bool is_Extender( const QChar& );
+ virtual bool is_NameChar( const QChar& );
+
+ QString& string();
+ void stringClear();
+ void stringAddC();
+ void stringAddC(const QChar&);
+ QString& name();
+ void nameClear();
+ void nameAddC();
+ void nameAddC(const QChar&);
+ QString& ref();
+ void refClear();
+ void refAddC();
+ void refAddC(const QChar&);
+
+ // used by parseReference() and parsePEReference()
+ enum EntityRecognitionContext { InContent, InAttributeValue, InEntityValue, InDTD };
+
+ // private functions
+ void eat_ws();
+ void next_eat_ws();
+
+ void next();
+ bool atEnd();
+
+ void init( const QXmlInputSource& i );
+
+ bool entityExist( const QString& ) const;
+
+ bool parseProlog();
+ bool parseElement();
+ bool parseElementEmptyTag( bool &t, QString &uri, QString &lname );
+ bool parseElementETagBegin2();
+ bool parseElementAttribute( QString &prefix, QString &uri, QString &lname );
+ bool parseMisc();
+ bool parseContent();
+
+ bool parsePI(bool xmldecl=FALSE);
+ bool parseDoctype();
+ bool parseComment();
+
+ bool parseName( bool useRef=FALSE );
+ bool parseNmtoken();
+ bool parseAttribute();
+ bool parseReference( bool &charDataRead, EntityRecognitionContext context );
+ bool processReference( bool &charDataRead, EntityRecognitionContext context );
+
+ bool parseExternalID( bool allowPublicID = FALSE );
+ bool parsePEReference( EntityRecognitionContext context );
+ bool parseMarkupdecl();
+ bool parseAttlistDecl();
+ bool parseAttType();
+ bool parseAttValue();
+ bool parseElementDecl();
+ bool parseNotationDecl();
+ bool parseChoiceSeq();
+ bool parseEntityDecl();
+ bool parseEntityValue();
+
+ bool parseString( const QString& s );
+
+ void reportParseError();
+
+ friend class QXmlSimpleReaderPrivate;
+ friend class QXmlLocator;
+};
+
+//
+// SAX Locator
+//
+
+class QM_EXPORT QXmlLocator
+{
+public:
+ QXmlLocator( QXmlSimpleReader* parent )
+ { reader = parent; }
+ ~QXmlLocator()
+ { }
+
+ int columnNumber();
+ int lineNumber();
+// QString getPublicId()
+// QString getSystemId()
+
+private:
+ QXmlSimpleReader* reader;
+
+ QXmlLocatorPrivate *d;
+};
+
+//
+// SAX handler classes
+//
+
+class QM_EXPORT QXmlContentHandler
+{
+public:
+ virtual void setDocumentLocator( QXmlLocator* locator ) = 0;
+ virtual bool startDocument() = 0;
+ virtual bool endDocument() = 0;
+ virtual bool startPrefixMapping( const QString& prefix, const QString& uri ) = 0;
+ virtual bool endPrefixMapping( const QString& prefix ) = 0;
+ virtual bool startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts ) = 0;
+ virtual bool endElement( const QString& namespaceURI, const QString& localName, const QString& qName ) = 0;
+ virtual bool characters( const QString& ch ) = 0;
+ virtual bool ignorableWhitespace( const QString& ch ) = 0;
+ virtual bool processingInstruction( const QString& target, const QString& data ) = 0;
+ virtual bool skippedEntity( const QString& name ) = 0;
+ virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlErrorHandler
+{
+public:
+ virtual bool warning( const QXmlParseException& exception ) = 0;
+ virtual bool error( const QXmlParseException& exception ) = 0;
+ virtual bool fatalError( const QXmlParseException& exception ) = 0;
+ virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlDTDHandler
+{
+public:
+ virtual bool notationDecl( const QString& name, const QString& publicId, const QString& systemId ) = 0;
+ virtual bool unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName ) = 0;
+ virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlEntityResolver
+{
+public:
+ virtual bool resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* ret ) = 0;
+ virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlLexicalHandler
+{
+public:
+ virtual bool startDTD( const QString& name, const QString& publicId, const QString& systemId ) = 0;
+ virtual bool endDTD() = 0;
+// virtual bool startEntity( const QString& name ) = 0;
+// virtual bool endEntity( const QString& name ) = 0;
+ virtual bool startCDATA() = 0;
+ virtual bool endCDATA() = 0;
+ virtual bool comment( const QString& ch ) = 0;
+ virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlDeclHandler
+{
+public:
+ virtual bool attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value ) = 0;
+ virtual bool internalEntityDecl( const QString& name, const QString& value ) = 0;
+ virtual bool externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId ) = 0;
+ virtual QString errorString() = 0;
+};
+
+
+class QM_EXPORT QXmlDefaultHandler : public QXmlContentHandler, public QXmlErrorHandler, public QXmlDTDHandler, public QXmlEntityResolver, public QXmlLexicalHandler, public QXmlDeclHandler
+{
+public:
+ QXmlDefaultHandler() { }
+ virtual ~QXmlDefaultHandler() { }
+
+ void setDocumentLocator( QXmlLocator* locator );
+ bool startDocument();
+ bool endDocument();
+ bool startPrefixMapping( const QString& prefix, const QString& uri );
+ bool endPrefixMapping( const QString& prefix );
+ bool startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts );
+ bool endElement( const QString& namespaceURI, const QString& localName, const QString& qName );
+ bool characters( const QString& ch );
+ bool ignorableWhitespace( const QString& ch );
+ bool processingInstruction( const QString& target, const QString& data );
+ bool skippedEntity( const QString& name );
+
+ bool warning( const QXmlParseException& exception );
+ bool error( const QXmlParseException& exception );
+ bool fatalError( const QXmlParseException& exception );
+
+ bool notationDecl( const QString& name, const QString& publicId, const QString& systemId );
+ bool unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName );
+
+ bool resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* ret );
+
+ bool startDTD( const QString& name, const QString& publicId, const QString& systemId );
+ bool endDTD();
+// bool startEntity( const QString& name );
+// bool endEntity( const QString& name );
+ bool startCDATA();
+ bool endCDATA();
+ bool comment( const QString& ch );
+
+ bool attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value );
+ bool internalEntityDecl( const QString& name, const QString& value );
+ bool externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId );
+
+ QString errorString();
+
+private:
+ QXmlDefaultHandlerPrivate *d;
+};
+
+#ifdef _WS_QWS_
+#ifdef QT_XML_CPP
+#define inline
+#else
+#define QT_NO_XML_INLINE
+#endif
+#endif
+
+#ifndef QT_NO_XML_INLINE
+//
+// inlines
+//
+
+inline bool QXmlSimpleReader::is_S(const QChar& ch)
+{ return ch==' ' || ch=='\t' || ch=='\n' || ch=='\r'; }
+
+inline bool QXmlSimpleReader::is_Letter( const QChar& ch )
+{ return ch.isLetter(); }
+
+inline bool QXmlSimpleReader::is_NameBeginning( const QChar& ch )
+{ return ch=='_' || ch==':' || ch.isLetter(); }
+
+inline bool QXmlSimpleReader::is_Digit( const QChar& ch )
+{ return ch.isDigit(); }
+
+inline bool QXmlSimpleReader::is_CombiningChar( const QChar& )
+{ return FALSE; }
+
+inline bool QXmlSimpleReader::is_Extender( const QChar& )
+{ return FALSE; }
+
+inline bool QXmlSimpleReader::is_NameChar( const QChar& ch )
+{
+ return ch=='.' || ch=='-' || ch=='_' || ch==':' ||
+ is_Letter(ch) || is_Digit(ch) ||
+ is_CombiningChar(ch) || is_Extender(ch);
+}
+
+inline void QXmlSimpleReader::next()
+{
+ if ( !xmlRef.isEmpty() ) {
+ c = xmlRef[0];
+ xmlRef.remove( 0, 1 );
+ } else {
+ if ( c=='\n' || c=='\r' ) {
+ lineNr++;
+ columnNr = -1;
+ }
+ if ( pos >= xmlLength ) {
+ c = QEOF;
+ } else {
+ c = xml[pos];
+ columnNr++;
+ pos++;
+ }
+ }
+}
+
+inline bool QXmlSimpleReader::atEnd()
+{ return c == QEOF; }
+
+inline void QXmlSimpleReader::eat_ws()
+{ while ( !atEnd() && is_S(c) ) next(); }
+
+inline void QXmlSimpleReader::next_eat_ws()
+{ next(); eat_ws(); }
+
+
+// use buffers instead of QString::operator+= when single characters are read
+inline QString& QXmlSimpleReader::string()
+{
+ stringValue += QString( stringArray, stringPos );
+ stringPos = 0;
+ return stringValue;
+}
+inline QString& QXmlSimpleReader::name()
+{
+ nameValue += QString( nameArray, namePos );
+ namePos = 0;
+ return nameValue;
+}
+inline QString& QXmlSimpleReader::ref()
+{
+ refValue += QString( refArray, refPos );
+ refPos = 0;
+ return refValue;
+}
+
+inline void QXmlSimpleReader::stringClear()
+{ stringValue = ""; stringPos = 0; }
+inline void QXmlSimpleReader::nameClear()
+{ nameValue = ""; namePos = 0; }
+inline void QXmlSimpleReader::refClear()
+{ refValue = ""; refPos = 0; }
+
+inline void QXmlSimpleReader::stringAddC()
+{
+ if ( stringPos >= 256 ) {
+ stringValue += QString( stringArray, stringPos );
+ stringPos = 0;
+ }
+ stringArray[stringPos++] = c;
+}
+inline void QXmlSimpleReader::nameAddC()
+{
+ if ( namePos >= 256 ) {
+ nameValue += QString( nameArray, namePos );
+ namePos = 0;
+ }
+ nameArray[namePos++] = c;
+}
+inline void QXmlSimpleReader::refAddC()
+{
+ if ( refPos >= 256 ) {
+ refValue += QString( refArray, refPos );
+ refPos = 0;
+ }
+ refArray[refPos++] = c;
+}
+
+inline void QXmlSimpleReader::stringAddC(const QChar& ch)
+{
+ if ( stringPos >= 256 ) {
+ stringValue += QString( stringArray, stringPos );
+ stringPos = 0;
+ }
+ stringArray[stringPos++] = ch;
+}
+inline void QXmlSimpleReader::nameAddC(const QChar& ch)
+{
+ if ( namePos >= 256 ) {
+ nameValue += QString( nameArray, namePos );
+ namePos = 0;
+ }
+ nameArray[namePos++] = ch;
+}
+inline void QXmlSimpleReader::refAddC(const QChar& ch)
+{
+ if ( refPos >= 256 ) {
+ refValue += QString( refArray, refPos );
+ refPos = 0;
+ }
+ refArray[refPos++] = ch;
+}
+#endif
+
+#ifdef _WS_QWS_
+#ifdef QT_XML_CPP
+#undef inline
+#endif
+#endif
+
+//US #endif //QT_NO_XML
+
+#endif