~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/corelib/xml/qxmlstream.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2009-11-02 18:30:08 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (15.2.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 88.
  • Revision ID: james.westby@ubuntu.com-20091102183008-b6a4gcs128mvfb3m
Tags: upstream-4.6.0~beta1
ImportĀ upstreamĀ versionĀ 4.6.0~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/****************************************************************************
2
2
**
3
3
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
 
4
** All rights reserved.
4
5
** Contact: Nokia Corporation (qt-info@nokia.com)
5
6
**
6
7
** This file is part of the QtCore module of the Qt Toolkit.
7
8
**
8
9
** $QT_BEGIN_LICENSE:LGPL$
9
 
** Commercial Usage
10
 
** Licensees holding valid Qt Commercial licenses may use this file in
11
 
** accordance with the Qt Commercial License Agreement provided with the
12
 
** Software or, alternatively, in accordance with the terms contained in
13
 
** a written agreement between you and Nokia.
 
10
** No Commercial Usage
 
11
** This file contains pre-release code and may not be distributed.
 
12
** You may use this file in accordance with the terms and conditions
 
13
** contained in the Technology Preview License Agreement accompanying
 
14
** this package.
14
15
**
15
16
** GNU Lesser General Public License Usage
16
17
** Alternatively, this file may be used under the terms of the GNU Lesser
20
21
** ensure the GNU Lesser General Public License version 2.1 requirements
21
22
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22
23
**
23
 
** In addition, as a special exception, Nokia gives you certain
24
 
** additional rights. These rights are described in the Nokia Qt LGPL
25
 
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26
 
** package.
27
 
**
28
 
** GNU General Public License Usage
29
 
** Alternatively, this file may be used under the terms of the GNU
30
 
** General Public License version 3.0 as published by the Free Software
31
 
** Foundation and appearing in the file LICENSE.GPL included in the
32
 
** packaging of this file.  Please review the following information to
33
 
** ensure the GNU General Public License version 3.0 requirements will be
34
 
** met: http://www.gnu.org/copyleft/gpl.html.
35
 
**
36
 
** If you are unsure which license is appropriate for your use, please
37
 
** contact the sales department at http://www.qtsoftware.com/contact.
 
24
** In addition, as a special exception, Nokia gives you certain additional
 
25
** rights.  These rights are described in the Nokia Qt LGPL Exception
 
26
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
27
**
 
28
** If you have questions regarding the use of this file, please contact
 
29
** Nokia at qt-info@nokia.com.
 
30
**
 
31
**
 
32
**
 
33
**
 
34
**
 
35
**
 
36
**
 
37
**
38
38
** $QT_END_LICENSE$
39
39
**
40
40
****************************************************************************/
52
52
 
53
53
#include "qxmlutils_p.h"
54
54
#include <qdebug.h>
55
 
#include <QFile>
 
55
#include <qfile.h>
56
56
#include <stdio.h>
57
57
#include <qtextcodec.h>
58
58
#include <qstack.h>
59
59
#include <qbuffer.h>
60
60
#ifndef QT_BOOTSTRAPPED
61
 
#include <QCoreApplication>
 
61
#include <qcoreapplication.h>
62
62
#else
63
63
// This specialization of Q_DECLARE_TR_FUNCTIONS is not in qcoreapplication.h,
64
64
// because that header depends on QObject being available, which is not the
129
129
*/
130
130
 
131
131
/*!
 
132
    \enum QXmlStreamReader::ReadElementTextBehaviour
 
133
 
 
134
    This enum specifies the different behaviours of readElementText().
 
135
 
 
136
    \value ErrorOnUnexpectedElement Raise an UnexpectedElementError and return
 
137
    what was read so far when a child element is encountered.
 
138
 
 
139
    \value IncludeChildElements Recursively include the text from child elements.
 
140
 
 
141
    \value SkipChildElements Skip child elements.
 
142
 
 
143
    \since 4.6
 
144
*/
 
145
 
 
146
/*!
132
147
    \enum QXmlStreamReader::Error
133
148
 
134
149
    This enum specifies different error cases
244
259
  \brief The QXmlStreamReader class provides a fast parser for reading
245
260
  well-formed XML via a simple streaming API.
246
261
 
247
 
  \mainclass
 
262
 
248
263
  \ingroup xml-tools
249
264
 
250
265
  QXmlStreamReader is a faster and more convenient replacement for
298
313
  error handling described.
299
314
 
300
315
  The \l{QXmlStream Bookmarks Example} illustrates how to use the
301
 
  recursive descent technique with a subclassed stream reader to read
302
 
  an XML bookmark file (XBEL).
 
316
  recursive descent technique to read an XML bookmark file (XBEL) with
 
317
  a stream reader.
303
318
 
304
319
  \section1 Namespaces
305
320
 
334
349
  from the PrematureEndOfDocumentError error and continues parsing the
335
350
  new data with the next call to readNext().
336
351
 
337
 
  For example, if you read data from the network using QHttp, you
338
 
  would connect its \l{QHttp::readyRead()}{readyRead()} signal to a
339
 
  custom slot. In this slot, you read all available data with
340
 
  \l{QHttp::readAll()}{readAll()} and pass it to the XML stream reader
341
 
  using addData(). Then you call your custom parsing function that
342
 
  reads the XML events from the reader.
 
352
  For example, if your application reads data from the network using a
 
353
  \l{QNetworkAccessManager} {network access manager}, you would issue
 
354
  a \l{QNetworkRequest} {network request} to the manager and receive a
 
355
  \l{QNetworkReply} {network reply} in return. Since a QNetworkReply
 
356
  is a QIODevice, you connect its \l{QNetworkReply::readyRead()}
 
357
  {readyRead()} signal to a custom slot, e.g. \c{slotReadyRead()} in
 
358
  the code snippet shown in the discussion for QNetworkAccessManager.
 
359
  In this slot, you read all available data with
 
360
  \l{QNetworkReply::readAll()} {readAll()} and pass it to the XML
 
361
  stream reader using addData(). Then you call your custom parsing
 
362
  function that reads the XML events from the reader.
343
363
 
344
364
  \section1 Performance and memory consumption
345
365
 
429
449
    Q_D(QXmlStreamReader);
430
450
    if (d->deleteDevice)
431
451
        delete d->device;
432
 
    delete d;
433
452
}
434
453
 
435
454
/*! \fn bool QXmlStreamReader::hasError() const
568
587
  returns true, hasError() returns true, and this function returns
569
588
  QXmlStreamReader::Invalid.
570
589
 
571
 
  The exception is when error() return PrematureEndOfDocumentError.
 
590
  The exception is when error() returns PrematureEndOfDocumentError.
572
591
  This error is reported when the end of an otherwise well-formed
573
592
  chunk of XML is reached, but the chunk doesn't represent a complete
574
593
  XML document.  In that case, parsing \e can be resumed by calling
617
636
    return d->type;
618
637
}
619
638
 
 
639
/*!
 
640
  Reads until the next start element within the current element. Returns true
 
641
  when a start element was reached. When the end element was reached, or when
 
642
  an error occurred, false is returned.
 
643
 
 
644
  The current element is the element matching the most recently parsed start
 
645
  element of which a matching end element has not yet been reached. When the
 
646
  parser has reached the end element, the current element becomes the parent
 
647
  element.
 
648
 
 
649
  This is a convenience function for when you're only concerned with parsing
 
650
  XML elements. The \l{QXmlStream Bookmarks Example} makes extensive use of
 
651
  this function.
 
652
 
 
653
  \since 4.6
 
654
  \sa readNext()
 
655
 */
 
656
bool QXmlStreamReader::readNextStartElement()
 
657
{
 
658
    while (readNext() != Invalid) {
 
659
        if (isEndElement())
 
660
            return false;
 
661
        else if (isStartElement())
 
662
            return true;
 
663
    }
 
664
    return false;
 
665
}
 
666
 
 
667
/*!
 
668
  Reads until the end of the current element, skipping any child nodes.
 
669
  This function is useful for skipping unknown elements.
 
670
 
 
671
  The current element is the element matching the most recently parsed start
 
672
  element of which a matching end element has not yet been reached. When the
 
673
  parser has reached the end element, the current element becomes the parent
 
674
  element.
 
675
 
 
676
  \since 4.6
 
677
 */
 
678
void QXmlStreamReader::skipCurrentElement()
 
679
{
 
680
    int depth = 1;
 
681
    while (depth && readNext() != Invalid) {
 
682
        if (isEndElement())
 
683
            --depth;
 
684
        else if (isStartElement())
 
685
            ++depth;
 
686
    }
 
687
}
 
688
 
620
689
/*
621
690
 * Use the following Perl script to generate the error string index list:
622
691
===== PERL SCRIPT ====
629
698
    $sizes[$i++] = $counter;
630
699
    $counter += length 1 + $_;
631
700
}
632
 
print "    \"\\0\";\n\nstatic const int QXmlStreamReader_tokenTypeString_indices[] = {\n    ";
 
701
print "    \"\\0\";\n\nstatic const short QXmlStreamReader_tokenTypeString_indices[] = {\n    ";
633
702
for ($j = 0; $j < $i; ++$j) {
634
703
    printf "$sizes[$j], ";
635
704
}
660
729
    "Comment\0"
661
730
    "DTD\0"
662
731
    "EntityReference\0"
663
 
    "ProcessingInstruction\0"
664
 
    "\0";
 
732
    "ProcessingInstruction\0";
665
733
 
666
 
static const int QXmlStreamReader_tokenTypeString_indices[] = {
 
734
static const short QXmlStreamReader_tokenTypeString_indices[] = {
667
735
    0, 8, 16, 30, 42, 55, 66, 77, 85, 89, 105, 0
668
736
};
669
737
 
819
887
{
820
888
    stack_size <<= 1;
821
889
    sym_stack = reinterpret_cast<Value*> (qRealloc(sym_stack, stack_size * sizeof(Value)));
 
890
    Q_CHECK_PTR(sym_stack);
822
891
    state_stack = reinterpret_cast<int*> (qRealloc(state_stack, stack_size * sizeof(int)));
 
892
    Q_CHECK_PTR(sym_stack);
823
893
}
824
894
 
825
895
 
2017
2087
 
2018
2088
  The function concatenates text() when it reads either \l Characters
2019
2089
  or EntityReference tokens, but skips ProcessingInstruction and \l
2020
 
  Comment. In case anything else is read before reaching EndElement,
2021
 
  the function returns what it read so far and raises an
2022
 
  UnexpectedElementError. If the current token is not StartElement, an
2023
 
  empty string is returned.
 
2090
  Comment. If the current token is not StartElement, an empty string is
 
2091
  returned.
 
2092
 
 
2093
  The \a behaviour defines what happens in case anything else is
 
2094
  read before reaching EndElement. The function can include the text from
 
2095
  child elements (useful for example for HTML), ignore child elements, or
 
2096
  raise an UnexpectedElementError and return what was read so far.
 
2097
 
 
2098
  \since 4.6
2024
2099
 */
2025
 
QString QXmlStreamReader::readElementText()
 
2100
QString QXmlStreamReader::readElementText(ReadElementTextBehaviour behaviour)
2026
2101
{
2027
2102
    Q_D(QXmlStreamReader);
2028
2103
    if (isStartElement()) {
2038
2113
            case ProcessingInstruction:
2039
2114
            case Comment:
2040
2115
                break;
 
2116
            case StartElement:
 
2117
                if (behaviour == SkipChildElements) {
 
2118
                    skipCurrentElement();
 
2119
                    break;
 
2120
                } else if (behaviour == IncludeChildElements) {
 
2121
                    result += readElementText(behaviour);
 
2122
                    break;
 
2123
                }
 
2124
                // Fall through (for ErrorOnUnexpectedElement)
2041
2125
            default:
2042
 
                if (!d->error)
2043
 
                    d->raiseError(UnexpectedElementError, QXmlStream::tr("Expected character data."));
2044
 
                return result;
 
2126
                if (d->error || behaviour == ErrorOnUnexpectedElement) {
 
2127
                    if (!d->error)
 
2128
                        d->raiseError(UnexpectedElementError, QXmlStream::tr("Expected character data."));
 
2129
                    return result;
 
2130
                }
2045
2131
            }
2046
2132
        }
2047
2133
    }
2048
2134
    return QString();
2049
2135
}
2050
2136
 
 
2137
/*!
 
2138
  \overload readElementText()
 
2139
 
 
2140
  Calling this function is equivalent to calling readElementText(ErrorOnUnexpectedElement).
 
2141
 */
 
2142
QString QXmlStreamReader::readElementText()
 
2143
{
 
2144
    return readElementText(ErrorOnUnexpectedElement);
 
2145
}
 
2146
 
2051
2147
/*!  Raises a custom error with an optional error \a message.
2052
2148
 
2053
2149
  \sa error(), errorString()
2788
2884
  \brief The QXmlStreamWriter class provides an XML writer with a
2789
2885
  simple streaming API.
2790
2886
 
2791
 
  \mainclass
 
2887
 
2792
2888
  \inmodule QtXml
2793
2889
  \ingroup xml-tools
2794
2890
 
2848
2944
  encodings can be enforced using setCodec().
2849
2945
 
2850
2946
  The \l{QXmlStream Bookmarks Example} illustrates how to use a
2851
 
  subclassed stream writer to write an XML bookmark file (XBEL) that
 
2947
  stream writer to write an XML bookmark file (XBEL) that
2852
2948
  was previously read in by a QXmlStreamReader.
2853
2949
 
2854
2950
*/
3058
3154
        QString s;
3059
3155
        int n = ++namespacePrefixCount;
3060
3156
        forever {
3061
 
            s = QLatin1String("n") + QString::number(n++);
 
3157
            s = QLatin1Char('n') + QString::number(n++);
3062
3158
            int j = namespaceDeclarations.size() - 2;
3063
3159
            while (j >= 0 && namespaceDeclarations.at(j).prefix != s)
3064
3160
                --j;
3131
3227
*/
3132
3228
QXmlStreamWriter::~QXmlStreamWriter()
3133
3229
{
3134
 
    Q_D(QXmlStreamWriter);
3135
 
    delete d;
3136
3230
}
3137
3231
 
3138
3232
 
3411
3505
{
3412
3506
    Q_D(QXmlStreamWriter);
3413
3507
    Q_ASSERT(!text.contains(QLatin1String("--")) && !text.endsWith(QLatin1Char('-')));
3414
 
    if (!d->finishStartElement() && d->autoFormatting)
 
3508
    if (!d->finishStartElement(false) && d->autoFormatting)
3415
3509
        d->indent(d->tagStack.size());
3416
3510
    d->write("<!--");
3417
3511
    d->write(text);
3418
3512
    d->write("-->");
 
3513
    d->inStartElement = d->lastWasStartElement = false;
3419
3514
}
3420
3515
 
3421
3516