18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/**
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This file is part of the DOM implementation for KDE.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2000 Peter Kelly (pmk@post.com)
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2005, 2006 Apple Computer, Inc.
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02111-1307, USA.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "XMLTokenizer.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CDATASection.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CachedScript.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Comment.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CString.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DocLoader.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DocumentFragment.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoader.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameView.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLScriptElement.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLTableSectionElement.h"
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLTokenizer.h"
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ProcessingInstruction.h"
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EventNames.h"
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// strndup is not available everywhere, so here is a portable version <reed>
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic char* portable_strndup(const char src[], size_t len)
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char* origDst = (char*)malloc(len + 1);
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (NULL == origDst)
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NULL;
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char* dst = origDst;
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (len-- > 0) {
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if ((*dst++ = *src++) == 0)
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return origDst;
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *dst = 0;
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return origDst;
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace EventNames;
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames;
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int maxErrors = 25;
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectclass PendingCallbacks {
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpublic:
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PendingCallbacks() {
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_callbacks.setAutoDelete(true);
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void appendStartElementNSCallback(const XML_Char* name, const XML_Char** atts) {
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PendingStartElementNSCallback* callback = new PendingStartElementNSCallback;
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callback->name = strdup(name);
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callback->count = 0;
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (atts[callback->count])
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            callback->count++;
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callback->atts = (XML_Char**)malloc(sizeof(XML_Char*) * (callback->count+1));
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (int i=0; i<callback->count; i++)
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            callback->atts[i] = strdup(atts[i]);
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callback->atts[callback->count] = NULL;
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_callbacks.append(callback);
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void appendEndElementNSCallback() {
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PendingEndElementNSCallback* callback = new PendingEndElementNSCallback;
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_callbacks.append(callback);
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void appendCharactersCallback(const XML_Char* s, int len) {
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PendingCharactersCallback* callback = new PendingCharactersCallback;
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callback->s = portable_strndup(s, len);
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callback->len = len;
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_callbacks.append(callback);
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void appendProcessingInstructionCallback(const XML_Char* target, const XML_Char* data) {
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PendingProcessingInstructionCallback* callback = new PendingProcessingInstructionCallback;
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callback->target = strdup(target);
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callback->data = strdup(data);
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_callbacks.append(callback);
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void appendStartCDATABlockCallback() {
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PendingStartCDATABlockCallback* callback = new PendingStartCDATABlockCallback;
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_callbacks.append(callback);
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void appendEndCDATABlockCallback() {
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PendingEndCDATABlockCallback* callback = new PendingEndCDATABlockCallback;
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_callbacks.append(callback);
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void appendCommentCallback(const XML_Char* s) {
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PendingCommentCallback* callback = new PendingCommentCallback;
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callback->s = strdup(s);
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_callbacks.append(callback);
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void appendErrorCallback(XMLTokenizer::ErrorType type, const char* message, int lineNumber, int columnNumber) {
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PendingErrorCallback* callback = new PendingErrorCallback;
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callback->message = strdup(message);
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callback->type = type;
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callback->lineNumber = lineNumber;
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callback->columnNumber = columnNumber;
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_callbacks.append(callback);
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void callAndRemoveFirstCallback(XMLTokenizer* tokenizer) {
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PendingCallback* cb = m_callbacks.getFirst();
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cb->call(tokenizer);
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_callbacks.removeFirst();
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool isEmpty() const { return m_callbacks.isEmpty(); }
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectprivate:
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct PendingCallback {
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        virtual ~PendingCallback() { }
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        virtual void call(XMLTokenizer* tokenizer) = 0;
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct PendingStartElementNSCallback : public PendingCallback {
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        virtual ~PendingStartElementNSCallback() {
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            free(name);
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (int i=0; i<count; i++)
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                free(atts[i]);
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            free(atts);
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        virtual void call(XMLTokenizer* tokenizer) {
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tokenizer->startElementNs(name, (const XML_Char**)(atts));
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_Char* name;
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int count;
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_Char** atts;
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct PendingEndElementNSCallback : public PendingCallback {
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        virtual void call(XMLTokenizer* tokenizer) {
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tokenizer->endElementNs();
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct PendingCharactersCallback : public PendingCallback {
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        virtual ~PendingCharactersCallback() {
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            free(s);
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        virtual void call(XMLTokenizer* tokenizer) {
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tokenizer->characters(s, len);
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_Char* s;
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int len;
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct PendingProcessingInstructionCallback : public PendingCallback {
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        virtual ~PendingProcessingInstructionCallback() {
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            free(target);
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            free(data);
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        virtual void call(XMLTokenizer* tokenizer) {
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tokenizer->processingInstruction(target, data);
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_Char* target;
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_Char* data;
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct PendingStartCDATABlockCallback : public PendingCallback {
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        virtual void call(XMLTokenizer* tokenizer) {
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tokenizer->startCdata();
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct PendingEndCDATABlockCallback : public PendingCallback {
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        virtual void call(XMLTokenizer* tokenizer) {
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tokenizer->endCdata();
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct PendingCommentCallback : public PendingCallback {
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        virtual ~PendingCommentCallback() {
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            free(s);
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        virtual void call(XMLTokenizer* tokenizer) {
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tokenizer->comment(s);
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_Char* s;
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    struct PendingErrorCallback: public PendingCallback {
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        virtual ~PendingErrorCallback() {
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            free (message);
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        virtual void call(XMLTokenizer* tokenizer) {
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tokenizer->error(type, message, lineNumber, columnNumber);
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XMLTokenizer::ErrorType type;
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char* message;
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int lineNumber;
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int columnNumber;
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpublic:
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    DeprecatedPtrList<PendingCallback> m_callbacks;
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// --------------------------------
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectXMLTokenizer::XMLTokenizer(Document *_doc, FrameView *_view)
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : m_doc(_doc)
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_view(_view)
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_parser(0)
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_currentNode(_doc)
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_currentNodeIsReferenced(false)
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_sawError(false)
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_sawXSLTransform(false)
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_sawFirstElement(false)
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_parserPaused(false)
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_requestingScript(false)
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_finishCalled(false)
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_errorCount(0)
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_pendingScript(0)
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_scriptStartLine(0)
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_parsingFragment(false)
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_pendingCallbacks(new PendingCallbacks)
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectXMLTokenizer::XMLTokenizer(DocumentFragment *fragment, Element *parentElement)
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : m_doc(fragment->document())
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_view(0)
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_parser(0)
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_currentNode(fragment)
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_currentNodeIsReferenced(fragment)
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_sawError(false)
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_sawXSLTransform(false)
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_sawFirstElement(false)
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_parserPaused(false)
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_requestingScript(false)
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_finishCalled(false)
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_errorCount(0)
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_pendingScript(0)
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_scriptStartLine(0)
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_parsingFragment(true)
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_pendingCallbacks(new PendingCallbacks)
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (fragment)
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        fragment->ref();
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_doc)
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_doc->ref();
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Add namespaces based on the parent node
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<Element*> elemStack;
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (parentElement) {
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        elemStack.append(parentElement);
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* n = parentElement->parentNode();
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!n || !n->isElementNode())
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        parentElement = static_cast<Element*>(n);
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (elemStack.isEmpty())
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Element* element = elemStack.last(); !elemStack.isEmpty(); elemStack.removeLast()) {
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (NamedAttrMap* attrs = element->attributes()) {
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (unsigned i = 0; i < attrs->length(); i++) {
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                Attribute* attr = attrs->attributeItem(i);
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (attr->localName() == "xmlns")
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    m_defaultNamespaceURI = attr->value();
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else if (attr->prefix() == "xmlns")
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    m_prefixToNamespaceMap.set(attr->localName(), attr->value());
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectXMLTokenizer::~XMLTokenizer()
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setCurrentNode(0);
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parsingFragment && m_doc)
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_doc->deref();
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_pendingScript)
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_pendingScript->deref(this);
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::setCurrentNode(Node* n)
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool nodeNeedsReference = n && n != m_doc;
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (nodeNeedsReference)
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        n->ref();
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_currentNodeIsReferenced)
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_currentNode->deref();
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_currentNode = n;
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_currentNodeIsReferenced = nodeNeedsReference;
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// use space instead of ':' as separator because ':' can be inside an uri
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst XML_Char tripletSep=' ';
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectinline DeprecatedString toQString(const XML_Char* str, unsigned int len)
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return DeprecatedString::fromUtf8(reinterpret_cast<const char *>(str), len);
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectinline DeprecatedString toQString(const XML_Char* str)
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return DeprecatedString::fromUtf8(str ? reinterpret_cast<const char *>(str) : "");
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// triplet is formatted as URI + sep + local_name + sep + prefix.
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline void splitTriplet(const XML_Char *name, String &uri, String &localname, String &prefix)
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String string[3];
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int found = 0;
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const char *start = reinterpret_cast<const char *>(name);
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while(start && (found < 3)) {
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char *next = strchr(start, tripletSep);
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (next) {
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            string[found++] = toQString(start, (next-start));
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            start = next+1;
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            string[found++] = toQString(start);
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch(found) {
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    case 1:
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        localname = string[0];
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        break;
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    case 2:
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        uri = string[0];
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        localname = string[1];
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        break;
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    case 3:
3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        uri = string[0];
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        localname = string[1];
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        prefix = string[2];
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        break;
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline void handleElementNamespaces(Element *newElement, const String &uri, const String &prefix, ExceptionCode &exceptioncode)
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (uri.isEmpty())
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String namespaceQName("xmlns");
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if(!prefix.isEmpty())
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        namespaceQName += String(":")+ prefix;
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    newElement->setAttributeNS(String("http://www.w3.org/2000/xmlns/"), namespaceQName, uri, exceptioncode);
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline void handleElementAttributes(Element *newElement, const XML_Char **atts, ExceptionCode &exceptioncode)
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = 0; atts[i]; i += 2) {
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String attrURI, attrLocalName, attrPrefix;
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        splitTriplet(atts[i], attrURI, attrLocalName, attrPrefix);
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String attrQName = attrPrefix.isEmpty() ? attrLocalName : attrPrefix + String(":") + attrLocalName;
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String attrValue = toQString(atts[i+1]);
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        newElement->setAttributeNS(attrURI, attrQName, attrValue, exceptioncode);
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (exceptioncode) // exception while setting attributes
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::startElementNs(const XML_Char *name, const XML_Char **atts)
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserStopped)
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserPaused) {
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_pendingCallbacks->appendStartElementNSCallback(name, atts);
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_sawFirstElement = true;
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exitText();
4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String uri, localName, prefix;
4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    splitTriplet(name, uri, localName, prefix);
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String qName = prefix.isEmpty() ? localName : prefix + ":" + localName;
4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parsingFragment && uri.isEmpty()) {
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!prefix.isEmpty())
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            uri = String(m_prefixToNamespaceMap.get(prefix.impl()));
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            uri = m_defaultNamespaceURI;
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ExceptionCode ec = 0;
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Element> newElement = m_doc->createElementNS(uri, qName, ec);
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!newElement) {
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        stopParsing();
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    handleElementNamespaces(newElement.get(), uri, prefix, ec);
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec) {
4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        stopParsing();
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    handleElementAttributes(newElement.get(), atts, ec);
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec) {
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        stopParsing();
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (newElement->hasTagName(scriptTag))
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static_cast<HTMLScriptElement*>(newElement.get())->setCreatedByParser(true);
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (newElement->hasTagName(HTMLNames::scriptTag))
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_scriptStartLine = lineNumber();
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_currentNode->addChild(newElement.get())) {
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        stopParsing();
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setCurrentNode(newElement.get());
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_view && !newElement->attached())
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        newElement->attach();
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::endElementNs()
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserStopped)
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserPaused) {
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_pendingCallbacks->appendEndElementNSCallback();
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exitText();
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* n = m_currentNode;
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> parent = n->parentNode();
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    n->finishedParsing();
4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // don't load external scripts for standalone documents (for now)
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (n->isElementNode() && m_view && static_cast<Element*>(n)->hasTagName(scriptTag)) {
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(!m_pendingScript);
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_requestingScript = true;
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Element* scriptElement = static_cast<Element*>(n);
5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String scriptHref;
5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (static_cast<Element*>(n)->hasTagName(scriptTag))
5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            scriptHref = scriptElement->getAttribute(srcAttr);
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!scriptHref.isEmpty()) {
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // we have a src attribute
5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            const AtomicString& charset = scriptElement->getAttribute(charsetAttr);
5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if ((m_pendingScript = m_doc->docLoader()->requestScript(scriptHref, charset))) {
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_scriptElement = scriptElement;
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_pendingScript->ref(this);
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // m_pendingScript will be 0 if script was already loaded and ref() executed it
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (m_pendingScript)
5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    pauseParsing();
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else
5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_scriptElement = 0;
5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            String scriptCode = "";
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (Node* child = scriptElement->firstChild(); child; child = child->nextSibling()) {
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (child->isTextNode() || child->nodeType() == Node::CDATA_SECTION_NODE)
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    scriptCode += static_cast<CharacterData*>(child)->data();
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_view->frame()->loader()->executeScript(m_doc->URL(), m_scriptStartLine - 1, scriptCode);
5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_requestingScript = false;
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setCurrentNode(parent.get());
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::characters(const XML_Char *s, int len)
5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserStopped)
5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserPaused) {
5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_pendingCallbacks->appendCharactersCallback(s, len);
5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_currentNode->isTextNode() || enterText()) {
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ExceptionCode ec = 0;
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static_cast<Text*>(m_currentNode)->appendData(toQString(s, len), ec);
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool XMLTokenizer::enterText()
5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> newNode = new Text(m_doc, "");
5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_currentNode->addChild(newNode.get()))
5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setCurrentNode(newNode.get());
5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::exitText()
5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserStopped)
5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_currentNode || !m_currentNode->isTextNode())
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_view && m_currentNode && !m_currentNode->attached())
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_currentNode->attach();
5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: What's the right thing to do if the parent is really 0?
5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Just leaving the current node set to the text node doesn't make much sense.
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (Node* par = m_currentNode->parentNode())
5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setCurrentNode(par);
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::processingInstruction(const XML_Char *target, const XML_Char *data)
5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserStopped)
5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserPaused) {
5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_pendingCallbacks->appendProcessingInstructionCallback(target, data);
5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exitText();
5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // ### handle exceptions
5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int exception = 0;
5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<ProcessingInstruction> pi = m_doc->createProcessingInstruction(
5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        toQString(target), toQString(data), exception);
5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (exception)
5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_currentNode->addChild(pi.get()))
5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_view && !pi->attached())
5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        pi->attach();
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // don't load stylesheets for standalone documents
6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_doc->frame()) {
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_sawXSLTransform = !m_sawFirstElement && !pi->checkStyleSheet();
6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_sawXSLTransform)
6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            stopParsing();
6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::comment(const XML_Char *s)
6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserStopped)
6118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserPaused) {
6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_pendingCallbacks->appendCommentCallback(s);
6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exitText();
6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> newNode = m_doc->createComment(toQString(s));
6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_currentNode->addChild(newNode.get());
6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_view && !newNode->attached())
6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        newNode->attach();
6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::startCdata()
6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserStopped)
6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserPaused) {
6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_pendingCallbacks->appendStartCDATABlockCallback();
6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exitText();
6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> newNode = new CDATASection(m_doc, "");
6398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_currentNode->addChild(newNode.get()))
6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_view && !newNode->attached())
6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        newNode->attach();
6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setCurrentNode(newNode.get());
6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::endCdata()
6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserStopped)
6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserPaused) {
6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_pendingCallbacks->appendEndCDATABlockCallback();
6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_currentNode->parentNode() != 0)
6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setCurrentNode(m_currentNode->parentNode());
6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void XMLCALL startElementHandler(void *userdata, const XML_Char *name, const XML_Char **atts)
6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XMLTokenizer *tokenizer = static_cast<XMLTokenizer *>(userdata);
6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    tokenizer->startElementNs(name, atts);
6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void XMLCALL endElementHandler(void *userdata, const XML_Char *name)
6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XMLTokenizer *tokenizer = static_cast<XMLTokenizer *>(userdata);
6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    tokenizer->endElementNs();
6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void charactersHandler(void *userdata, const XML_Char *s, int len)
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XMLTokenizer *tokenizer = static_cast<XMLTokenizer *>(userdata);
6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    tokenizer->characters(s, len);
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void processingInstructionHandler(void *userdata, const XML_Char *target, const XML_Char *data)
6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XMLTokenizer *tokenizer = static_cast<XMLTokenizer *>(userdata);
6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    tokenizer->processingInstruction(target, data);
6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void commentHandler(void *userdata, const XML_Char *comment)
6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XMLTokenizer *tokenizer = static_cast<XMLTokenizer *>(userdata);
6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    tokenizer->comment(comment);
6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void startCdataHandler(void *userdata)
6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XMLTokenizer *tokenizer = static_cast<XMLTokenizer *>(userdata);
6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    tokenizer->startCdata();
6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void endCdataHandler(void *userdata)
6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XMLTokenizer *tokenizer = static_cast<XMLTokenizer *>(userdata);
6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    tokenizer->endCdata();
7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic int unknownEncodingHandler(void *userdata, const XML_Char *name, XML_Encoding *info)
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Expat doesn't like latin1 so we have to build this map
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // to do conversion correctly.
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Create a wrapper for expat that looks like libxml.
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (strcasecmp(name, "latin1") == 0)
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (int i=0; i<256; i++) {
7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            info->map[i] = i;
7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return XML_STATUS_OK;
7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return XML_STATUS_ERROR;
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool XMLTokenizer::write(const SegmentedString&s, bool /*appendData*/ )
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String parseString = s.toString();
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserStopped || m_sawXSLTransform)
7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserPaused) {
7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_pendingSrc.append(s);
7268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_parser) {
7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static const UChar BOM = 0xFEFF;
7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM);
7328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_parser = XML_ParserCreateNS(BOMHighByte == 0xFF ? "UTF-16LE" : "UTF-16BE", tripletSep);
7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_SetUserData(m_parser, (void *)this);
7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_SetReturnNSTriplet(m_parser, true);
7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_SetStartElementHandler(m_parser, startElementHandler);
7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_SetEndElementHandler(m_parser, endElementHandler);
7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_SetCharacterDataHandler(m_parser, charactersHandler);
7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_SetProcessingInstructionHandler(m_parser, processingInstructionHandler);
7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_SetCommentHandler(m_parser, commentHandler);
7418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_SetStartCdataSectionHandler(m_parser, startCdataHandler);
7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_SetEndCdataSectionHandler(m_parser, endCdataHandler);
7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_SetUnknownEncodingHandler(m_parser, unknownEncodingHandler, NULL);
7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    enum XML_Status result = XML_Parse(m_parser, (const char*)parseString.characters(), sizeof(UChar) * parseString.length(), false);
7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (result == XML_STATUS_ERROR) {
7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        reportError();
7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::end()
7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parser) {
7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_Parse(m_parser, 0, 0, true);
7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_ParserFree(m_parser);
7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_parser = 0;
7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_sawError)
7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        insertErrorMessageBlock();
7658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        exitText();
7678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_doc->updateStyleSelector();
7688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setCurrentNode(0);
7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_doc->finishedParsing();
7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::finish()
7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parserPaused)
7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_finishCalled = true;
7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        end();
7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::reportError()
7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ErrorType type = nonFatal;
7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    enum XML_Error code = XML_GetErrorCode(m_parser);
7868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (code) {
7878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case XML_ERROR_NO_MEMORY:
7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            type = fatal;
7898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case XML_ERROR_FINISHED:
7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            type = warning;
7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        default:
7948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            type = nonFatal;
7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    error(type, XML_ErrorString(code), lineNumber(), columnNumber());
7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::error(ErrorType type, const char* m, int lineNumber, int columnNumber)
8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (type == fatal || m_errorCount < maxErrors) {
8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        switch (type) {
8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case warning:
8048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_errorMessages += String::format("warning on line %d at column %d: %s", lineNumber, columnNumber, m);
8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case fatal:
8078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case nonFatal:
8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_errorMessages += String::format("error on line %d at column %d: %s", lineNumber, columnNumber, m);
8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ++m_errorCount;
8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (type != warning)
8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_sawError = true;
8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (type == fatal)
8178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        stopParsing();
8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline RefPtr<Element> createXHTMLParserErrorHeader(Document* doc, const String& errorMessages)
8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ExceptionCode ec = 0;
8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Element> reportElement = doc->createElementNS(xhtmlNamespaceURI, "parsererror", ec);
8248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    reportElement->setAttribute(styleAttr, "display:block; pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black");
8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Element> h3 = doc->createElementNS(xhtmlNamespaceURI, "h3", ec);
8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    reportElement->appendChild(h3.get(), ec);
8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    h3->appendChild(doc->createTextNode("This page contains the following errors:"), ec);
8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Element> fixed = doc->createElementNS(xhtmlNamespaceURI, "div", ec);
8318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    reportElement->appendChild(fixed.get(), ec);
8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    fixed->setAttribute(styleAttr, "font-family:monospace;font-size:12px");
8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    fixed->appendChild(doc->createTextNode(errorMessages), ec);
8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    h3 = doc->createElementNS(xhtmlNamespaceURI, "h3", ec);
8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    reportElement->appendChild(h3.get(), ec);
8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    h3->appendChild(doc->createTextNode("Below is a rendering of the page up to the first error."), ec);
8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return reportElement;
8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::insertErrorMessageBlock()
8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // One or more errors occurred during parsing of the code. Display an error block to the user above
8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the normal content (the DOM tree is created manually and includes line/col info regarding
8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // where the errors are located)
8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Create elements for display
8498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ExceptionCode ec = 0;
8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Document* doc = m_doc;
8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* documentElement = doc->documentElement();
8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!documentElement) {
8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RefPtr<Node> rootElement = doc->createElementNS(xhtmlNamespaceURI, "html", ec);
8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        doc->appendChild(rootElement, ec);
8558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RefPtr<Node> body = doc->createElementNS(xhtmlNamespaceURI, "body", ec);
8568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        rootElement->appendChild(body, ec);
8578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        documentElement = body.get();
8588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Element> reportElement = createXHTMLParserErrorHeader(doc, m_errorMessages);
8618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    documentElement->insertBefore(reportElement, documentElement->firstChild(), ec);
8628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    doc->updateRendering();
8638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::notifyFinished(CachedResource *finishedObj)
8668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_pendingScript == finishedObj);
8688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String cachedScriptUrl = m_pendingScript->url();
8708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String scriptSource = m_pendingScript->script();
8718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool errorOccurred = m_pendingScript->errorOccurred();
8728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_pendingScript->deref(this);
8738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_pendingScript = 0;
8748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Element> e = m_scriptElement;
8768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_scriptElement = 0;
8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (errorOccurred)
8798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        EventTargetNodeCast(e.get())->dispatchHTMLEvent(errorEvent, true, false);
8808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_view->frame()->loader()->executeScript(cachedScriptUrl, 0, scriptSource);
8828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        EventTargetNodeCast(e.get())->dispatchHTMLEvent(loadEvent, false, false);
8838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_scriptElement = 0;
8868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_requestingScript)
8888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        resumeParsing();
8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool XMLTokenizer::isWaitingForScripts() const
8928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_pendingScript != 0;
8948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectTokenizer *newXMLTokenizer(Document *d, FrameView *v)
8978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return new XMLTokenizer(d, v);
8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint XMLTokenizer::lineNumber() const
9028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return XML_GetCurrentLineNumber(m_parser);
9048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint XMLTokenizer::columnNumber() const
9078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return XML_GetCurrentColumnNumber(m_parser);
9098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::stopParsing()
9128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Tokenizer::stopParsing();
9148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parser)
9158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        XML_StopParser(m_parser, 0);
9168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::pauseParsing()
9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_parsingFragment)
9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_parserPaused = true;
9248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid XMLTokenizer::resumeParsing()
9278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_parserPaused);
9298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_parserPaused = false;
9318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // First, execute any pending callbacks
9338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (!m_pendingCallbacks->isEmpty()) {
9348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_pendingCallbacks->callAndRemoveFirstCallback(this);
9358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // A callback paused the parser
9378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_parserPaused)
9388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
9398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Then, write any pending data
9428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SegmentedString rest = m_pendingSrc;
9438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_pendingSrc.clear();
9448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    write(rest, false);
9458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Finally, if finish() has been called and write() didn't result
9478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // in any further callbacks being queued, call end()
9488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_finishCalled && m_pendingCallbacks->isEmpty())
9498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        end();
9508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// --------------------------------
9538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool parseXMLDocumentFragment(const String &string, DocumentFragment *fragment, Element *parent)
9558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XMLTokenizer tokenizer(fragment, parent);
9578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_Parser parser = XML_ParserCreateNS(NULL, tripletSep);
9598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    tokenizer.setXMLParser(parser);
9608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_SetUserData(parser, (void *)&tokenizer);
9628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_SetReturnNSTriplet(parser, true);
9638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_SetStartElementHandler(parser, startElementHandler);
9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_SetEndElementHandler(parser, endElementHandler);
9668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_SetCharacterDataHandler(parser, charactersHandler);
9678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_SetProcessingInstructionHandler(parser, processingInstructionHandler);
9688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_SetCommentHandler(parser, commentHandler);
9698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_SetStartCdataSectionHandler(parser, startCdataHandler);
9708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_SetEndCdataSectionHandler(parser, endCdataHandler);
9718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CString cString = string.utf8();
9738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int result = XML_Parse(parser, cString.data(), cString.length(), true);
9748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_ParserFree(parser);
9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    tokenizer.setXMLParser(0);
9778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result != XML_STATUS_ERROR;
9798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// --------------------------------
9828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstruct AttributeParseState {
9848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashMap<String, String> attributes;
9858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool gotAttributes;
9868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
9878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void attributesStartElementHandler(void *userData, const XML_Char *name, const XML_Char **atts)
9898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (strcmp(name, "attrs") != 0)
9918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (atts[0] == 0 )
9948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    AttributeParseState *state = static_cast<AttributeParseState *>(userData);
9978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    state->gotAttributes = true;
9988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = 0; atts[i]; i += 2) {
10008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DeprecatedString attrName = toQString(atts[i]);
10018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DeprecatedString attrValue = toQString(atts[i+1]);
10028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        state->attributes.set(attrName, attrValue);
10038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHashMap<String, String> parseAttributes(const String& string, bool& attrsOK)
10078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    AttributeParseState state;
10098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    state.gotAttributes = false;
10108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_Parser parser = XML_ParserCreateNS(NULL, tripletSep);
10128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_SetUserData(parser, (void *)&state);
10138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_SetReturnNSTriplet(parser, true);
10148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_SetStartElementHandler(parser, attributesStartElementHandler);
10168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String input = "<?xml version=\"1.0\"?><attrs " + string.deprecatedString() + " />";
10178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CString cString = input.deprecatedString().utf8();
10188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if ( XML_Parse(parser, cString.data(), cString.length(), true) != XML_STATUS_ERROR )
10198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        attrsOK = state.gotAttributes;
10208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    XML_ParserFree(parser);
10218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return state.attributes;
10238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1026