nsresult txPatternParser::createKeyPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern) { // check for '(' Literal, Literal ')' if (aLexer.peek()->mType != Token::LITERAL) return NS_ERROR_XPATH_PARSE_FAILURE; const nsDependentSubstring& key = aLexer.nextToken()->Value(); if (aLexer.nextToken()->mType != Token::COMMA && aLexer.peek()->mType != Token::LITERAL) return NS_ERROR_XPATH_PARSE_FAILURE; const nsDependentSubstring& value = aLexer.nextToken()->Value(); if (aLexer.nextToken()->mType != Token::R_PAREN) return NS_ERROR_XPATH_PARSE_FAILURE; const PRUnichar* colon; if (!XMLUtils::isValidQName(PromiseFlatString(key), &colon)) return NS_ERROR_XPATH_PARSE_FAILURE; nsCOMPtr<nsIAtom> prefix, localName; PRInt32 namespaceID; nsresult rv = resolveQName(key, getter_AddRefs(prefix), aContext, getter_AddRefs(localName), namespaceID); if (NS_FAILED(rv)) return rv; aPattern = new txKeyPattern(prefix, localName, namespaceID, value); return aPattern ? NS_OK : NS_ERROR_OUT_OF_MEMORY; }
nsresult txPatternParser::createKeyPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern) { // check for '(' Literal, Literal ')' if (aLexer.peek()->mType != Token::LITERAL) return NS_ERROR_XPATH_PARSE_FAILURE; const nsDependentSubstring& key = aLexer.nextToken()->Value(); if (aLexer.nextToken()->mType != Token::COMMA && aLexer.peek()->mType != Token::LITERAL) return NS_ERROR_XPATH_PARSE_FAILURE; const nsDependentSubstring& value = aLexer.nextToken()->Value(); if (aLexer.nextToken()->mType != Token::R_PAREN) return NS_ERROR_XPATH_PARSE_FAILURE; if (!aContext->allowed(txIParseContext::KEY_FUNCTION)) return NS_ERROR_XSLT_CALL_TO_KEY_NOT_ALLOWED; const char16_t* colon; if (!XMLUtils::isValidQName(key, &colon)) { return NS_ERROR_XPATH_PARSE_FAILURE; } RefPtr<nsAtom> prefix, localName; int32_t namespaceID; nsresult rv = resolveQName(key, getter_AddRefs(prefix), aContext, getter_AddRefs(localName), namespaceID); if (NS_FAILED(rv)) return rv; aPattern = new txKeyPattern(prefix, localName, namespaceID, value); return NS_OK; }
nsresult txPatternParser::createStepPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern) { nsresult rv = NS_OK; bool isAttr = false; Token* tok = aLexer.peek(); if (tok->mType == Token::AXIS_IDENTIFIER) { if (TX_StringEqualsAtom(tok->Value(), nsGkAtoms::attribute)) { isAttr = true; } else if (!TX_StringEqualsAtom(tok->Value(), nsGkAtoms::child)) { // all done already for CHILD_AXIS, for all others // XXX report unexpected axis error return NS_ERROR_XPATH_PARSE_FAILURE; } aLexer.nextToken(); } else if (tok->mType == Token::AT_SIGN) { aLexer.nextToken(); isAttr = true; } txNodeTest* nodeTest; if (aLexer.peek()->mType == Token::CNAME) { tok = aLexer.nextToken(); // resolve QName RefPtr<nsAtom> prefix, lName; int32_t nspace; rv = resolveQName(tok->Value(), getter_AddRefs(prefix), aContext, getter_AddRefs(lName), nspace, true); if (NS_FAILED(rv)) { // XXX error report namespace resolve failed return rv; } uint16_t nodeType = isAttr ? (uint16_t)txXPathNodeType::ATTRIBUTE_NODE : (uint16_t)txXPathNodeType::ELEMENT_NODE; nodeTest = new txNameTest(prefix, lName, nspace, nodeType); } else { rv = createNodeTypeTest(aLexer, &nodeTest); NS_ENSURE_SUCCESS(rv, rv); } nsAutoPtr<txStepPattern> step(new txStepPattern(nodeTest, isAttr)); rv = parsePredicates(step, aLexer, aContext); NS_ENSURE_SUCCESS(rv, rv); aPattern = step.forget(); return NS_OK; }
nsresult txExprParser::createFunctionCall(txExprLexer& lexer, txIParseContext* aContext, Expr** aResult) { *aResult = nsnull; nsAutoPtr<FunctionCall> fnCall; Token* tok = lexer.nextToken(); NS_ASSERTION(tok->mType == Token::FUNCTION_NAME_AND_PAREN, "FunctionCall expected"); //-- compare function names nsCOMPtr<nsIAtom> prefix, lName; PRInt32 namespaceID; nsresult rv = resolveQName(tok->Value(), getter_AddRefs(prefix), aContext, getter_AddRefs(lName), namespaceID); NS_ENSURE_SUCCESS(rv, rv); txCoreFunctionCall::eType type; if (namespaceID == kNameSpaceID_None && txCoreFunctionCall::getTypeFromAtom(lName, type)) { // It is a known built-in function. fnCall = new txCoreFunctionCall(type); NS_ENSURE_TRUE(fnCall, NS_ERROR_OUT_OF_MEMORY); } // check extension functions and xslt if (!fnCall) { rv = aContext->resolveFunctionCall(lName, namespaceID, getter_Transfers(fnCall)); if (rv == NS_ERROR_NOT_IMPLEMENTED) { // this should just happen for unparsed-entity-uri() NS_ASSERTION(!fnCall, "Now is it implemented or not?"); rv = parseParameters(0, lexer, aContext); NS_ENSURE_SUCCESS(rv, rv); *aResult = new txLiteralExpr(tok->Value() + NS_LITERAL_STRING(" not implemented.")); NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); return NS_OK; } NS_ENSURE_SUCCESS(rv, rv); } //-- handle parametes rv = parseParameters(fnCall, lexer, aContext); NS_ENSURE_SUCCESS(rv, rv); *aResult = fnCall.forget(); return NS_OK; }
void XSAXMLScanner::scanRawAttrListforNameSpaces(int attCount) { // Make an initial pass through the list and find any xmlns attributes or // schema attributes. // When we find one, send it off to be used to update the element stack's // namespace mappings. int index = 0; for (index = 0; index < attCount; index++) { // each attribute has the prefix:suffix="value" const KVStringPair* curPair = fRawAttrList->elementAt(index); const XMLCh* rawPtr = curPair->getKey(); // If either the key begins with "xmlns:" or its just plain // "xmlns", then use it to update the map. if (!XMLString::compareNString(rawPtr, XMLUni::fgXMLNSColonString, 6) || XMLString::equals(rawPtr, XMLUni::fgXMLNSString)) { const XMLCh* valuePtr = curPair->getValue(); updateNSMap(rawPtr, valuePtr, fRawAttrColonList[index]); // if the schema URI is seen in the the valuePtr, set the boolean seeXsi if (XMLString::equals(valuePtr, SchemaSymbols::fgURI_XSI)) { fSeeXsi = true; } } } // walk through the list again to deal with "xsi:...." if (fSeeXsi) { // Schema Xsi Type yyyy (e.g. xsi:type="yyyyy") XMLBufBid bbXsi(&fBufMgr); XMLBuffer& fXsiType = bbXsi.getBuffer(); QName attName(fMemoryManager); for (index = 0; index < attCount; index++) { // each attribute has the prefix:suffix="value" const KVStringPair* curPair = fRawAttrList->elementAt(index); const XMLCh* rawPtr = curPair->getKey(); attName.setName(rawPtr, fEmptyNamespaceId); const XMLCh* prefPtr = attName.getPrefix(); // if schema URI has been seen, scan for the schema location and uri // and resolve the schema grammar; or scan for schema type if (resolvePrefix(prefPtr, ElemStack::Mode_Attribute) == fSchemaNamespaceId) { const XMLCh* valuePtr = curPair->getValue(); const XMLCh* suffPtr = attName.getLocalPart(); if (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_TYPE)) { fXsiType.set(valuePtr); } else if (XMLString::equals(suffPtr, SchemaSymbols::fgATT_NILL) && XMLString::equals(valuePtr, SchemaSymbols::fgATTVAL_TRUE)) { ((SchemaValidator*)fValidator)->setNillable(true); } } } if (!fXsiType.isEmpty()) { int colonPos = -1; unsigned int uriId = resolveQName ( fXsiType.getRawBuffer(), fPrefixBuf, ElemStack::Mode_Element, colonPos ); ((SchemaValidator*)fValidator)->setXsiType(fPrefixBuf.getRawBuffer(), fXsiType.getRawBuffer() + colonPos + 1, uriId); } } }
nsresult txPatternParser::createStepPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern) { nsresult rv = NS_OK; MBool isAttr = MB_FALSE; Token* tok = aLexer.peek(); if (tok->mType == Token::AXIS_IDENTIFIER) { if (TX_StringEqualsAtom(tok->Value(), txXPathAtoms::attribute)) { isAttr = MB_TRUE; } else if (!TX_StringEqualsAtom(tok->Value(), txXPathAtoms::child)) { // all done already for CHILD_AXIS, for all others // XXX report unexpected axis error return NS_ERROR_XPATH_PARSE_FAILURE; } aLexer.nextToken(); } else if (tok->mType == Token::AT_SIGN) { aLexer.nextToken(); isAttr = MB_TRUE; } tok = aLexer.nextToken(); txNodeTest* nodeTest; if (tok->mType == Token::CNAME) { // resolve QName nsCOMPtr<nsIAtom> prefix, lName; PRInt32 nspace; rv = resolveQName(tok->Value(), getter_AddRefs(prefix), aContext, getter_AddRefs(lName), nspace, PR_TRUE); if (NS_FAILED(rv)) { // XXX error report namespace resolve failed return rv; } PRUint16 nodeType = isAttr ? (PRUint16)txXPathNodeType::ATTRIBUTE_NODE : (PRUint16)txXPathNodeType::ELEMENT_NODE; nodeTest = new txNameTest(prefix, lName, nspace, nodeType); if (!nodeTest) { return NS_ERROR_OUT_OF_MEMORY; } } else { aLexer.pushBack(); rv = createNodeTypeTest(aLexer, &nodeTest); NS_ENSURE_SUCCESS(rv, rv); } nsAutoPtr<txStepPattern> step(new txStepPattern(nodeTest, isAttr)); if (!step) { delete nodeTest; return NS_ERROR_OUT_OF_MEMORY; } rv = parsePredicates(step, aLexer, aContext); NS_ENSURE_SUCCESS(rv, rv); aPattern = step.forget(); return NS_OK; }
nsresult txExprParser::createLocationStep(txExprLexer& lexer, txIParseContext* aContext, Expr** aExpr) { *aExpr = nullptr; //-- child axis is default LocationStep::LocationStepType axisIdentifier = LocationStep::CHILD_AXIS; nsAutoPtr<txNodeTest> nodeTest; //-- get Axis Identifier or AbbreviatedStep, if present Token* tok = lexer.peek(); switch (tok->mType) { case Token::AXIS_IDENTIFIER: { //-- eat token lexer.nextToken(); nsCOMPtr<nsIAtom> axis = do_GetAtom(tok->Value()); if (axis == nsGkAtoms::ancestor) { axisIdentifier = LocationStep::ANCESTOR_AXIS; } else if (axis == nsGkAtoms::ancestorOrSelf) { axisIdentifier = LocationStep::ANCESTOR_OR_SELF_AXIS; } else if (axis == nsGkAtoms::attribute) { axisIdentifier = LocationStep::ATTRIBUTE_AXIS; } else if (axis == nsGkAtoms::child) { axisIdentifier = LocationStep::CHILD_AXIS; } else if (axis == nsGkAtoms::descendant) { axisIdentifier = LocationStep::DESCENDANT_AXIS; } else if (axis == nsGkAtoms::descendantOrSelf) { axisIdentifier = LocationStep::DESCENDANT_OR_SELF_AXIS; } else if (axis == nsGkAtoms::following) { axisIdentifier = LocationStep::FOLLOWING_AXIS; } else if (axis == nsGkAtoms::followingSibling) { axisIdentifier = LocationStep::FOLLOWING_SIBLING_AXIS; } else if (axis == nsGkAtoms::_namespace) { axisIdentifier = LocationStep::NAMESPACE_AXIS; } else if (axis == nsGkAtoms::parent) { axisIdentifier = LocationStep::PARENT_AXIS; } else if (axis == nsGkAtoms::preceding) { axisIdentifier = LocationStep::PRECEDING_AXIS; } else if (axis == nsGkAtoms::precedingSibling) { axisIdentifier = LocationStep::PRECEDING_SIBLING_AXIS; } else if (axis == nsGkAtoms::self) { axisIdentifier = LocationStep::SELF_AXIS; } else { return NS_ERROR_XPATH_INVALID_AXIS; } break; } case Token::AT_SIGN: //-- eat token lexer.nextToken(); axisIdentifier = LocationStep::ATTRIBUTE_AXIS; break; case Token::PARENT_NODE : //-- eat token lexer.nextToken(); axisIdentifier = LocationStep::PARENT_AXIS; nodeTest = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE); break; case Token::SELF_NODE : //-- eat token lexer.nextToken(); axisIdentifier = LocationStep::SELF_AXIS; nodeTest = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE); break; default: break; } //-- get NodeTest unless an AbbreviatedStep was found nsresult rv = NS_OK; if (!nodeTest) { tok = lexer.peek(); if (tok->mType == Token::CNAME) { lexer.nextToken(); // resolve QName nsCOMPtr<nsIAtom> prefix, lName; int32_t nspace; rv = resolveQName(tok->Value(), getter_AddRefs(prefix), aContext, getter_AddRefs(lName), nspace, true); NS_ENSURE_SUCCESS(rv, rv); nodeTest = new txNameTest(prefix, lName, nspace, axisIdentifier == LocationStep::ATTRIBUTE_AXIS ? static_cast<uint16_t>(txXPathNodeType::ATTRIBUTE_NODE) : static_cast<uint16_t>(txXPathNodeType::ELEMENT_NODE)); } else { rv = createNodeTypeTest(lexer, getter_Transfers(nodeTest)); NS_ENSURE_SUCCESS(rv, rv); } } nsAutoPtr<LocationStep> lstep(new LocationStep(nodeTest, axisIdentifier)); nodeTest.forget(); //-- handle predicates rv = parsePredicates(lstep, lexer, aContext); NS_ENSURE_SUCCESS(rv, rv); *aExpr = lstep.forget(); return NS_OK; }
nsresult txExprParser::createFilterOrStep(txExprLexer& lexer, txIParseContext* aContext, Expr** aResult) { *aResult = nullptr; nsresult rv = NS_OK; Token* tok = lexer.peek(); nsAutoPtr<Expr> expr; switch (tok->mType) { case Token::FUNCTION_NAME_AND_PAREN: rv = createFunctionCall(lexer, aContext, getter_Transfers(expr)); NS_ENSURE_SUCCESS(rv, rv); break; case Token::VAR_REFERENCE : lexer.nextToken(); { nsCOMPtr<nsIAtom> prefix, lName; int32_t nspace; nsresult rv = resolveQName(tok->Value(), getter_AddRefs(prefix), aContext, getter_AddRefs(lName), nspace); NS_ENSURE_SUCCESS(rv, rv); expr = new VariableRefExpr(prefix, lName, nspace); } break; case Token::L_PAREN: lexer.nextToken(); rv = createExpr(lexer, aContext, getter_Transfers(expr)); NS_ENSURE_SUCCESS(rv, rv); if (lexer.peek()->mType != Token::R_PAREN) { return NS_ERROR_XPATH_PAREN_EXPECTED; } lexer.nextToken(); break; case Token::LITERAL : lexer.nextToken(); expr = new txLiteralExpr(tok->Value()); break; case Token::NUMBER: { lexer.nextToken(); expr = new txLiteralExpr(txDouble::toDouble(tok->Value())); break; } default: return createLocationStep(lexer, aContext, aResult); } if (lexer.peek()->mType == Token::L_BRACKET) { nsAutoPtr<FilterExpr> filterExpr(new FilterExpr(expr)); expr.forget(); //-- handle predicates rv = parsePredicates(filterExpr, lexer, aContext); NS_ENSURE_SUCCESS(rv, rv); expr = filterExpr.forget(); } *aResult = expr.forget(); return NS_OK; }