18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(XPATH)
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "XPathNodeSet.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Attr.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Element.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Node.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace XPath {
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline Node* parentWithDepth(unsigned depth, const Vector<Node*>& parents)
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(parents.size() >= depth + 1);
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return parents[parents.size() - 1 - depth];
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void sortBlock(unsigned from, unsigned to, Vector<Vector<Node*> >& parentMatrix, bool mayContainAttributeNodes)
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(from + 1 < to); // Should not call this function with less that two nodes to sort.
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned minDepth = UINT_MAX;
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = from; i < to; ++i) {
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unsigned depth = parentMatrix[i].size() - 1;
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (minDepth > depth)
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            minDepth = depth;
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Find the common ancestor.
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned commonAncestorDepth = minDepth;
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* commonAncestor;
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (true) {
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        commonAncestor = parentWithDepth(commonAncestorDepth, parentMatrix[from]);
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (commonAncestorDepth == 0)
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool allEqual = true;
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (unsigned i = from + 1; i < to; ++i) {
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (commonAncestor != parentWithDepth(commonAncestorDepth, parentMatrix[i])) {
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                allEqual = false;
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (allEqual)
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        --commonAncestorDepth;
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (commonAncestorDepth == minDepth) {
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // One of the nodes is the common ancestor => it is the first in document order.
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Find it and move it to the beginning.
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (unsigned i = from; i < to; ++i)
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (commonAncestor == parentMatrix[i][0]) {
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                parentMatrix[i].swap(parentMatrix[from]);
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (from + 2 < to)
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    sortBlock(from + 1, to, parentMatrix, mayContainAttributeNodes);
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return;
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (mayContainAttributeNodes && commonAncestor->isElementNode()) {
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The attribute nodes and namespace nodes of an element occur before the children of the element.
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The namespace nodes are defined to occur before the attribute nodes.
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The relative order of namespace nodes is implementation-dependent.
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The relative order of attribute nodes is implementation-dependent.
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unsigned sortedEnd = from;
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: namespace nodes are not implemented.
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (unsigned i = sortedEnd; i < to; ++i) {
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Node* n = parentMatrix[i][0];
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (n->isAttributeNode() && static_cast<Attr*>(n)->ownerElement() == commonAncestor)
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                parentMatrix[i].swap(parentMatrix[sortedEnd++]);
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (sortedEnd != from) {
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (to - sortedEnd > 1)
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                sortBlock(sortedEnd, to, parentMatrix, mayContainAttributeNodes);
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Children nodes of the common ancestor induce a subdivision of our node-set.
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Sort it according to this subdivision, and recursively sort each group.
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashSet<Node*> parentNodes;
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = from; i < to; ++i)
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        parentNodes.add(parentWithDepth(commonAncestorDepth + 1, parentMatrix[i]));
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned previousGroupEnd = from;
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned groupEnd = from;
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Node* n = commonAncestor->firstChild(); n; n = n->nextSibling()) {
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If parentNodes contains the node, perform a linear search to move its children in the node-set to the beginning.
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (parentNodes.contains(n)) {
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (unsigned i = groupEnd; i < to; ++i)
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (parentWithDepth(commonAncestorDepth + 1, parentMatrix[i]) == n)
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    parentMatrix[i].swap(parentMatrix[groupEnd++]);
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (groupEnd - previousGroupEnd > 1)
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                sortBlock(previousGroupEnd, groupEnd, parentMatrix, mayContainAttributeNodes);
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(previousGroupEnd != groupEnd);
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            previousGroupEnd = groupEnd;
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            parentNodes.remove(n);
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(parentNodes.isEmpty());
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid NodeSet::sort() const
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_isSorted)
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned nodeCount = m_nodes.size();
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (nodeCount < 2) {
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const_cast<bool&>(m_isSorted) = true;
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool containsAttributeNodes = false;
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<Vector<Node*> > parentMatrix(nodeCount);
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < nodeCount; ++i) {
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Vector<Node*>& parentsVector = parentMatrix[i];
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* n = m_nodes[i].get();
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        parentsVector.append(n);
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n->isAttributeNode()) {
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            n = static_cast<Attr*>(n)->ownerElement();
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            parentsVector.append(n);
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            containsAttributeNodes = true;
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1586b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        while ((n = n->parentNode()))
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            parentsVector.append(n);
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    sortBlock(0, nodeCount, parentMatrix, containsAttributeNodes);
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // It is not possible to just assign the result to m_nodes, because some nodes may get dereferenced and destroyed.
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<RefPtr<Node> > sortedNodes;
1658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    sortedNodes.reserveInitialCapacity(nodeCount);
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < nodeCount; ++i)
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sortedNodes.append(parentMatrix[i][0]);
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const_cast<Vector<RefPtr<Node> >& >(m_nodes).swap(sortedNodes);
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid NodeSet::reverse()
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_nodes.isEmpty())
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned from = 0;
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned to = m_nodes.size() - 1;
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (from < to) {
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_nodes[from].swap(m_nodes[to]);
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ++from;
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        --to;
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* NodeSet::firstNode() const
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isEmpty())
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    sort(); // FIXME: fully sorting the node-set just to find its first node is wasteful.
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_nodes.at(0).get();
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* NodeSet::anyNode() const
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isEmpty())
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_nodes.at(0).get();
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif // ENABLE(XPATH)
207