nsresult txPushNewContext::execute(txExecutionState& aEs) { RefPtr<txAExprResult> exprRes; nsresult rv = mSelect->evaluate(aEs.getEvalContext(), getter_AddRefs(exprRes)); NS_ENSURE_SUCCESS(rv, rv); if (exprRes->getResultType() != txAExprResult::NODESET) { // XXX ErrorReport: nodeset expected return NS_ERROR_XSLT_NODESET_EXPECTED; } txNodeSet* nodes = static_cast<txNodeSet*> (static_cast<txAExprResult*> (exprRes)); if (nodes->isEmpty()) { aEs.gotoInstruction(mBailTarget); return NS_OK; } txNodeSorter sorter; uint32_t i, count = mSortKeys.Length(); for (i = 0; i < count; ++i) { SortKey& sort = mSortKeys[i]; rv = sorter.addSortElement(sort.mSelectExpr, sort.mLangExpr, sort.mDataTypeExpr, sort.mOrderExpr, sort.mCaseOrderExpr, aEs.getEvalContext()); NS_ENSURE_SUCCESS(rv, rv); } RefPtr<txNodeSet> sortedNodes; rv = sorter.sortNodeSet(nodes, &aEs, getter_AddRefs(sortedNodes)); NS_ENSURE_SUCCESS(rv, rv); txNodeSetContext* context = new txNodeSetContext(sortedNodes, &aEs); NS_ENSURE_TRUE(context, NS_ERROR_OUT_OF_MEMORY); context->next(); rv = aEs.pushEvalContext(context); if (NS_FAILED(rv)) { delete context; return rv; } return NS_OK; }
/** * Tests one node if it matches any of the keys match-patterns. If * the node matches its values are added to the index. * @param aNode Node to test * @param aKey Key to use when adding into the hash * @param aKeyValueHash Hash to add values to * @param aEs txExecutionState to use for XPath evaluation */ nsresult txXSLKey::testNode(const txXPathNode& aNode, txKeyValueHashKey& aKey, txKeyValueHash& aKeyValueHash, txExecutionState& aEs) { nsAutoString val; uint32_t currKey, numKeys = mKeys.Length(); for (currKey = 0; currKey < numKeys; ++currKey) { if (mKeys[currKey].matchPattern->matches(aNode, &aEs)) { txSingleNodeContext *evalContext = new txSingleNodeContext(aNode, &aEs); NS_ENSURE_TRUE(evalContext, NS_ERROR_OUT_OF_MEMORY); nsresult rv = aEs.pushEvalContext(evalContext); NS_ENSURE_SUCCESS(rv, rv); RefPtr<txAExprResult> exprResult; rv = mKeys[currKey].useExpr->evaluate(evalContext, getter_AddRefs(exprResult)); delete aEs.popEvalContext(); NS_ENSURE_SUCCESS(rv, rv); if (exprResult->getResultType() == txAExprResult::NODESET) { txNodeSet* res = static_cast<txNodeSet*> (static_cast<txAExprResult*> (exprResult)); int32_t i; for (i = 0; i < res->size(); ++i) { val.Truncate(); txXPathNodeUtils::appendNodeValue(res->get(i), val); aKey.mKeyValue.Assign(val); txKeyValueHashEntry* entry = aKeyValueHash.PutEntry(aKey); NS_ENSURE_TRUE(entry && entry->mNodeSet, NS_ERROR_OUT_OF_MEMORY); if (entry->mNodeSet->isEmpty() || entry->mNodeSet->get(entry->mNodeSet->size() - 1) != aNode) { entry->mNodeSet->append(aNode); } } } else { exprResult->stringValue(val); aKey.mKeyValue.Assign(val); txKeyValueHashEntry* entry = aKeyValueHash.PutEntry(aKey); NS_ENSURE_TRUE(entry && entry->mNodeSet, NS_ERROR_OUT_OF_MEMORY); if (entry->mNodeSet->isEmpty() || entry->mNodeSet->get(entry->mNodeSet->size() - 1) != aNode) { entry->mNodeSet->append(aNode); } } } } return NS_OK; }