summaryrefslogtreecommitdiffstats
path: root/dom/xslt/xpath/txCoreFunctionCall.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/xslt/xpath/txCoreFunctionCall.cpp')
-rw-r--r--dom/xslt/xpath/txCoreFunctionCall.cpp666
1 files changed, 666 insertions, 0 deletions
diff --git a/dom/xslt/xpath/txCoreFunctionCall.cpp b/dom/xslt/xpath/txCoreFunctionCall.cpp
new file mode 100644
index 0000000000..9585944e9e
--- /dev/null
+++ b/dom/xslt/xpath/txCoreFunctionCall.cpp
@@ -0,0 +1,666 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 "mozilla/ArrayUtils.h"
+#include "mozilla/FloatingPoint.h"
+
+#include "txExpr.h"
+#include "txNodeSet.h"
+#include "nsGkAtoms.h"
+#include "txIXPathContext.h"
+#include "nsWhitespaceTokenizer.h"
+#include "txXPathTreeWalker.h"
+#include <math.h>
+#include "txStringUtils.h"
+#include "txXMLUtils.h"
+
+using namespace mozilla;
+
+struct txCoreFunctionDescriptor {
+ const int8_t mMinParams;
+ const int8_t mMaxParams;
+ const Expr::ResultType mReturnType;
+ const nsStaticAtom* const mName;
+};
+
+// This must be ordered in the same order as txCoreFunctionCall::eType.
+// If you change one, change the other.
+static const txCoreFunctionDescriptor descriptTable[] = {
+ {1, 1, Expr::NUMBER_RESULT, nsGkAtoms::count}, // COUNT
+ {1, 1, Expr::NODESET_RESULT, nsGkAtoms::id}, // ID
+ {0, 0, Expr::NUMBER_RESULT, nsGkAtoms::last}, // LAST
+ {0, 1, Expr::STRING_RESULT, nsGkAtoms::localName}, // LOCAL_NAME
+ {0, 1, Expr::STRING_RESULT, nsGkAtoms::namespaceUri}, // NAMESPACE_URI
+ {0, 1, Expr::STRING_RESULT, nsGkAtoms::name}, // NAME
+ {0, 0, Expr::NUMBER_RESULT, nsGkAtoms::position}, // POSITION
+
+ {2, -1, Expr::STRING_RESULT, nsGkAtoms::concat}, // CONCAT
+ {2, 2, Expr::BOOLEAN_RESULT, nsGkAtoms::contains}, // CONTAINS
+ {0, 1, Expr::STRING_RESULT, nsGkAtoms::normalizeSpace}, // NORMALIZE_SPACE
+ {2, 2, Expr::BOOLEAN_RESULT, nsGkAtoms::startsWith}, // STARTS_WITH
+ {0, 1, Expr::STRING_RESULT, nsGkAtoms::string}, // STRING
+ {0, 1, Expr::NUMBER_RESULT, nsGkAtoms::stringLength}, // STRING_LENGTH
+ {2, 3, Expr::STRING_RESULT, nsGkAtoms::substring}, // SUBSTRING
+ {2, 2, Expr::STRING_RESULT, nsGkAtoms::substringAfter}, // SUBSTRING_AFTER
+ {2, 2, Expr::STRING_RESULT,
+ nsGkAtoms::substringBefore}, // SUBSTRING_BEFORE
+ {3, 3, Expr::STRING_RESULT, nsGkAtoms::translate}, // TRANSLATE
+
+ {0, 1, Expr::NUMBER_RESULT, nsGkAtoms::number}, // NUMBER
+ {1, 1, Expr::NUMBER_RESULT, nsGkAtoms::round}, // ROUND
+ {1, 1, Expr::NUMBER_RESULT, nsGkAtoms::floor}, // FLOOR
+ {1, 1, Expr::NUMBER_RESULT, nsGkAtoms::ceiling}, // CEILING
+ {1, 1, Expr::NUMBER_RESULT, nsGkAtoms::sum}, // SUM
+
+ {1, 1, Expr::BOOLEAN_RESULT, nsGkAtoms::boolean}, // BOOLEAN
+ {0, 0, Expr::BOOLEAN_RESULT, nsGkAtoms::_false}, // _FALSE
+ {1, 1, Expr::BOOLEAN_RESULT, nsGkAtoms::lang}, // LANG
+ {1, 1, Expr::BOOLEAN_RESULT, nsGkAtoms::_not}, // _NOT
+ {0, 0, Expr::BOOLEAN_RESULT, nsGkAtoms::_true} // _TRUE
+};
+
+/*
+ * Evaluates this Expr based on the given context node and processor state
+ * @param context the context node for evaluation of this Expr
+ * @param ps the ContextState containing the stack information needed
+ * for evaluation
+ * @return the result of the evaluation
+ */
+nsresult txCoreFunctionCall::evaluate(txIEvalContext* aContext,
+ txAExprResult** aResult) {
+ *aResult = nullptr;
+
+ if (!requireParams(descriptTable[mType].mMinParams,
+ descriptTable[mType].mMaxParams, aContext)) {
+ return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
+ }
+
+ nsresult rv = NS_OK;
+ switch (mType) {
+ case COUNT: {
+ RefPtr<txNodeSet> nodes;
+ rv = evaluateToNodeSet(mParams[0], aContext, getter_AddRefs(nodes));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return aContext->recycler()->getNumberResult(nodes->size(), aResult);
+ }
+ case ID: {
+ RefPtr<txAExprResult> exprResult;
+ rv = mParams[0]->evaluate(aContext, getter_AddRefs(exprResult));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ RefPtr<txNodeSet> resultSet;
+ rv = aContext->recycler()->getNodeSet(getter_AddRefs(resultSet));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ txXPathTreeWalker walker(aContext->getContextNode());
+
+ if (exprResult->getResultType() == txAExprResult::NODESET) {
+ txNodeSet* nodes =
+ static_cast<txNodeSet*>(static_cast<txAExprResult*>(exprResult));
+ int32_t i;
+ for (i = 0; i < nodes->size(); ++i) {
+ nsAutoString idList;
+ txXPathNodeUtils::appendNodeValue(nodes->get(i), idList);
+ nsWhitespaceTokenizer tokenizer(idList);
+ while (tokenizer.hasMoreTokens()) {
+ if (walker.moveToElementById(tokenizer.nextToken())) {
+ resultSet->add(walker.getCurrentPosition());
+ }
+ }
+ }
+ } else {
+ nsAutoString idList;
+ exprResult->stringValue(idList);
+ nsWhitespaceTokenizer tokenizer(idList);
+ while (tokenizer.hasMoreTokens()) {
+ if (walker.moveToElementById(tokenizer.nextToken())) {
+ resultSet->add(walker.getCurrentPosition());
+ }
+ }
+ }
+
+ *aResult = resultSet;
+ NS_ADDREF(*aResult);
+
+ return NS_OK;
+ }
+ case LAST: {
+ return aContext->recycler()->getNumberResult(aContext->size(), aResult);
+ }
+ case LOCAL_NAME:
+ case NAME:
+ case NAMESPACE_URI: {
+ // Check for optional arg
+ RefPtr<txNodeSet> nodes;
+ if (!mParams.IsEmpty()) {
+ rv = evaluateToNodeSet(mParams[0], aContext, getter_AddRefs(nodes));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (nodes->isEmpty()) {
+ aContext->recycler()->getEmptyStringResult(aResult);
+
+ return NS_OK;
+ }
+ }
+
+ const txXPathNode& node =
+ nodes ? nodes->get(0) : aContext->getContextNode();
+ switch (mType) {
+ case LOCAL_NAME: {
+ StringResult* strRes = nullptr;
+ rv = aContext->recycler()->getStringResult(&strRes);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ *aResult = strRes;
+ txXPathNodeUtils::getLocalName(node, strRes->mValue);
+
+ return NS_OK;
+ }
+ case NAMESPACE_URI: {
+ StringResult* strRes = nullptr;
+ rv = aContext->recycler()->getStringResult(&strRes);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ *aResult = strRes;
+ txXPathNodeUtils::getNamespaceURI(node, strRes->mValue);
+
+ return NS_OK;
+ }
+ case NAME: {
+ // XXX Namespace: namespaces have a name
+ if (txXPathNodeUtils::isAttribute(node) ||
+ txXPathNodeUtils::isElement(node) ||
+ txXPathNodeUtils::isProcessingInstruction(node)) {
+ StringResult* strRes = nullptr;
+ rv = aContext->recycler()->getStringResult(&strRes);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ *aResult = strRes;
+ txXPathNodeUtils::getNodeName(node, strRes->mValue);
+ } else {
+ aContext->recycler()->getEmptyStringResult(aResult);
+ }
+
+ return NS_OK;
+ }
+ default: {
+ MOZ_CRASH("Unexpected mType?!");
+ }
+ }
+ MOZ_CRASH("Inner mType switch should have returned!");
+ }
+ case POSITION: {
+ return aContext->recycler()->getNumberResult(aContext->position(),
+ aResult);
+ }
+
+ // String functions
+
+ case CONCAT: {
+ RefPtr<StringResult> strRes;
+ rv = aContext->recycler()->getStringResult(getter_AddRefs(strRes));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ uint32_t i, len = mParams.Length();
+ for (i = 0; i < len; ++i) {
+ rv = mParams[i]->evaluateToString(aContext, strRes->mValue);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ NS_ADDREF(*aResult = strRes);
+
+ return NS_OK;
+ }
+ case CONTAINS: {
+ nsAutoString arg2;
+ rv = mParams[1]->evaluateToString(aContext, arg2);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (arg2.IsEmpty()) {
+ aContext->recycler()->getBoolResult(true, aResult);
+ } else {
+ nsAutoString arg1;
+ rv = mParams[0]->evaluateToString(aContext, arg1);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ aContext->recycler()->getBoolResult(FindInReadable(arg2, arg1),
+ aResult);
+ }
+
+ return NS_OK;
+ }
+ case NORMALIZE_SPACE: {
+ nsAutoString resultStr;
+ if (!mParams.IsEmpty()) {
+ rv = mParams[0]->evaluateToString(aContext, resultStr);
+ NS_ENSURE_SUCCESS(rv, rv);
+ } else {
+ txXPathNodeUtils::appendNodeValue(aContext->getContextNode(),
+ resultStr);
+ }
+
+ RefPtr<StringResult> strRes;
+ rv = aContext->recycler()->getStringResult(getter_AddRefs(strRes));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool addSpace = false;
+ bool first = true;
+ strRes->mValue.SetCapacity(resultStr.Length());
+ char16_t c;
+ uint32_t src;
+ for (src = 0; src < resultStr.Length(); src++) {
+ c = resultStr.CharAt(src);
+ if (XMLUtils::isWhitespace(c)) {
+ addSpace = true;
+ } else {
+ if (addSpace && !first) strRes->mValue.Append(char16_t(' '));
+
+ strRes->mValue.Append(c);
+ addSpace = false;
+ first = false;
+ }
+ }
+ *aResult = strRes;
+ NS_ADDREF(*aResult);
+
+ return NS_OK;
+ }
+ case STARTS_WITH: {
+ nsAutoString arg2;
+ rv = mParams[1]->evaluateToString(aContext, arg2);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool result = false;
+ if (arg2.IsEmpty()) {
+ result = true;
+ } else {
+ nsAutoString arg1;
+ rv = mParams[0]->evaluateToString(aContext, arg1);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ result = StringBeginsWith(arg1, arg2);
+ }
+
+ aContext->recycler()->getBoolResult(result, aResult);
+
+ return NS_OK;
+ }
+ case STRING: {
+ RefPtr<StringResult> strRes;
+ rv = aContext->recycler()->getStringResult(getter_AddRefs(strRes));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (!mParams.IsEmpty()) {
+ rv = mParams[0]->evaluateToString(aContext, strRes->mValue);
+ NS_ENSURE_SUCCESS(rv, rv);
+ } else {
+ txXPathNodeUtils::appendNodeValue(aContext->getContextNode(),
+ strRes->mValue);
+ }
+
+ NS_ADDREF(*aResult = strRes);
+
+ return NS_OK;
+ }
+ case STRING_LENGTH: {
+ nsAutoString resultStr;
+ if (!mParams.IsEmpty()) {
+ rv = mParams[0]->evaluateToString(aContext, resultStr);
+ NS_ENSURE_SUCCESS(rv, rv);
+ } else {
+ txXPathNodeUtils::appendNodeValue(aContext->getContextNode(),
+ resultStr);
+ }
+ rv = aContext->recycler()->getNumberResult(resultStr.Length(), aResult);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_OK;
+ }
+ case SUBSTRING: {
+ nsAutoString src;
+ rv = mParams[0]->evaluateToString(aContext, src);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ double start;
+ rv = evaluateToNumber(mParams[1], aContext, &start);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // check for NaN or +/-Inf
+ if (mozilla::IsNaN(start) || mozilla::IsInfinite(start) ||
+ start >= src.Length() + 0.5) {
+ aContext->recycler()->getEmptyStringResult(aResult);
+
+ return NS_OK;
+ }
+
+ start = floor(start + 0.5) - 1;
+
+ double end;
+ if (mParams.Length() == 3) {
+ rv = evaluateToNumber(mParams[2], aContext, &end);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ end += start;
+ if (mozilla::IsNaN(end) || end < 0) {
+ aContext->recycler()->getEmptyStringResult(aResult);
+
+ return NS_OK;
+ }
+
+ if (end > src.Length())
+ end = src.Length();
+ else
+ end = floor(end + 0.5);
+ } else {
+ end = src.Length();
+ }
+
+ if (start < 0) start = 0;
+
+ if (start > end) {
+ aContext->recycler()->getEmptyStringResult(aResult);
+
+ return NS_OK;
+ }
+
+ return aContext->recycler()->getStringResult(
+ Substring(src, (uint32_t)start, (uint32_t)(end - start)), aResult);
+ }
+ case SUBSTRING_AFTER: {
+ nsAutoString arg1;
+ rv = mParams[0]->evaluateToString(aContext, arg1);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsAutoString arg2;
+ rv = mParams[1]->evaluateToString(aContext, arg2);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (arg2.IsEmpty()) {
+ return aContext->recycler()->getStringResult(arg1, aResult);
+ }
+
+ int32_t idx = arg1.Find(arg2);
+ if (idx == kNotFound) {
+ aContext->recycler()->getEmptyStringResult(aResult);
+
+ return NS_OK;
+ }
+
+ const nsAString& result = Substring(arg1, idx + arg2.Length());
+ return aContext->recycler()->getStringResult(result, aResult);
+ }
+ case SUBSTRING_BEFORE: {
+ nsAutoString arg2;
+ rv = mParams[1]->evaluateToString(aContext, arg2);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (arg2.IsEmpty()) {
+ aContext->recycler()->getEmptyStringResult(aResult);
+
+ return NS_OK;
+ }
+
+ nsAutoString arg1;
+ rv = mParams[0]->evaluateToString(aContext, arg1);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ int32_t idx = arg1.Find(arg2);
+ if (idx == kNotFound) {
+ aContext->recycler()->getEmptyStringResult(aResult);
+
+ return NS_OK;
+ }
+
+ return aContext->recycler()->getStringResult(StringHead(arg1, idx),
+ aResult);
+ }
+ case TRANSLATE: {
+ nsAutoString src;
+ rv = mParams[0]->evaluateToString(aContext, src);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (src.IsEmpty()) {
+ aContext->recycler()->getEmptyStringResult(aResult);
+
+ return NS_OK;
+ }
+
+ RefPtr<StringResult> strRes;
+ rv = aContext->recycler()->getStringResult(getter_AddRefs(strRes));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ strRes->mValue.SetCapacity(src.Length());
+
+ nsAutoString oldChars, newChars;
+ rv = mParams[1]->evaluateToString(aContext, oldChars);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = mParams[2]->evaluateToString(aContext, newChars);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ uint32_t i;
+ int32_t newCharsLength = (int32_t)newChars.Length();
+ for (i = 0; i < src.Length(); i++) {
+ int32_t idx = oldChars.FindChar(src.CharAt(i));
+ if (idx != kNotFound) {
+ if (idx < newCharsLength)
+ strRes->mValue.Append(newChars.CharAt((uint32_t)idx));
+ } else {
+ strRes->mValue.Append(src.CharAt(i));
+ }
+ }
+
+ NS_ADDREF(*aResult = strRes);
+
+ return NS_OK;
+ }
+
+ // Number functions
+
+ case NUMBER: {
+ double res;
+ if (!mParams.IsEmpty()) {
+ rv = evaluateToNumber(mParams[0], aContext, &res);
+ NS_ENSURE_SUCCESS(rv, rv);
+ } else {
+ nsAutoString resultStr;
+ txXPathNodeUtils::appendNodeValue(aContext->getContextNode(),
+ resultStr);
+ res = txDouble::toDouble(resultStr);
+ }
+ return aContext->recycler()->getNumberResult(res, aResult);
+ }
+ case ROUND: {
+ double dbl;
+ rv = evaluateToNumber(mParams[0], aContext, &dbl);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (mozilla::IsFinite(dbl)) {
+ if (mozilla::IsNegative(dbl) && dbl >= -0.5) {
+ dbl *= 0;
+ } else {
+ dbl = floor(dbl + 0.5);
+ }
+ }
+
+ return aContext->recycler()->getNumberResult(dbl, aResult);
+ }
+ case FLOOR: {
+ double dbl;
+ rv = evaluateToNumber(mParams[0], aContext, &dbl);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (mozilla::IsFinite(dbl) && !mozilla::IsNegativeZero(dbl))
+ dbl = floor(dbl);
+
+ return aContext->recycler()->getNumberResult(dbl, aResult);
+ }
+ case CEILING: {
+ double dbl;
+ rv = evaluateToNumber(mParams[0], aContext, &dbl);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (mozilla::IsFinite(dbl)) {
+ if (mozilla::IsNegative(dbl) && dbl > -1)
+ dbl *= 0;
+ else
+ dbl = ceil(dbl);
+ }
+
+ return aContext->recycler()->getNumberResult(dbl, aResult);
+ }
+ case SUM: {
+ RefPtr<txNodeSet> nodes;
+ nsresult rv =
+ evaluateToNodeSet(mParams[0], aContext, getter_AddRefs(nodes));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ double res = 0;
+ int32_t i;
+ for (i = 0; i < nodes->size(); ++i) {
+ nsAutoString resultStr;
+ txXPathNodeUtils::appendNodeValue(nodes->get(i), resultStr);
+ res += txDouble::toDouble(resultStr);
+ }
+ return aContext->recycler()->getNumberResult(res, aResult);
+ }
+
+ // Boolean functions
+
+ case BOOLEAN: {
+ bool result;
+ nsresult rv = mParams[0]->evaluateToBool(aContext, result);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ aContext->recycler()->getBoolResult(result, aResult);
+
+ return NS_OK;
+ }
+ case _FALSE: {
+ aContext->recycler()->getBoolResult(false, aResult);
+
+ return NS_OK;
+ }
+ case LANG: {
+ txXPathTreeWalker walker(aContext->getContextNode());
+
+ nsAutoString lang;
+ bool found;
+ do {
+ found = walker.getAttr(nsGkAtoms::lang, kNameSpaceID_XML, lang);
+ } while (!found && walker.moveToParent());
+
+ if (!found) {
+ aContext->recycler()->getBoolResult(false, aResult);
+
+ return NS_OK;
+ }
+
+ nsAutoString arg;
+ rv = mParams[0]->evaluateToString(aContext, arg);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool result =
+ StringBeginsWith(lang, arg, nsCaseInsensitiveStringComparator) &&
+ (lang.Length() == arg.Length() || lang.CharAt(arg.Length()) == '-');
+
+ aContext->recycler()->getBoolResult(result, aResult);
+
+ return NS_OK;
+ }
+ case _NOT: {
+ bool result;
+ rv = mParams[0]->evaluateToBool(aContext, result);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ aContext->recycler()->getBoolResult(!result, aResult);
+
+ return NS_OK;
+ }
+ case _TRUE: {
+ aContext->recycler()->getBoolResult(true, aResult);
+
+ return NS_OK;
+ }
+ }
+
+ aContext->receiveError(u"Internal error"_ns, NS_ERROR_UNEXPECTED);
+ return NS_ERROR_UNEXPECTED;
+}
+
+Expr::ResultType txCoreFunctionCall::getReturnType() {
+ return descriptTable[mType].mReturnType;
+}
+
+bool txCoreFunctionCall::isSensitiveTo(ContextSensitivity aContext) {
+ switch (mType) {
+ case COUNT:
+ case CONCAT:
+ case CONTAINS:
+ case STARTS_WITH:
+ case SUBSTRING:
+ case SUBSTRING_AFTER:
+ case SUBSTRING_BEFORE:
+ case TRANSLATE:
+ case ROUND:
+ case FLOOR:
+ case CEILING:
+ case SUM:
+ case BOOLEAN:
+ case _NOT:
+ case _FALSE:
+ case _TRUE: {
+ return argsSensitiveTo(aContext);
+ }
+ case ID: {
+ return (aContext & NODE_CONTEXT) || argsSensitiveTo(aContext);
+ }
+ case LAST: {
+ return !!(aContext & SIZE_CONTEXT);
+ }
+ case LOCAL_NAME:
+ case NAME:
+ case NAMESPACE_URI:
+ case NORMALIZE_SPACE:
+ case STRING:
+ case STRING_LENGTH:
+ case NUMBER: {
+ if (mParams.IsEmpty()) {
+ return !!(aContext & NODE_CONTEXT);
+ }
+ return argsSensitiveTo(aContext);
+ }
+ case POSITION: {
+ return !!(aContext & POSITION_CONTEXT);
+ }
+ case LANG: {
+ return (aContext & NODE_CONTEXT) || argsSensitiveTo(aContext);
+ }
+ }
+
+ MOZ_ASSERT_UNREACHABLE("how'd we get here?");
+ return true;
+}
+
+// static
+bool txCoreFunctionCall::getTypeFromAtom(nsAtom* aName, eType& aType) {
+ uint32_t i;
+ for (i = 0; i < ArrayLength(descriptTable); ++i) {
+ if (aName == descriptTable[i].mName) {
+ aType = static_cast<eType>(i);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#ifdef TX_TO_STRING
+void txCoreFunctionCall::appendName(nsAString& aDest) {
+ aDest.Append(descriptTable[mType].mName->GetUTF16String());
+}
+#endif