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

« back to all changes in this revision

Viewing changes to src/xml/sax/qxml.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 QtXml 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
****************************************************************************/
244
244
class QXmlParseExceptionPrivate
245
245
{
246
246
public:
 
247
    QXmlParseExceptionPrivate()
 
248
        : column(-1), line(-1)
 
249
    {
 
250
    }
 
251
    QXmlParseExceptionPrivate(const QXmlParseExceptionPrivate &other)
 
252
        : msg(other.msg), column(other.column), line(other.line),
 
253
          pub(other.pub), sys(other.sys)
 
254
    {
 
255
    }
 
256
 
247
257
    QString msg;
248
258
    int column;
249
259
    int line;
262
272
 
263
273
class QXmlSimpleReaderPrivate
264
274
{
 
275
public:
 
276
    ~QXmlSimpleReaderPrivate();
265
277
private:
266
278
    // functions
267
 
    QXmlSimpleReaderPrivate();
268
 
    ~QXmlSimpleReaderPrivate();
 
279
    QXmlSimpleReaderPrivate(QXmlSimpleReader *reader);
269
280
    void initIncrementalParsing();
270
281
 
271
282
    // used to determine if elements are correctly nested
302
313
 
303
314
    // used for parsing of entity references
304
315
    struct XmlRef {
305
 
        XmlRef(const QString &_name = QString(), const QString &_value = QString())
 
316
        XmlRef()
 
317
            : index(0) {}
 
318
        XmlRef(const QString &_name, const QString &_value)
306
319
            : name(_name), value(_value), index(0) {}
307
320
        bool isEmpty() const { return index == value.length(); }
308
321
        QChar next() { return value.at(index++); }
348
361
    bool contentCharDataRead;
349
362
 
350
363
    // helper classes
351
 
    QXmlLocator *locator;
 
364
    QScopedPointer<QXmlLocator> locator;
352
365
    QXmlNamespaceSupport namespaceSupport;
353
366
 
354
367
    // error string
543
556
 
544
557
QXmlParseException::QXmlParseException(const QString& name, int c, int l,
545
558
                                       const QString& p, const QString& s)
 
559
    : d(new QXmlParseExceptionPrivate)
546
560
{
547
 
    d = new QXmlParseExceptionPrivate;
548
561
    d->msg = name;
549
562
    d->column = c;
550
563
    d->line = l;
553
566
}
554
567
 
555
568
/*!
 
569
    Creates a copy of \a other.
 
570
*/
 
571
QXmlParseException::QXmlParseException(const QXmlParseException& other) :
 
572
     d(new QXmlParseExceptionPrivate(*other.d))
 
573
{
 
574
 
 
575
}
 
576
 
 
577
/*!
556
578
    Destroys the QXmlParseException.
557
579
*/
558
580
QXmlParseException::~QXmlParseException()
559
581
{
560
 
    delete d;
561
582
}
562
583
 
563
584
/*!
926
947
*/
927
948
void QXmlNamespaceSupport::reset()
928
949
{
 
950
    QXmlNamespaceSupportPrivate *newD = new QXmlNamespaceSupportPrivate;
929
951
    delete d;
930
 
    d = new QXmlNamespaceSupportPrivate;
 
952
    d = newD;
931
953
}
932
954
 
933
955
 
1258
1280
{
1259
1281
    d = new QXmlInputSourcePrivate;
1260
1282
 
1261
 
    d->inputDevice = 0;
1262
 
    d->inputStream = 0;
 
1283
    QT_TRY {
 
1284
        d->inputDevice = 0;
 
1285
        d->inputStream = 0;
1263
1286
 
1264
 
    setData(QString());
 
1287
        setData(QString());
1265
1288
#ifndef QT_NO_TEXTCODEC
1266
 
    d->encMapper = 0;
 
1289
        d->encMapper = 0;
1267
1290
#endif
1268
 
    d->nextReturnedEndOfData = true; // first call to next() will call fetchData()
 
1291
        d->nextReturnedEndOfData = true; // first call to next() will call fetchData()
1269
1292
 
1270
 
    d->encodingDeclBytes.clear();
1271
 
    d->encodingDeclChars.clear();
1272
 
    d->lookingForEncodingDecl = true;
 
1293
        d->encodingDeclBytes.clear();
 
1294
        d->encodingDeclChars.clear();
 
1295
        d->lookingForEncodingDecl = true;
 
1296
    } QT_CATCH(...) {
 
1297
        delete(d);
 
1298
        QT_RETHROW;
 
1299
    }
1273
1300
}
1274
1301
 
1275
1302
/*!
2403
2430
/*!
2404
2431
    \reimp
2405
2432
 
2406
 
    Does nothing.
 
2433
    This reimplementation does nothing.
2407
2434
*/
2408
2435
void QXmlDefaultHandler::setDocumentLocator(QXmlLocator*)
2409
2436
{
2412
2439
/*!
2413
2440
    \reimp
2414
2441
 
2415
 
    Does nothing.
 
2442
    This reimplementation does nothing.
2416
2443
*/
2417
2444
bool QXmlDefaultHandler::startDocument()
2418
2445
{
2422
2449
/*!
2423
2450
    \reimp
2424
2451
 
2425
 
    Does nothing.
 
2452
    This reimplementation does nothing.
2426
2453
*/
2427
2454
bool QXmlDefaultHandler::endDocument()
2428
2455
{
2432
2459
/*!
2433
2460
    \reimp
2434
2461
 
2435
 
    Does nothing.
 
2462
    This reimplementation does nothing.
2436
2463
*/
2437
2464
bool QXmlDefaultHandler::startPrefixMapping(const QString&, const QString&)
2438
2465
{
2442
2469
/*!
2443
2470
    \reimp
2444
2471
 
2445
 
    Does nothing.
 
2472
    This reimplementation does nothing.
2446
2473
*/
2447
2474
bool QXmlDefaultHandler::endPrefixMapping(const QString&)
2448
2475
{
2452
2479
/*!
2453
2480
    \reimp
2454
2481
 
2455
 
    Does nothing.
 
2482
    This reimplementation does nothing.
2456
2483
*/
2457
2484
bool QXmlDefaultHandler::startElement(const QString&, const QString&,
2458
2485
        const QString&, const QXmlAttributes&)
2463
2490
/*!
2464
2491
    \reimp
2465
2492
 
2466
 
    Does nothing.
 
2493
    This reimplementation does nothing.
2467
2494
*/
2468
2495
bool QXmlDefaultHandler::endElement(const QString&, const QString&,
2469
2496
        const QString&)
2474
2501
/*!
2475
2502
    \reimp
2476
2503
 
2477
 
    Does nothing.
 
2504
    This reimplementation does nothing.
2478
2505
*/
2479
2506
bool QXmlDefaultHandler::characters(const QString&)
2480
2507
{
2484
2511
/*!
2485
2512
    \reimp
2486
2513
 
2487
 
    Does nothing.
 
2514
    This reimplementation does nothing.
2488
2515
*/
2489
2516
bool QXmlDefaultHandler::ignorableWhitespace(const QString&)
2490
2517
{
2494
2521
/*!
2495
2522
    \reimp
2496
2523
 
2497
 
    Does nothing.
 
2524
    This reimplementation does nothing.
2498
2525
*/
2499
2526
bool QXmlDefaultHandler::processingInstruction(const QString&,
2500
2527
        const QString&)
2505
2532
/*!
2506
2533
    \reimp
2507
2534
 
2508
 
    Does nothing.
 
2535
    This reimplementation does nothing.
2509
2536
*/
2510
2537
bool QXmlDefaultHandler::skippedEntity(const QString&)
2511
2538
{
2515
2542
/*!
2516
2543
    \reimp
2517
2544
 
2518
 
    Does nothing.
 
2545
    This reimplementation does nothing.
2519
2546
*/
2520
2547
bool QXmlDefaultHandler::warning(const QXmlParseException&)
2521
2548
{
2525
2552
/*!
2526
2553
    \reimp
2527
2554
 
2528
 
    Does nothing.
 
2555
    This reimplementation does nothing.
2529
2556
*/
2530
2557
bool QXmlDefaultHandler::error(const QXmlParseException&)
2531
2558
{
2535
2562
/*!
2536
2563
    \reimp
2537
2564
 
2538
 
    Does nothing.
 
2565
    This reimplementation does nothing.
2539
2566
*/
2540
2567
bool QXmlDefaultHandler::fatalError(const QXmlParseException&)
2541
2568
{
2545
2572
/*!
2546
2573
    \reimp
2547
2574
 
2548
 
    Does nothing.
 
2575
    This reimplementation does nothing.
2549
2576
*/
2550
2577
bool QXmlDefaultHandler::notationDecl(const QString&, const QString&,
2551
2578
        const QString&)
2556
2583
/*!
2557
2584
    \reimp
2558
2585
 
2559
 
    Does nothing.
 
2586
    This reimplementation does nothing.
2560
2587
*/
2561
2588
bool QXmlDefaultHandler::unparsedEntityDecl(const QString&, const QString&,
2562
2589
        const QString&, const QString&)
2590
2617
/*!
2591
2618
    \reimp
2592
2619
 
2593
 
    Does nothing.
 
2620
    This reimplementation does nothing.
2594
2621
*/
2595
2622
bool QXmlDefaultHandler::startDTD(const QString&, const QString&, const QString&)
2596
2623
{
2600
2627
/*!
2601
2628
    \reimp
2602
2629
 
2603
 
    Does nothing.
 
2630
    This reimplementation does nothing.
2604
2631
*/
2605
2632
bool QXmlDefaultHandler::endDTD()
2606
2633
{
2610
2637
/*!
2611
2638
    \reimp
2612
2639
 
2613
 
    Does nothing.
 
2640
    This reimplementation does nothing.
2614
2641
*/
2615
2642
bool QXmlDefaultHandler::startEntity(const QString&)
2616
2643
{
2620
2647
/*!
2621
2648
    \reimp
2622
2649
 
2623
 
    Does nothing.
 
2650
    This reimplementation does nothing.
2624
2651
*/
2625
2652
bool QXmlDefaultHandler::endEntity(const QString&)
2626
2653
{
2630
2657
/*!
2631
2658
    \reimp
2632
2659
 
2633
 
    Does nothing.
 
2660
    This reimplementation does nothing.
2634
2661
*/
2635
2662
bool QXmlDefaultHandler::startCDATA()
2636
2663
{
2640
2667
/*!
2641
2668
    \reimp
2642
2669
 
2643
 
    Does nothing.
 
2670
    This reimplementation does nothing.
2644
2671
*/
2645
2672
bool QXmlDefaultHandler::endCDATA()
2646
2673
{
2650
2677
/*!
2651
2678
    \reimp
2652
2679
 
2653
 
    Does nothing.
 
2680
    This reimplementation does nothing.
2654
2681
*/
2655
2682
bool QXmlDefaultHandler::comment(const QString&)
2656
2683
{
2660
2687
/*!
2661
2688
    \reimp
2662
2689
 
2663
 
    Does nothing.
 
2690
    This reimplementation does nothing.
2664
2691
*/
2665
2692
bool QXmlDefaultHandler::attributeDecl(const QString&, const QString&, const QString&, const QString&, const QString&)
2666
2693
{
2670
2697
/*!
2671
2698
    \reimp
2672
2699
 
2673
 
    Does nothing.
 
2700
    This reimplementation does nothing.
2674
2701
*/
2675
2702
bool QXmlDefaultHandler::internalEntityDecl(const QString&, const QString&)
2676
2703
{
2680
2707
/*!
2681
2708
    \reimp
2682
2709
 
2683
 
    Does nothing.
 
2710
    This reimplementation does nothing.
2684
2711
*/
2685
2712
bool QXmlDefaultHandler::externalEntityDecl(const QString&, const QString&, const QString&)
2686
2713
{
2713
2740
    refValueLen = 0; refArrayPos = 0;
2714
2741
}
2715
2742
 
2716
 
QXmlSimpleReaderPrivate::QXmlSimpleReaderPrivate()
 
2743
QXmlSimpleReaderPrivate::QXmlSimpleReaderPrivate(QXmlSimpleReader *reader)
2717
2744
{
 
2745
    q_ptr = reader;
2718
2746
    parseStack = 0;
 
2747
 
 
2748
    locator.reset(new QXmlSimpleReaderLocator(reader));
 
2749
    entityRes  = 0;
 
2750
    dtdHnd     = 0;
 
2751
    contentHnd = 0;
 
2752
    errorHnd   = 0;
 
2753
    lexicalHnd = 0;
 
2754
    declHnd    = 0;
 
2755
 
 
2756
    // default feature settings
 
2757
    useNamespaces = true;
 
2758
    useNamespacePrefixes = false;
 
2759
    reportWhitespaceCharData = true;
 
2760
    reportEntities = false;
2719
2761
}
2720
2762
 
2721
2763
QXmlSimpleReaderPrivate::~QXmlSimpleReaderPrivate()
2725
2767
 
2726
2768
void QXmlSimpleReaderPrivate::initIncrementalParsing()
2727
2769
{
2728
 
    delete parseStack;
2729
 
    parseStack = new QStack<ParseState>;
 
2770
    if(parseStack)
 
2771
        parseStack->clear();
 
2772
    else
 
2773
        parseStack = new QStack<ParseState>;
2730
2774
}
2731
2775
 
2732
2776
/*********************************************
2968
3012
 
2969
3013
    \inmodule QtXml
2970
3014
    \ingroup xml-tools
2971
 
    \mainclass
 
3015
 
2972
3016
 
2973
3017
    This XML reader is suitable for a wide range of applications. It
2974
3018
    is able to parse well-formed XML and can report the namespaces of
3012
3056
    parse() to work incrementally, and making subsequent calls to the
3013
3057
    parseContinue() function, until all the data has been processed.
3014
3058
 
3015
 
    A common way to perform incremental parsing is to connect the
3016
 
    \c readyRead() signal of the input source to a slot, and handle the
3017
 
    incoming data there. For example, the following code shows how a
3018
 
    parser for \l{http://web.resource.org/rss/1.0/}{RSS feeds} can be
3019
 
    used to incrementally parse data that it receives from a QHttp
3020
 
    object:
3021
 
 
3022
 
    \snippet doc/src/snippets/xml/rsslisting/rsslisting.cpp 1
3023
 
 
 
3059
    A common way to perform incremental parsing is to connect the \c
 
3060
    readyRead() signal of a \l{QNetworkReply} {network reply} a slot,
 
3061
    and handle the incoming data there. See QNetworkAccessManager.
 
3062
    
3024
3063
    Aspects of the parsing behavior can be adapted using setFeature()
3025
 
    and setProperty(). For example, the following code could be used
3026
 
    to enable reporting of namespace prefixes to the content handler:
3027
 
 
 
3064
    and setProperty().
 
3065
    
3028
3066
    QXmlSimpleReader is not reentrant. If you want to use the class
3029
3067
    in threaded code, lock the code using QXmlSimpleReader with a
3030
3068
    locking mechanism, such as a QMutex.
3099
3137
 
3100
3138
*/
3101
3139
QXmlSimpleReader::QXmlSimpleReader()
 
3140
    : d_ptr(new QXmlSimpleReaderPrivate(this))
3102
3141
{
3103
 
    d_ptr = new QXmlSimpleReaderPrivate();
3104
 
    Q_D(QXmlSimpleReader);
3105
 
    d->q_ptr = this;
3106
 
 
3107
 
    d->locator = new QXmlSimpleReaderLocator(this);
3108
 
 
3109
 
    d->entityRes  = 0;
3110
 
    d->dtdHnd     = 0;
3111
 
    d->contentHnd = 0;
3112
 
    d->errorHnd   = 0;
3113
 
    d->lexicalHnd = 0;
3114
 
    d->declHnd    = 0;
3115
 
 
3116
 
    // default feature settings
3117
 
    d->useNamespaces = true;
3118
 
    d->useNamespacePrefixes = false;
3119
 
    d->reportWhitespaceCharData = true;
3120
 
    d->reportEntities = false;
3121
3142
}
3122
3143
 
3123
3144
/*!
3125
3146
*/
3126
3147
QXmlSimpleReader::~QXmlSimpleReader()
3127
3148
{
3128
 
    Q_D(QXmlSimpleReader);
3129
 
    delete d->locator;
3130
 
    delete d;
3131
3149
}
3132
3150
 
3133
3151
/*!
3137
3155
{
3138
3156
    const QXmlSimpleReaderPrivate *d = d_func();
3139
3157
 
3140
 
    // Qt5 ###: Change these strings to qtsoftware.com
 
3158
    // Qt5 ###: Change these strings to qt.nokia.com
3141
3159
    if (ok != 0)
3142
3160
        *ok = true;
3143
3161
    if (name == QLatin1String("http://xml.org/sax/features/namespaces")) {
3192
3210
void QXmlSimpleReader::setFeature(const QString& name, bool enable)
3193
3211
{
3194
3212
    Q_D(QXmlSimpleReader);
3195
 
    // Qt5 ###: Change these strings to qtsoftware.com
 
3213
    // Qt5 ###: Change these strings to qt.nokia.com
3196
3214
    if (name == QLatin1String("http://xml.org/sax/features/namespaces")) {
3197
3215
        d->useNamespaces = enable;
3198
3216
    } else if (name == QLatin1String("http://xml.org/sax/features/namespace-prefixes")) {
3210
3228
*/
3211
3229
bool QXmlSimpleReader::hasFeature(const QString& name) const
3212
3230
{
3213
 
    // Qt5 ###: Change these strings to qtsoftware.com
 
3231
    // Qt5 ###: Change these strings to qt.nokia.com
3214
3232
    if (name == QLatin1String("http://xml.org/sax/features/namespaces")
3215
3233
        || name == QLatin1String("http://xml.org/sax/features/namespace-prefixes")
3216
3234
        || name == QLatin1String("http://trolltech.com/xml/features/report-whitespace-only-CharData") // Shouldn't change in Qt 4
3410
3428
 
3411
3429
    // call the handler
3412
3430
    if (d->contentHnd) {
3413
 
        d->contentHnd->setDocumentLocator(d->locator);
 
3431
        d->contentHnd->setDocumentLocator(d->locator.data());
3414
3432
        if (!d->contentHnd->startDocument()) {
3415
3433
            d->reportParseError(d->contentHnd->errorString());
3416
3434
            d->tags.clear();
5464
5482
 
5465
5483
                    if (skipIt) {
5466
5484
                        if (contentHnd) {
5467
 
                            if (!contentHnd->skippedEntity(QString::fromLatin1("%") + ref())) {
 
5485
                            if (!contentHnd->skippedEntity(QLatin1Char('%') + ref())) {
5468
5486
                                reportParseError(contentHnd->errorString());
5469
5487
                                return false;
5470
5488
                            }
5476
5494
                                return false;
5477
5495
                        } else if (parsePEReference_context == InDTD) {
5478
5496
                            // Included as PE
5479
 
                            if (!insertXmlRef(QString::fromLatin1(" ")+xmlRefString+QString::fromLatin1(" "), ref(), false))
 
5497
                            if (!insertXmlRef(QLatin1Char(' ') + xmlRefString + QLatin1Char(' '), ref(), false))
5480
5498
                                return false;
5481
5499
                        }
5482
5500
                    }
6728
6746
                if ( !entityExist(name())) {
6729
6747
                    parameterEntities.insert(name(), string());
6730
6748
                    if (declHnd) {
6731
 
                        if (!declHnd->internalEntityDecl(QString::fromLatin1("%")+name(), string())) {
 
6749
                        if (!declHnd->internalEntityDecl(QLatin1Char('%') + name(), string())) {
6732
6750
                            reportParseError(declHnd->errorString());
6733
6751
                            return false;
6734
6752
                        }
6740
6758
                if ( !entityExist(name())) {
6741
6759
                    externParameterEntities.insert(name(), QXmlSimpleReaderPrivate::ExternParameterEntity(publicId, systemId));
6742
6760
                    if (declHnd) {
6743
 
                        if (!declHnd->externalEntityDecl(QString::fromLatin1("%")+name(), publicId, systemId)) {
 
6761
                        if (!declHnd->externalEntityDecl(QLatin1Char('%') + name(), publicId, systemId)) {
6744
6762
                            reportParseError(declHnd->errorString());
6745
6763
                            return false;
6746
6764
                        }
7864
7882
{
7865
7883
    if (inLiteral) {
7866
7884
        QString tmp = data;
7867
 
        xmlRefStack.push(XmlRef(name, tmp.replace(QLatin1String("\""),
7868
 
                            QLatin1String("&quot;")).replace(QLatin1String("'"), QLatin1String("&apos;"))));
 
7885
        xmlRefStack.push(XmlRef(name, tmp.replace(QLatin1Char('\"'),
 
7886
                            QLatin1String("&quot;")).replace(QLatin1Char('\''), QLatin1String("&apos;"))));
7869
7887
    } else {
7870
7888
        xmlRefStack.push(XmlRef(name, data));
7871
7889
    }