mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-13 23:17:57 +00:00
f51c82302b
--HG-- rename : content/xslt/src/base/moz.build => dom/xslt/base/moz.build rename : content/xslt/src/base/txCore.h => dom/xslt/base/txCore.h rename : content/xslt/src/base/txDouble.cpp => dom/xslt/base/txDouble.cpp rename : content/xslt/src/base/txErrorObserver.h => dom/xslt/base/txErrorObserver.h rename : content/xslt/src/base/txExpandedNameMap.cpp => dom/xslt/base/txExpandedNameMap.cpp rename : content/xslt/src/base/txExpandedNameMap.h => dom/xslt/base/txExpandedNameMap.h rename : content/xslt/src/base/txList.cpp => dom/xslt/base/txList.cpp rename : content/xslt/src/base/txList.h => dom/xslt/base/txList.h rename : content/xslt/src/base/txLog.h => dom/xslt/base/txLog.h rename : content/xslt/src/base/txNamespaceMap.cpp => dom/xslt/base/txNamespaceMap.cpp rename : content/xslt/src/base/txNamespaceMap.h => dom/xslt/base/txNamespaceMap.h rename : content/xslt/src/base/txOwningArray.h => dom/xslt/base/txOwningArray.h rename : content/xslt/src/base/txStack.h => dom/xslt/base/txStack.h rename : content/xslt/src/base/txStringUtils.h => dom/xslt/base/txStringUtils.h rename : content/xslt/src/base/txURIUtils.cpp => dom/xslt/base/txURIUtils.cpp rename : content/xslt/src/base/txURIUtils.h => dom/xslt/base/txURIUtils.h rename : content/xslt/crashtests/111994.xml => dom/xslt/crashtests/111994.xml rename : content/xslt/crashtests/111994.xsl => dom/xslt/crashtests/111994.xsl rename : content/xslt/crashtests/182460-select.xml => dom/xslt/crashtests/182460-select.xml rename : content/xslt/crashtests/182460-selects.xsl => dom/xslt/crashtests/182460-selects.xsl rename : content/xslt/crashtests/182460-table.xhtml => dom/xslt/crashtests/182460-table.xhtml rename : content/xslt/crashtests/226425.xml => dom/xslt/crashtests/226425.xml rename : content/xslt/crashtests/226425.xsl => dom/xslt/crashtests/226425.xsl rename : content/xslt/crashtests/406106-1.html => dom/xslt/crashtests/406106-1.html rename : content/xslt/crashtests/483444.xml => dom/xslt/crashtests/483444.xml rename : content/xslt/crashtests/485217.xml => dom/xslt/crashtests/485217.xml rename : content/xslt/crashtests/485217.xsl => dom/xslt/crashtests/485217.xsl rename : content/xslt/crashtests/485286.xml => dom/xslt/crashtests/485286.xml rename : content/xslt/crashtests/528300.xml => dom/xslt/crashtests/528300.xml rename : content/xslt/crashtests/528488.xml => dom/xslt/crashtests/528488.xml rename : content/xslt/crashtests/528963.xml => dom/xslt/crashtests/528963.xml rename : content/xslt/crashtests/545927.html => dom/xslt/crashtests/545927.html rename : content/xslt/crashtests/601543.html => dom/xslt/crashtests/601543.html rename : content/xslt/crashtests/602115.html => dom/xslt/crashtests/602115.html rename : content/xslt/crashtests/603844.html => dom/xslt/crashtests/603844.html rename : content/xslt/crashtests/667315.xml => dom/xslt/crashtests/667315.xml rename : content/xslt/crashtests/91332.xml => dom/xslt/crashtests/91332.xml rename : content/xslt/crashtests/91332.xsl => dom/xslt/crashtests/91332.xsl rename : content/xslt/crashtests/crashtests.list => dom/xslt/crashtests/crashtests.list rename : content/xslt/public/moz.build => dom/xslt/moz.build rename : content/xslt/public/nsIDocumentTransformer.h => dom/xslt/nsIDocumentTransformer.h rename : content/xslt/public/nsIXSLTException.idl => dom/xslt/nsIXSLTException.idl rename : content/xslt/public/nsIXSLTProcessor.idl => dom/xslt/nsIXSLTProcessor.idl rename : content/xslt/public/nsIXSLTProcessorPrivate.idl => dom/xslt/nsIXSLTProcessorPrivate.idl rename : content/xslt/tests/XSLTMark/XSLTMark-static.js => dom/xslt/tests/XSLTMark/XSLTMark-static.js rename : content/xslt/tests/XSLTMark/XSLTMark-test.js => dom/xslt/tests/XSLTMark/XSLTMark-test.js rename : content/xslt/tests/XSLTMark/XSLTMark-view.js => dom/xslt/tests/XSLTMark/XSLTMark-view.js rename : content/xslt/tests/XSLTMark/XSLTMark.css => dom/xslt/tests/XSLTMark/XSLTMark.css rename : content/xslt/tests/XSLTMark/XSLTMark.xul => dom/xslt/tests/XSLTMark/XSLTMark.xul rename : content/xslt/tests/buster/DiffDOM.js => dom/xslt/tests/buster/DiffDOM.js rename : content/xslt/tests/buster/DumpDOM.js => dom/xslt/tests/buster/DumpDOM.js rename : content/xslt/tests/buster/ReadMe => dom/xslt/tests/buster/ReadMe rename : content/xslt/tests/buster/buster-files.js => dom/xslt/tests/buster/buster-files.js rename : content/xslt/tests/buster/buster-handlers.js => dom/xslt/tests/buster/buster-handlers.js rename : content/xslt/tests/buster/buster-statics.js => dom/xslt/tests/buster/buster-statics.js rename : content/xslt/tests/buster/buster-test.js => dom/xslt/tests/buster/buster-test.js rename : content/xslt/tests/buster/buster-view.js => dom/xslt/tests/buster/buster-view.js rename : content/xslt/tests/buster/buster.css => dom/xslt/tests/buster/buster.css rename : content/xslt/tests/buster/buster.xul => dom/xslt/tests/buster/buster.xul rename : content/xslt/tests/buster/helper/generate-rdf.pl => dom/xslt/tests/buster/helper/generate-rdf.pl rename : content/xslt/tests/buster/install.js => dom/xslt/tests/buster/install.js rename : content/xslt/tests/buster/jar.mn => dom/xslt/tests/buster/jar.mn rename : content/xslt/tests/buster/moz.build => dom/xslt/tests/buster/moz.build rename : content/xslt/tests/buster/result-inspector.xul => dom/xslt/tests/buster/result-inspector.xul rename : content/xslt/tests/buster/result-view.css => dom/xslt/tests/buster/result-view.css rename : content/xslt/tests/buster/result-view.js => dom/xslt/tests/buster/result-view.js rename : content/xslt/tests/buster/result-view.xul => dom/xslt/tests/buster/result-view.xul rename : content/xslt/tests/buster/xslt-qa-overlay.js => dom/xslt/tests/buster/xslt-qa-overlay.js rename : content/xslt/tests/buster/xslt-qa-overlay.xul => dom/xslt/tests/buster/xslt-qa-overlay.xul rename : content/xslt/tests/mochitest/mochitest.ini => dom/xslt/tests/mochitest/mochitest.ini rename : content/xslt/tests/mochitest/moz.build => dom/xslt/tests/mochitest/moz.build rename : content/xslt/tests/mochitest/test_bug319374.xhtml => dom/xslt/tests/mochitest/test_bug319374.xhtml rename : content/xslt/tests/mochitest/test_bug427060.html => dom/xslt/tests/mochitest/test_bug427060.html rename : content/xslt/tests/mochitest/test_bug440974.html => dom/xslt/tests/mochitest/test_bug440974.html rename : content/xslt/tests/mochitest/test_bug453441.html => dom/xslt/tests/mochitest/test_bug453441.html rename : content/xslt/tests/mochitest/test_bug468208.html => dom/xslt/tests/mochitest/test_bug468208.html rename : content/xslt/tests/mochitest/test_bug511487.html => dom/xslt/tests/mochitest/test_bug511487.html rename : content/xslt/tests/mochitest/test_bug551412.html => dom/xslt/tests/mochitest/test_bug551412.html rename : content/xslt/tests/mochitest/test_bug551654.html => dom/xslt/tests/mochitest/test_bug551654.html rename : content/xslt/tests/mochitest/test_bug566629.html => dom/xslt/tests/mochitest/test_bug566629.html rename : content/xslt/tests/mochitest/test_bug566629.xhtml => dom/xslt/tests/mochitest/test_bug566629.xhtml rename : content/xslt/tests/mochitest/test_bug603159.html => dom/xslt/tests/mochitest/test_bug603159.html rename : content/xslt/tests/mochitest/test_bug616774.html => dom/xslt/tests/mochitest/test_bug616774.html rename : content/xslt/tests/mochitest/test_bug667315.html => dom/xslt/tests/mochitest/test_bug667315.html rename : content/xslt/tests/mochitest/test_exslt_regex.html => dom/xslt/tests/mochitest/test_exslt_regex.html rename : content/xslt/public/txIEXSLTRegExFunctions.idl => dom/xslt/txIEXSLTRegExFunctions.idl rename : content/xslt/public/txIFunctionEvaluationContext.idl => dom/xslt/txIFunctionEvaluationContext.idl rename : content/xslt/public/txINodeSet.idl => dom/xslt/txINodeSet.idl rename : content/xslt/public/txIXPathObject.idl => dom/xslt/txIXPathObject.idl rename : content/xslt/src/xml/moz.build => dom/xslt/xml/moz.build rename : content/xslt/src/xml/txXMLParser.cpp => dom/xslt/xml/txXMLParser.cpp rename : content/xslt/src/xml/txXMLParser.h => dom/xslt/xml/txXMLParser.h rename : content/xslt/src/xml/txXMLUtils.cpp => dom/xslt/xml/txXMLUtils.cpp rename : content/xslt/src/xml/txXMLUtils.h => dom/xslt/xml/txXMLUtils.h rename : content/xslt/src/xpath/XPathEvaluator.cpp => dom/xslt/xpath/XPathEvaluator.cpp rename : content/xslt/src/xpath/XPathEvaluator.h => dom/xslt/xpath/XPathEvaluator.h rename : content/xslt/src/xpath/moz.build => dom/xslt/xpath/moz.build rename : content/xslt/src/xpath/nsXPathExpression.cpp => dom/xslt/xpath/nsXPathExpression.cpp rename : content/xslt/src/xpath/nsXPathExpression.h => dom/xslt/xpath/nsXPathExpression.h rename : content/xslt/src/xpath/nsXPathNSResolver.cpp => dom/xslt/xpath/nsXPathNSResolver.cpp rename : content/xslt/src/xpath/nsXPathNSResolver.h => dom/xslt/xpath/nsXPathNSResolver.h rename : content/xslt/src/xpath/nsXPathResult.cpp => dom/xslt/xpath/nsXPathResult.cpp rename : content/xslt/src/xpath/nsXPathResult.h => dom/xslt/xpath/nsXPathResult.h rename : content/xslt/src/xpath/txBooleanExpr.cpp => dom/xslt/xpath/txBooleanExpr.cpp rename : content/xslt/src/xpath/txBooleanResult.cpp => dom/xslt/xpath/txBooleanResult.cpp rename : content/xslt/src/xpath/txCoreFunctionCall.cpp => dom/xslt/xpath/txCoreFunctionCall.cpp rename : content/xslt/src/xpath/txErrorExpr.cpp => dom/xslt/xpath/txErrorExpr.cpp rename : content/xslt/src/xpath/txExpr.cpp => dom/xslt/xpath/txExpr.cpp rename : content/xslt/src/xpath/txExpr.h => dom/xslt/xpath/txExpr.h rename : content/xslt/src/xpath/txExprLexer.cpp => dom/xslt/xpath/txExprLexer.cpp rename : content/xslt/src/xpath/txExprLexer.h => dom/xslt/xpath/txExprLexer.h rename : content/xslt/src/xpath/txExprParser.cpp => dom/xslt/xpath/txExprParser.cpp rename : content/xslt/src/xpath/txExprParser.h => dom/xslt/xpath/txExprParser.h rename : content/xslt/src/xpath/txExprResult.h => dom/xslt/xpath/txExprResult.h rename : content/xslt/src/xpath/txFilterExpr.cpp => dom/xslt/xpath/txFilterExpr.cpp rename : content/xslt/src/xpath/txForwardContext.cpp => dom/xslt/xpath/txForwardContext.cpp rename : content/xslt/src/xpath/txForwardContext.h => dom/xslt/xpath/txForwardContext.h rename : content/xslt/src/xpath/txFunctionCall.cpp => dom/xslt/xpath/txFunctionCall.cpp rename : content/xslt/src/xpath/txIXPathContext.h => dom/xslt/xpath/txIXPathContext.h rename : content/xslt/src/xpath/txLiteralExpr.cpp => dom/xslt/xpath/txLiteralExpr.cpp rename : content/xslt/src/xpath/txLocationStep.cpp => dom/xslt/xpath/txLocationStep.cpp rename : content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp => dom/xslt/xpath/txMozillaXPathTreeWalker.cpp rename : content/xslt/src/xpath/txNameTest.cpp => dom/xslt/xpath/txNameTest.cpp rename : content/xslt/src/xpath/txNamedAttributeStep.cpp => dom/xslt/xpath/txNamedAttributeStep.cpp rename : content/xslt/src/xpath/txNodeSet.cpp => dom/xslt/xpath/txNodeSet.cpp rename : content/xslt/src/xpath/txNodeSet.h => dom/xslt/xpath/txNodeSet.h rename : content/xslt/src/xpath/txNodeSetAdaptor.cpp => dom/xslt/xpath/txNodeSetAdaptor.cpp rename : content/xslt/src/xpath/txNodeSetAdaptor.h => dom/xslt/xpath/txNodeSetAdaptor.h rename : content/xslt/src/xpath/txNodeSetContext.cpp => dom/xslt/xpath/txNodeSetContext.cpp rename : content/xslt/src/xpath/txNodeSetContext.h => dom/xslt/xpath/txNodeSetContext.h rename : content/xslt/src/xpath/txNodeTypeTest.cpp => dom/xslt/xpath/txNodeTypeTest.cpp rename : content/xslt/src/xpath/txNumberExpr.cpp => dom/xslt/xpath/txNumberExpr.cpp rename : content/xslt/src/xpath/txNumberResult.cpp => dom/xslt/xpath/txNumberResult.cpp rename : content/xslt/src/xpath/txPathExpr.cpp => dom/xslt/xpath/txPathExpr.cpp rename : content/xslt/src/xpath/txPredicateList.cpp => dom/xslt/xpath/txPredicateList.cpp rename : content/xslt/src/xpath/txPredicatedNodeTest.cpp => dom/xslt/xpath/txPredicatedNodeTest.cpp rename : content/xslt/src/xpath/txRelationalExpr.cpp => dom/xslt/xpath/txRelationalExpr.cpp rename : content/xslt/src/xpath/txResultRecycler.cpp => dom/xslt/xpath/txResultRecycler.cpp rename : content/xslt/src/xpath/txResultRecycler.h => dom/xslt/xpath/txResultRecycler.h rename : content/xslt/src/xpath/txRootExpr.cpp => dom/xslt/xpath/txRootExpr.cpp rename : content/xslt/src/xpath/txSingleNodeContext.h => dom/xslt/xpath/txSingleNodeContext.h rename : content/xslt/src/xpath/txStringResult.cpp => dom/xslt/xpath/txStringResult.cpp rename : content/xslt/src/xpath/txUnaryExpr.cpp => dom/xslt/xpath/txUnaryExpr.cpp rename : content/xslt/src/xpath/txUnionExpr.cpp => dom/xslt/xpath/txUnionExpr.cpp rename : content/xslt/src/xpath/txUnionNodeTest.cpp => dom/xslt/xpath/txUnionNodeTest.cpp rename : content/xslt/src/xpath/txVariableRefExpr.cpp => dom/xslt/xpath/txVariableRefExpr.cpp rename : content/xslt/src/xpath/txXPCOMExtensionFunction.cpp => dom/xslt/xpath/txXPCOMExtensionFunction.cpp rename : content/xslt/src/xpath/txXPathNode.h => dom/xslt/xpath/txXPathNode.h rename : content/xslt/src/xpath/txXPathObjectAdaptor.h => dom/xslt/xpath/txXPathObjectAdaptor.h rename : content/xslt/src/xpath/txXPathOptimizer.cpp => dom/xslt/xpath/txXPathOptimizer.cpp rename : content/xslt/src/xpath/txXPathOptimizer.h => dom/xslt/xpath/txXPathOptimizer.h rename : content/xslt/src/xpath/txXPathTreeWalker.h => dom/xslt/xpath/txXPathTreeWalker.h rename : content/xslt/src/xslt/moz.build => dom/xslt/xslt/moz.build rename : content/xslt/src/xslt/txBufferingHandler.cpp => dom/xslt/xslt/txBufferingHandler.cpp rename : content/xslt/src/xslt/txBufferingHandler.h => dom/xslt/xslt/txBufferingHandler.h rename : content/xslt/src/xslt/txCurrentFunctionCall.cpp => dom/xslt/xslt/txCurrentFunctionCall.cpp rename : content/xslt/src/xslt/txDocumentFunctionCall.cpp => dom/xslt/xslt/txDocumentFunctionCall.cpp rename : content/xslt/src/xslt/txEXSLTFunctions.cpp => dom/xslt/xslt/txEXSLTFunctions.cpp rename : content/xslt/src/xslt/txEXSLTRegExFunctions.js => dom/xslt/xslt/txEXSLTRegExFunctions.js rename : content/xslt/src/xslt/txEXSLTRegExFunctions.manifest => dom/xslt/xslt/txEXSLTRegExFunctions.manifest rename : content/xslt/src/xslt/txExecutionState.cpp => dom/xslt/xslt/txExecutionState.cpp rename : content/xslt/src/xslt/txExecutionState.h => dom/xslt/xslt/txExecutionState.h rename : content/xslt/src/xslt/txFormatNumberFunctionCall.cpp => dom/xslt/xslt/txFormatNumberFunctionCall.cpp rename : content/xslt/src/xslt/txGenerateIdFunctionCall.cpp => dom/xslt/xslt/txGenerateIdFunctionCall.cpp rename : content/xslt/src/xslt/txInstructions.cpp => dom/xslt/xslt/txInstructions.cpp rename : content/xslt/src/xslt/txInstructions.h => dom/xslt/xslt/txInstructions.h rename : content/xslt/src/xslt/txKey.h => dom/xslt/xslt/txKey.h rename : content/xslt/src/xslt/txKeyFunctionCall.cpp => dom/xslt/xslt/txKeyFunctionCall.cpp rename : content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp => dom/xslt/xslt/txMozillaStylesheetCompiler.cpp rename : content/xslt/src/xslt/txMozillaTextOutput.cpp => dom/xslt/xslt/txMozillaTextOutput.cpp rename : content/xslt/src/xslt/txMozillaTextOutput.h => dom/xslt/xslt/txMozillaTextOutput.h rename : content/xslt/src/xslt/txMozillaXMLOutput.cpp => dom/xslt/xslt/txMozillaXMLOutput.cpp rename : content/xslt/src/xslt/txMozillaXMLOutput.h => dom/xslt/xslt/txMozillaXMLOutput.h rename : content/xslt/src/xslt/txMozillaXSLTProcessor.cpp => dom/xslt/xslt/txMozillaXSLTProcessor.cpp rename : content/xslt/src/xslt/txMozillaXSLTProcessor.h => dom/xslt/xslt/txMozillaXSLTProcessor.h rename : content/xslt/src/xslt/txNodeSorter.cpp => dom/xslt/xslt/txNodeSorter.cpp rename : content/xslt/src/xslt/txNodeSorter.h => dom/xslt/xslt/txNodeSorter.h rename : content/xslt/src/xslt/txOutputFormat.cpp => dom/xslt/xslt/txOutputFormat.cpp rename : content/xslt/src/xslt/txOutputFormat.h => dom/xslt/xslt/txOutputFormat.h rename : content/xslt/src/xslt/txPatternOptimizer.cpp => dom/xslt/xslt/txPatternOptimizer.cpp rename : content/xslt/src/xslt/txPatternOptimizer.h => dom/xslt/xslt/txPatternOptimizer.h rename : content/xslt/src/xslt/txPatternParser.cpp => dom/xslt/xslt/txPatternParser.cpp rename : content/xslt/src/xslt/txPatternParser.h => dom/xslt/xslt/txPatternParser.h rename : content/xslt/src/xslt/txRtfHandler.cpp => dom/xslt/xslt/txRtfHandler.cpp rename : content/xslt/src/xslt/txRtfHandler.h => dom/xslt/xslt/txRtfHandler.h rename : content/xslt/src/xslt/txStylesheet.cpp => dom/xslt/xslt/txStylesheet.cpp rename : content/xslt/src/xslt/txStylesheet.h => dom/xslt/xslt/txStylesheet.h rename : content/xslt/src/xslt/txStylesheetCompileHandlers.cpp => dom/xslt/xslt/txStylesheetCompileHandlers.cpp rename : content/xslt/src/xslt/txStylesheetCompileHandlers.h => dom/xslt/xslt/txStylesheetCompileHandlers.h rename : content/xslt/src/xslt/txStylesheetCompiler.cpp => dom/xslt/xslt/txStylesheetCompiler.cpp rename : content/xslt/src/xslt/txStylesheetCompiler.h => dom/xslt/xslt/txStylesheetCompiler.h rename : content/xslt/src/xslt/txTextHandler.cpp => dom/xslt/xslt/txTextHandler.cpp rename : content/xslt/src/xslt/txTextHandler.h => dom/xslt/xslt/txTextHandler.h rename : content/xslt/src/xslt/txToplevelItems.cpp => dom/xslt/xslt/txToplevelItems.cpp rename : content/xslt/src/xslt/txToplevelItems.h => dom/xslt/xslt/txToplevelItems.h rename : content/xslt/src/xslt/txUnknownHandler.cpp => dom/xslt/xslt/txUnknownHandler.cpp rename : content/xslt/src/xslt/txUnknownHandler.h => dom/xslt/xslt/txUnknownHandler.h rename : content/xslt/src/xslt/txVariableMap.h => dom/xslt/xslt/txVariableMap.h rename : content/xslt/src/xslt/txXMLEventHandler.h => dom/xslt/xslt/txXMLEventHandler.h rename : content/xslt/src/xslt/txXPathResultComparator.cpp => dom/xslt/xslt/txXPathResultComparator.cpp rename : content/xslt/src/xslt/txXPathResultComparator.h => dom/xslt/xslt/txXPathResultComparator.h rename : content/xslt/src/xslt/txXSLTEnvironmentFunctionCall.cpp => dom/xslt/xslt/txXSLTEnvironmentFunctionCall.cpp rename : content/xslt/src/xslt/txXSLTFunctions.h => dom/xslt/xslt/txXSLTFunctions.h rename : content/xslt/src/xslt/txXSLTNumber.cpp => dom/xslt/xslt/txXSLTNumber.cpp rename : content/xslt/src/xslt/txXSLTNumber.h => dom/xslt/xslt/txXSLTNumber.h rename : content/xslt/src/xslt/txXSLTNumberCounters.cpp => dom/xslt/xslt/txXSLTNumberCounters.cpp rename : content/xslt/src/xslt/txXSLTPatterns.cpp => dom/xslt/xslt/txXSLTPatterns.cpp rename : content/xslt/src/xslt/txXSLTPatterns.h => dom/xslt/xslt/txXSLTPatterns.h rename : content/xslt/src/xslt/txXSLTProcessor.cpp => dom/xslt/xslt/txXSLTProcessor.cpp rename : content/xslt/src/xslt/txXSLTProcessor.h => dom/xslt/xslt/txXSLTProcessor.h extra : rebase_source : 2ffae4527252a6937dd1ee2053d2c9d4fbe268fb
624 lines
16 KiB
C++
624 lines
16 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "txNodeSet.h"
|
|
#include "txLog.h"
|
|
#include "nsMemory.h"
|
|
#include "txXPathTreeWalker.h"
|
|
#include <algorithm>
|
|
|
|
/**
|
|
* Implementation of an XPath nodeset
|
|
*/
|
|
|
|
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
#define LOG_CHUNK_MOVE(_start, _new_start, _count) \
|
|
{ \
|
|
txXPathNode *start = const_cast<txXPathNode*>(_start); \
|
|
while (start < _start + _count) { \
|
|
NS_LogDtor(start, "txXPathNode", sizeof(*start)); \
|
|
++start; \
|
|
} \
|
|
start = const_cast<txXPathNode*>(_new_start); \
|
|
while (start < _new_start + _count) { \
|
|
NS_LogCtor(start, "txXPathNode", sizeof(*start)); \
|
|
++start; \
|
|
} \
|
|
}
|
|
#else
|
|
#define LOG_CHUNK_MOVE(_start, _new_start, _count)
|
|
#endif
|
|
|
|
static const int32_t kTxNodeSetMinSize = 4;
|
|
static const int32_t kTxNodeSetGrowFactor = 2;
|
|
|
|
#define kForward 1
|
|
#define kReversed -1
|
|
|
|
txNodeSet::txNodeSet(txResultRecycler* aRecycler)
|
|
: txAExprResult(aRecycler),
|
|
mStart(nullptr),
|
|
mEnd(nullptr),
|
|
mStartBuffer(nullptr),
|
|
mEndBuffer(nullptr),
|
|
mDirection(kForward),
|
|
mMarks(nullptr)
|
|
{
|
|
}
|
|
|
|
txNodeSet::txNodeSet(const txXPathNode& aNode, txResultRecycler* aRecycler)
|
|
: txAExprResult(aRecycler),
|
|
mStart(nullptr),
|
|
mEnd(nullptr),
|
|
mStartBuffer(nullptr),
|
|
mEndBuffer(nullptr),
|
|
mDirection(kForward),
|
|
mMarks(nullptr)
|
|
{
|
|
if (!ensureGrowSize(1)) {
|
|
return;
|
|
}
|
|
|
|
new(mStart) txXPathNode(aNode);
|
|
++mEnd;
|
|
}
|
|
|
|
txNodeSet::txNodeSet(const txNodeSet& aSource, txResultRecycler* aRecycler)
|
|
: txAExprResult(aRecycler),
|
|
mStart(nullptr),
|
|
mEnd(nullptr),
|
|
mStartBuffer(nullptr),
|
|
mEndBuffer(nullptr),
|
|
mDirection(kForward),
|
|
mMarks(nullptr)
|
|
{
|
|
append(aSource);
|
|
}
|
|
|
|
txNodeSet::~txNodeSet()
|
|
{
|
|
delete [] mMarks;
|
|
|
|
if (mStartBuffer) {
|
|
destroyElements(mStart, mEnd);
|
|
|
|
nsMemory::Free(mStartBuffer);
|
|
}
|
|
}
|
|
|
|
nsresult txNodeSet::add(const txXPathNode& aNode)
|
|
{
|
|
NS_ASSERTION(mDirection == kForward,
|
|
"only append(aNode) is supported on reversed nodesets");
|
|
|
|
if (isEmpty()) {
|
|
return append(aNode);
|
|
}
|
|
|
|
bool dupe;
|
|
txXPathNode* pos = findPosition(aNode, mStart, mEnd, dupe);
|
|
|
|
if (dupe) {
|
|
return NS_OK;
|
|
}
|
|
|
|
// save pos, ensureGrowSize messes with the pointers
|
|
int32_t moveSize = mEnd - pos;
|
|
int32_t offset = pos - mStart;
|
|
if (!ensureGrowSize(1)) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
// set pos to where it was
|
|
pos = mStart + offset;
|
|
|
|
if (moveSize > 0) {
|
|
LOG_CHUNK_MOVE(pos, pos + 1, moveSize);
|
|
memmove(pos + 1, pos, moveSize * sizeof(txXPathNode));
|
|
}
|
|
|
|
new(pos) txXPathNode(aNode);
|
|
++mEnd;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult txNodeSet::add(const txNodeSet& aNodes)
|
|
{
|
|
return add(aNodes, copyElements, nullptr);
|
|
}
|
|
|
|
nsresult txNodeSet::addAndTransfer(txNodeSet* aNodes)
|
|
{
|
|
// failure is out-of-memory, transfer didn't happen
|
|
nsresult rv = add(*aNodes, transferElements, destroyElements);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
#ifdef TX_DONT_RECYCLE_BUFFER
|
|
if (aNodes->mStartBuffer) {
|
|
nsMemory::Free(aNodes->mStartBuffer);
|
|
aNodes->mStartBuffer = aNodes->mEndBuffer = nullptr;
|
|
}
|
|
#endif
|
|
aNodes->mStart = aNodes->mEnd = aNodes->mStartBuffer;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
/**
|
|
* add(aNodeSet, aTransferOp)
|
|
*
|
|
* The code is optimized to make a minimum number of calls to
|
|
* Node::compareDocumentPosition. The idea is this:
|
|
* We have the two nodesets (number indicate "document position")
|
|
*
|
|
* 1 3 7 <- source 1
|
|
* 2 3 6 8 9 <- source 2
|
|
* _ _ _ _ _ _ _ _ <- result
|
|
*
|
|
*
|
|
* When merging these nodesets into the result, the nodes are transfered
|
|
* in chunks to the end of the buffer so that each chunk does not contain
|
|
* a node from the other nodeset, in document order.
|
|
*
|
|
* We select the last non-transfered node in the first nodeset and find
|
|
* where in the other nodeset it would be inserted. In this case we would
|
|
* take the 7 from the first nodeset and find the position between the
|
|
* 6 and 8 in the second. We then take the nodes after the insert-position
|
|
* and transfer them to the end of the resulting nodeset. Which in this case
|
|
* means that we first transfered the 8 and 9 nodes, giving us the following:
|
|
*
|
|
* 1 3 7 <- source 1
|
|
* 2 3 6 <- source 2
|
|
* _ _ _ _ _ _ 8 9 <- result
|
|
*
|
|
* The corresponding procedure is done for the second nodeset, that is
|
|
* the insertion position of the 6 in the first nodeset is found, which
|
|
* is between the 3 and the 7. The 7 is memmoved (as it stays within
|
|
* the same nodeset) to the result buffer.
|
|
*
|
|
* As the result buffer is filled from the end, it is safe to share the
|
|
* buffer between this nodeset and the result.
|
|
*
|
|
* This is repeated until both of the nodesets are empty.
|
|
*
|
|
* If we find a duplicate node when searching for where insertposition we
|
|
* check for sequences of duplicate nodes, which can be optimized.
|
|
*
|
|
*/
|
|
nsresult txNodeSet::add(const txNodeSet& aNodes, transferOp aTransfer,
|
|
destroyOp aDestroy)
|
|
{
|
|
NS_ASSERTION(mDirection == kForward,
|
|
"only append(aNode) is supported on reversed nodesets");
|
|
|
|
if (aNodes.isEmpty()) {
|
|
return NS_OK;
|
|
}
|
|
|
|
if (!ensureGrowSize(aNodes.size())) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
// This is probably a rather common case, so lets try to shortcut.
|
|
if (mStart == mEnd ||
|
|
txXPathNodeUtils::comparePosition(mEnd[-1], *aNodes.mStart) < 0) {
|
|
aTransfer(mEnd, aNodes.mStart, aNodes.mEnd);
|
|
mEnd += aNodes.size();
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
// Last element in this nodeset
|
|
txXPathNode* thisPos = mEnd;
|
|
|
|
// Last element of the other nodeset
|
|
txXPathNode* otherPos = aNodes.mEnd;
|
|
|
|
// Pointer to the insertion point in this nodeset
|
|
txXPathNode* insertPos = mEndBuffer;
|
|
|
|
bool dupe;
|
|
txXPathNode* pos;
|
|
int32_t count;
|
|
while (thisPos > mStart || otherPos > aNodes.mStart) {
|
|
// Find where the last remaining node of this nodeset would
|
|
// be inserted in the other nodeset.
|
|
if (thisPos > mStart) {
|
|
pos = findPosition(thisPos[-1], aNodes.mStart, otherPos, dupe);
|
|
|
|
if (dupe) {
|
|
const txXPathNode *deletePos = thisPos;
|
|
--thisPos; // this is already added
|
|
// check dupe sequence
|
|
while (thisPos > mStart && pos > aNodes.mStart &&
|
|
thisPos[-1] == pos[-1]) {
|
|
--thisPos;
|
|
--pos;
|
|
}
|
|
|
|
if (aDestroy) {
|
|
aDestroy(thisPos, deletePos);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
pos = aNodes.mStart;
|
|
}
|
|
|
|
// Transfer the otherNodes after the insertion point to the result
|
|
count = otherPos - pos;
|
|
if (count > 0) {
|
|
insertPos -= count;
|
|
aTransfer(insertPos, pos, otherPos);
|
|
otherPos -= count;
|
|
}
|
|
|
|
// Find where the last remaining node of the otherNodeset would
|
|
// be inserted in this nodeset.
|
|
if (otherPos > aNodes.mStart) {
|
|
pos = findPosition(otherPos[-1], mStart, thisPos, dupe);
|
|
|
|
if (dupe) {
|
|
const txXPathNode *deletePos = otherPos;
|
|
--otherPos; // this is already added
|
|
// check dupe sequence
|
|
while (otherPos > aNodes.mStart && pos > mStart &&
|
|
otherPos[-1] == pos[-1]) {
|
|
--otherPos;
|
|
--pos;
|
|
}
|
|
|
|
if (aDestroy) {
|
|
aDestroy(otherPos, deletePos);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
pos = mStart;
|
|
}
|
|
|
|
// Move the nodes from this nodeset after the insertion point
|
|
// to the result
|
|
count = thisPos - pos;
|
|
if (count > 0) {
|
|
insertPos -= count;
|
|
LOG_CHUNK_MOVE(pos, insertPos, count);
|
|
memmove(insertPos, pos, count * sizeof(txXPathNode));
|
|
thisPos -= count;
|
|
}
|
|
}
|
|
mStart = insertPos;
|
|
mEnd = mEndBuffer;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
/**
|
|
* Append API
|
|
* These functions should be used with care.
|
|
* They are intended to be used when the caller assures that the resulting
|
|
* nodeset remains in document order.
|
|
* Abuse will break document order, and cause errors in the result.
|
|
* These functions are significantly faster than the add API, as no
|
|
* order info operations will be performed.
|
|
*/
|
|
|
|
nsresult
|
|
txNodeSet::append(const txXPathNode& aNode)
|
|
{
|
|
if (!ensureGrowSize(1)) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
if (mDirection == kForward) {
|
|
new(mEnd) txXPathNode(aNode);
|
|
++mEnd;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
new(--mStart) txXPathNode(aNode);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
txNodeSet::append(const txNodeSet& aNodes)
|
|
{
|
|
NS_ASSERTION(mDirection == kForward,
|
|
"only append(aNode) is supported on reversed nodesets");
|
|
|
|
if (aNodes.isEmpty()) {
|
|
return NS_OK;
|
|
}
|
|
|
|
int32_t appended = aNodes.size();
|
|
if (!ensureGrowSize(appended)) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
copyElements(mEnd, aNodes.mStart, aNodes.mEnd);
|
|
mEnd += appended;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
txNodeSet::mark(int32_t aIndex)
|
|
{
|
|
NS_ASSERTION(aIndex >= 0 && mStart && mEnd - mStart > aIndex,
|
|
"index out of bounds");
|
|
if (!mMarks) {
|
|
int32_t length = size();
|
|
mMarks = new bool[length];
|
|
NS_ENSURE_TRUE(mMarks, NS_ERROR_OUT_OF_MEMORY);
|
|
memset(mMarks, 0, length * sizeof(bool));
|
|
}
|
|
if (mDirection == kForward) {
|
|
mMarks[aIndex] = true;
|
|
}
|
|
else {
|
|
mMarks[size() - aIndex - 1] = true;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
txNodeSet::sweep()
|
|
{
|
|
if (!mMarks) {
|
|
// sweep everything
|
|
clear();
|
|
}
|
|
|
|
int32_t chunk, pos = 0;
|
|
int32_t length = size();
|
|
txXPathNode* insertion = mStartBuffer;
|
|
|
|
while (pos < length) {
|
|
while (pos < length && !mMarks[pos]) {
|
|
// delete unmarked
|
|
mStart[pos].~txXPathNode();
|
|
++pos;
|
|
}
|
|
// find chunk to move
|
|
chunk = 0;
|
|
while (pos < length && mMarks[pos]) {
|
|
++pos;
|
|
++chunk;
|
|
}
|
|
// move chunk
|
|
if (chunk > 0) {
|
|
LOG_CHUNK_MOVE(mStart + pos - chunk, insertion, chunk);
|
|
memmove(insertion, mStart + pos - chunk,
|
|
chunk * sizeof(txXPathNode));
|
|
insertion += chunk;
|
|
}
|
|
}
|
|
mStart = mStartBuffer;
|
|
mEnd = insertion;
|
|
delete [] mMarks;
|
|
mMarks = nullptr;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
txNodeSet::clear()
|
|
{
|
|
destroyElements(mStart, mEnd);
|
|
#ifdef TX_DONT_RECYCLE_BUFFER
|
|
if (mStartBuffer) {
|
|
nsMemory::Free(mStartBuffer);
|
|
mStartBuffer = mEndBuffer = nullptr;
|
|
}
|
|
#endif
|
|
mStart = mEnd = mStartBuffer;
|
|
delete [] mMarks;
|
|
mMarks = nullptr;
|
|
mDirection = kForward;
|
|
}
|
|
|
|
int32_t
|
|
txNodeSet::indexOf(const txXPathNode& aNode, uint32_t aStart) const
|
|
{
|
|
NS_ASSERTION(mDirection == kForward,
|
|
"only append(aNode) is supported on reversed nodesets");
|
|
|
|
if (!mStart || mStart == mEnd) {
|
|
return -1;
|
|
}
|
|
|
|
txXPathNode* pos = mStart + aStart;
|
|
for (; pos < mEnd; ++pos) {
|
|
if (*pos == aNode) {
|
|
return pos - mStart;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
const txXPathNode&
|
|
txNodeSet::get(int32_t aIndex) const
|
|
{
|
|
if (mDirection == kForward) {
|
|
return mStart[aIndex];
|
|
}
|
|
|
|
return mEnd[-aIndex - 1];
|
|
}
|
|
|
|
short
|
|
txNodeSet::getResultType()
|
|
{
|
|
return txAExprResult::NODESET;
|
|
}
|
|
|
|
bool
|
|
txNodeSet::booleanValue()
|
|
{
|
|
return !isEmpty();
|
|
}
|
|
double
|
|
txNodeSet::numberValue()
|
|
{
|
|
nsAutoString str;
|
|
stringValue(str);
|
|
|
|
return txDouble::toDouble(str);
|
|
}
|
|
|
|
void
|
|
txNodeSet::stringValue(nsString& aStr)
|
|
{
|
|
NS_ASSERTION(mDirection == kForward,
|
|
"only append(aNode) is supported on reversed nodesets");
|
|
if (isEmpty()) {
|
|
return;
|
|
}
|
|
txXPathNodeUtils::appendNodeValue(get(0), aStr);
|
|
}
|
|
|
|
const nsString*
|
|
txNodeSet::stringValuePointer()
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
bool txNodeSet::ensureGrowSize(int32_t aSize)
|
|
{
|
|
// check if there is enough place in the buffer as is
|
|
if (mDirection == kForward && aSize <= mEndBuffer - mEnd) {
|
|
return true;
|
|
}
|
|
|
|
if (mDirection == kReversed && aSize <= mStart - mStartBuffer) {
|
|
return true;
|
|
}
|
|
|
|
// check if we just have to align mStart to have enough space
|
|
int32_t oldSize = mEnd - mStart;
|
|
int32_t oldLength = mEndBuffer - mStartBuffer;
|
|
int32_t ensureSize = oldSize + aSize;
|
|
if (ensureSize <= oldLength) {
|
|
// just move the buffer
|
|
txXPathNode* dest = mStartBuffer;
|
|
if (mDirection == kReversed) {
|
|
dest = mEndBuffer - oldSize;
|
|
}
|
|
LOG_CHUNK_MOVE(mStart, dest, oldSize);
|
|
memmove(dest, mStart, oldSize * sizeof(txXPathNode));
|
|
mStart = dest;
|
|
mEnd = dest + oldSize;
|
|
|
|
return true;
|
|
}
|
|
|
|
// This isn't 100% safe. But until someone manages to make a 1gig nodeset
|
|
// it should be ok.
|
|
int32_t newLength = std::max(oldLength, kTxNodeSetMinSize);
|
|
|
|
while (newLength < ensureSize) {
|
|
newLength *= kTxNodeSetGrowFactor;
|
|
}
|
|
|
|
txXPathNode* newArr = static_cast<txXPathNode*>
|
|
(nsMemory::Alloc(newLength *
|
|
sizeof(txXPathNode)));
|
|
if (!newArr) {
|
|
return false;
|
|
}
|
|
|
|
txXPathNode* dest = newArr;
|
|
if (mDirection == kReversed) {
|
|
dest += newLength - oldSize;
|
|
}
|
|
|
|
if (oldSize > 0) {
|
|
LOG_CHUNK_MOVE(mStart, dest, oldSize);
|
|
memcpy(dest, mStart, oldSize * sizeof(txXPathNode));
|
|
}
|
|
|
|
if (mStartBuffer) {
|
|
#ifdef DEBUG
|
|
memset(mStartBuffer, 0,
|
|
(mEndBuffer - mStartBuffer) * sizeof(txXPathNode));
|
|
#endif
|
|
nsMemory::Free(mStartBuffer);
|
|
}
|
|
|
|
mStartBuffer = newArr;
|
|
mEndBuffer = mStartBuffer + newLength;
|
|
mStart = dest;
|
|
mEnd = dest + oldSize;
|
|
|
|
return true;
|
|
}
|
|
|
|
txXPathNode*
|
|
txNodeSet::findPosition(const txXPathNode& aNode, txXPathNode* aFirst,
|
|
txXPathNode* aLast, bool& aDupe) const
|
|
{
|
|
aDupe = false;
|
|
if (aLast - aFirst <= 2) {
|
|
// If we search 2 nodes or less there is no point in further divides
|
|
txXPathNode* pos = aFirst;
|
|
for (; pos < aLast; ++pos) {
|
|
int cmp = txXPathNodeUtils::comparePosition(aNode, *pos);
|
|
if (cmp < 0) {
|
|
return pos;
|
|
}
|
|
|
|
if (cmp == 0) {
|
|
aDupe = true;
|
|
|
|
return pos;
|
|
}
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
// (cannot add two pointers)
|
|
txXPathNode* midpos = aFirst + (aLast - aFirst) / 2;
|
|
int cmp = txXPathNodeUtils::comparePosition(aNode, *midpos);
|
|
if (cmp == 0) {
|
|
aDupe = true;
|
|
|
|
return midpos;
|
|
}
|
|
|
|
if (cmp > 0) {
|
|
return findPosition(aNode, midpos + 1, aLast, aDupe);
|
|
}
|
|
|
|
// midpos excluded as end of range
|
|
|
|
return findPosition(aNode, aFirst, midpos, aDupe);
|
|
}
|
|
|
|
/* static */
|
|
void
|
|
txNodeSet::copyElements(txXPathNode* aDest,
|
|
const txXPathNode* aStart, const txXPathNode* aEnd)
|
|
{
|
|
const txXPathNode* pos = aStart;
|
|
while (pos < aEnd) {
|
|
new(aDest) txXPathNode(*pos);
|
|
++aDest;
|
|
++pos;
|
|
}
|
|
}
|
|
|
|
/* static */
|
|
void
|
|
txNodeSet::transferElements(txXPathNode* aDest,
|
|
const txXPathNode* aStart, const txXPathNode* aEnd)
|
|
{
|
|
LOG_CHUNK_MOVE(aStart, aDest, (aEnd - aStart));
|
|
memcpy(aDest, aStart, (aEnd - aStart) * sizeof(txXPathNode));
|
|
}
|