⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmltokenizerlibxml2.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
void setLoaderForLibXMLCallbacks(DocLoader* docLoader){    globalDocLoader = docLoader;}static bool didInit = false;static xmlParserCtxtPtr createStringParser(xmlSAXHandlerPtr handlers, void* userData){    if (!didInit) {        xmlInitParser();        xmlRegisterInputCallbacks(matchFunc, openFunc, readFunc, closeFunc);        xmlRegisterOutputCallbacks(matchFunc, openFunc, writeFunc, closeFunc);        libxmlLoaderThread = currentThread();        didInit = true;    }    xmlParserCtxtPtr parser = xmlCreatePushParserCtxt(handlers, 0, 0, 0, 0);    parser->_private = userData;    parser->replaceEntities = true;    const UChar BOM = 0xFEFF;    const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM);    xmlSwitchEncoding(parser, BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE);    return parser;}// Chunk should be encoded in UTF-8static xmlParserCtxtPtr createMemoryParser(xmlSAXHandlerPtr handlers, void* userData, const char* chunk){    if (!didInit) {        xmlInitParser();        xmlRegisterInputCallbacks(matchFunc, openFunc, readFunc, closeFunc);        xmlRegisterOutputCallbacks(matchFunc, openFunc, writeFunc, closeFunc);        libxmlLoaderThread = currentThread();        didInit = true;    }    xmlParserCtxtPtr parser = xmlCreateMemoryParserCtxt(chunk, xmlStrlen((const xmlChar*)chunk));    if (!parser)        return 0;    // Copy the sax handler    memcpy(parser->sax, handlers, sizeof(xmlSAXHandler));    // Set parser options.    // XML_PARSE_NODICT: default dictionary option.    // XML_PARSE_NOENT: force entities substitutions.    xmlCtxtUseOptions(parser, XML_PARSE_NODICT | XML_PARSE_NOENT);    // Internal initialization    parser->sax2 = 1;    parser->instate = XML_PARSER_CONTENT; // We are parsing a CONTENT    parser->depth = 0;    parser->str_xml = xmlDictLookup(parser->dict, BAD_CAST "xml", 3);    parser->str_xmlns = xmlDictLookup(parser->dict, BAD_CAST "xmlns", 5);    parser->str_xml_ns = xmlDictLookup(parser->dict, XML_XML_NAMESPACE, 36);    parser->_private = userData;    return parser;}// --------------------------------XMLTokenizer::XMLTokenizer(Document* _doc, FrameView* _view)    : m_doc(_doc)    , m_view(_view)    , m_context(0)    , m_pendingCallbacks(new PendingCallbacks)    , m_currentNode(_doc)    , m_currentNodeIsReferenced(false)    , m_sawError(false)    , m_sawXSLTransform(false)    , m_sawFirstElement(false)    , m_isXHTMLDocument(false)    , m_parserPaused(false)    , m_requestingScript(false)    , m_finishCalled(false)    , m_errorCount(0)    , m_lastErrorLine(0)    , m_lastErrorColumn(0)    , m_pendingScript(0)    , m_scriptStartLine(0)    , m_parsingFragment(false){}XMLTokenizer::XMLTokenizer(DocumentFragment* fragment, Element* parentElement)    : m_doc(fragment->document())    , m_view(0)    , m_context(0)    , m_pendingCallbacks(new PendingCallbacks)    , m_currentNode(fragment)    , m_currentNodeIsReferenced(fragment)    , m_sawError(false)    , m_sawXSLTransform(false)    , m_sawFirstElement(false)    , m_isXHTMLDocument(false)    , m_parserPaused(false)    , m_requestingScript(false)    , m_finishCalled(false)    , m_errorCount(0)    , m_lastErrorLine(0)    , m_lastErrorColumn(0)    , m_pendingScript(0)    , m_scriptStartLine(0)    , m_parsingFragment(true){    if (fragment)        fragment->ref();    if (m_doc)        m_doc->ref();              // Add namespaces based on the parent node    Vector<Element*> elemStack;    while (parentElement) {        elemStack.append(parentElement);                Node* n = parentElement->parentNode();        if (!n || !n->isElementNode())            break;        parentElement = static_cast<Element*>(n);    }        if (elemStack.isEmpty())        return;        for (Element* element = elemStack.last(); !elemStack.isEmpty(); elemStack.removeLast()) {        if (NamedAttrMap* attrs = element->attributes()) {            for (unsigned i = 0; i < attrs->length(); i++) {                Attribute* attr = attrs->attributeItem(i);                if (attr->localName() == "xmlns")                    m_defaultNamespaceURI = attr->value();                else if (attr->prefix() == "xmlns")                    m_prefixToNamespaceMap.set(attr->localName(), attr->value());            }        }    }    // If the parent element is not in document tree, there may be no xmlns attribute; just default to the parent's namespace.    if (m_defaultNamespaceURI.isNull() && !parentElement->inDocument())        m_defaultNamespaceURI = parentElement->namespaceURI();}XMLTokenizer::~XMLTokenizer(){    setCurrentNode(0);    if (m_parsingFragment && m_doc)        m_doc->deref();    if (m_pendingScript)        m_pendingScript->removeClient(this);    if (m_context)        xmlFreeParserCtxt(m_context);}void XMLTokenizer::doWrite(const String& parseString){    if (!m_context)        initializeParserContext();        // libXML throws an error if you try to switch the encoding for an empty string.    if (parseString.length()) {        // Hack around libxml2's lack of encoding overide support by manually        // resetting the encoding to UTF-16 before every chunk.  Otherwise libxml        // will detect <?xml version="1.0" encoding="<encoding name>"?> blocks         // and switch encodings, causing the parse to fail.        const UChar BOM = 0xFEFF;        const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM);        xmlSwitchEncoding(m_context, BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE);        xmlParseChunk(m_context, reinterpret_cast<const char*>(parseString.characters()), sizeof(UChar) * parseString.length(), 0);    }        if (m_doc->decoder() && m_doc->decoder()->sawError()) {        // If the decoder saw an error, report it as fatal (stops parsing)        handleError(fatal, "Encoding error", lineNumber(), columnNumber());    }    return;}static inline String toString(const xmlChar* str, unsigned len){    return UTF8Encoding().decode(reinterpret_cast<const char*>(str), len);}static inline String toString(const xmlChar* str){    if (!str)        return String();        return UTF8Encoding().decode(reinterpret_cast<const char*>(str), strlen(reinterpret_cast<const char*>(str)));}struct _xmlSAX2Namespace {    const xmlChar* prefix;    const xmlChar* uri;};typedef struct _xmlSAX2Namespace xmlSAX2Namespace;static inline void handleElementNamespaces(Element* newElement, const xmlChar** libxmlNamespaces, int nb_namespaces, ExceptionCode& ec){    xmlSAX2Namespace* namespaces = reinterpret_cast<xmlSAX2Namespace*>(libxmlNamespaces);    for(int i = 0; i < nb_namespaces; i++) {        String namespaceQName = "xmlns";        String namespaceURI = toString(namespaces[i].uri);        if (namespaces[i].prefix)            namespaceQName = "xmlns:" + toString(namespaces[i].prefix);        newElement->setAttributeNS("http://www.w3.org/2000/xmlns/", namespaceQName, namespaceURI, ec);        if (ec) // exception setting attributes            return;    }}struct _xmlSAX2Attributes {    const xmlChar* localname;    const xmlChar* prefix;    const xmlChar* uri;    const xmlChar* value;    const xmlChar* end;};typedef struct _xmlSAX2Attributes xmlSAX2Attributes;static inline void handleElementAttributes(Element* newElement, const xmlChar** libxmlAttributes, int nb_attributes, ExceptionCode& ec){    xmlSAX2Attributes* attributes = reinterpret_cast<xmlSAX2Attributes*>(libxmlAttributes);    for(int i = 0; i < nb_attributes; i++) {        String attrLocalName = toString(attributes[i].localname);        int valueLength = (int) (attributes[i].end - attributes[i].value);        String attrValue = toString(attributes[i].value, valueLength);        String attrPrefix = toString(attributes[i].prefix);        String attrURI = attrPrefix.isEmpty() ? String() : toString(attributes[i].uri);        String attrQName = attrPrefix.isEmpty() ? attrLocalName : attrPrefix + ":" + attrLocalName;                newElement->setAttributeNS(attrURI, attrQName, attrValue, ec);        if (ec) // exception setting attributes            return;    }}void XMLTokenizer::startElementNs(const xmlChar* xmlLocalName, const xmlChar* xmlPrefix, const xmlChar* xmlURI, int nb_namespaces,                                  const xmlChar** libxmlNamespaces, int nb_attributes, int nb_defaulted, const xmlChar** libxmlAttributes){    if (m_parserStopped)        return;        if (m_parserPaused) {        m_pendingCallbacks->appendStartElementNSCallback(xmlLocalName, xmlPrefix, xmlURI, nb_namespaces, libxmlNamespaces,                                                         nb_attributes, nb_defaulted, libxmlAttributes);        return;    }    bool isFirstElement = !m_sawFirstElement;    m_sawFirstElement = true;    exitText();    String localName = toString(xmlLocalName);    String uri = toString(xmlURI);    String prefix = toString(xmlPrefix);    if (m_parsingFragment && uri.isNull()) {        if (!prefix.isNull())            uri = m_prefixToNamespaceMap.get(prefix);        else            uri = m_defaultNamespaceURI;    }    QualifiedName qName(prefix, localName, uri);    RefPtr<Element> newElement = m_doc->createElement(qName, true);    if (!newElement) {        stopParsing();        return;    }        ExceptionCode ec = 0;    handleElementNamespaces(newElement.get(), libxmlNamespaces, nb_namespaces, ec);    if (ec) {        stopParsing();        return;    }    ScriptController* jsProxy = m_doc->frame() ? m_doc->frame()->script() : 0;    if (jsProxy && m_doc->frame()->script()->isEnabled())        jsProxy->setEventHandlerLineno(lineNumber());    handleElementAttributes(newElement.get(), libxmlAttributes, nb_attributes, ec);    if (ec) {        stopParsing();        return;    }    if (jsProxy)        jsProxy->setEventHandlerLineno(0);    newElement->beginParsingChildren();    ScriptElement* scriptElement = toScriptElement(newElement.get());    if (scriptElement)        m_scriptStartLine = lineNumber();    if (!m_currentNode->addChild(newElement.get())) {        stopParsing();        return;    }    setCurrentNode(newElement.get());    if (m_view && !newElement->attached())        newElement->attach();    if (isFirstElement && m_doc->frame())        m_doc->frame()->loader()->dispatchDocumentElementAvailable();}void XMLTokenizer::endElementNs(){    if (m_parserStopped)        return;    if (m_parserPaused) {        m_pendingCallbacks->appendEndElementNSCallback();        return;    }        exitText();    Node* n = m_currentNode;    RefPtr<Node> parent = n->parentNode();    n->finishParsingChildren();    if (!n->isElementNode() || !m_view) {        setCurrentNode(parent.get());        return;    }    Element* element = static_cast<Element*>(n);    ScriptElement* scriptElement = toScriptElement(element);    if (!scriptElement) {        setCurrentNode(parent.get());        return;    }    // don't load external scripts for standalone documents (for now)    ASSERT(!m_pendingScript);    m_requestingScript = true;    String scriptHref = scriptElement->sourceAttributeValue();    if (!scriptHref.isEmpty()) {        // we have a src attribute         String scriptCharset = scriptElement->scriptCharset();        if ((m_pendingScript = m_doc->docLoader()->requestScript(scriptHref, scriptCharset))) {            m_scriptElement = element;            m_pendingScript->addClient(this);            // m_pendingScript will be 0 if script was already loaded and ref() executed it            if (m_pendingScript)                pauseParsing();        } else             m_scriptElement = 0;    } else        m_view->frame()->loader()->executeScript(ScriptSourceCode(scriptElement->scriptContent(), m_doc->url(), m_scriptStartLine));    m_requestingScript = false;    setCurrentNode(parent.get());}void XMLTokenizer::characters(const xmlChar* s, int len){    if (m_parserStopped)        return;        if (m_parserPaused) {        m_pendingCallbacks->appendCharactersCallback(s, len);        return;    }        if (m_currentNode->isTextNode() || enterText())        m_bufferedText.append(s, len);}void XMLTokenizer::error(ErrorType type, const char* message, va_list args){    if (m_parserStopped)        return;#if PLATFORM(WIN_OS)    char m[1024];    vsnprintf(m, sizeof(m) - 1, message, args);#else    char* m;    vasprintf(&m, message, args);#endif        if (m_parserPaused)        m_pendingCallbacks->appendErrorCallback(type, m, lineNumber(), columnNumber());    else        handleError(type, m, lineNumber(), columnNumber());#if !PLATFORM(WIN_OS)    free(m);#endif}void XMLTokenizer::processingInstruction(const xmlChar* target, const xmlChar* data){    if (m_parserStopped)        return;    if (m_parserPaused) {        m_pendingCallbacks->appendProcessingInstructionCallback(target, data);        return;    }        exitText();    // ### handle exceptions    int exception = 0;    RefPtr<ProcessingInstruction> pi = m_doc->createProcessingInstruction(        toString(target), toString(data), exception);    if (exception)        return;    pi->setCreatedByParser(true);        if (!m_currentNode->addChild(pi.get()))        return;    if (m_view && !pi->attached())        pi->attach();    pi->finishParsingChildren();#if ENABLE(XSLT)    m_sawXSLTransform = !m_sawFirstElement && pi->isXSL();    if (m_sawXSLTransform && !m_doc->transformSourceDocument())        stopParsing();#endif}void XMLTokenizer::cdataBlock(const xmlChar* s, int len){    if (m_parserStopped)        return;    if (m_parserPaused) {        m_pendingCallbacks->appendCDATABlockCallback(s, len);        return;    }        exitText();    RefPtr<Node> newNode = new CDATASection(m_doc, toString(s, len));    if (!m_currentNode->addChild(newNode.get()))        return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -