Item::Ptr AtomizeResult::next(DynamicContext *context) { // for $item in (Expr) return // typeswitch ($item) // case $value as atomic value return $value // default $node return fn:data($node) Item::Ptr result = _sub->next(context); while(result.isNull()) { _sub = 0; result = _parent->next(context); if(result.isNull()) { _parent = 0; return 0; } if(result->isNode()) { _sub = ((Node*)result.get())->dmTypedValue(context); result = _sub->next(context); } else if(result->isFunction()) { XMLBuffer buf; buf.set(X("Sequence does not match type (xs:anyAtomicType | node())*")); buf.append(X(" - found item of type ")); result->typeToBuffer(context, buf); buf.append(X(" [err:XPTY0004]")); XQThrow(XPath2TypeMatchException, X("AtomizeResult::next"), buf.getRawBuffer()); } } return result; }
Item::Ptr UTransform::TransformResult::next(DynamicContext *context) { context->testInterrupt(); AutoVariableStoreReset reset(context, &scope_); if(toDo_) { toDo_ = false; NodeSet copiedNodes = NodeSet(nodecompare(context)); VectorOfCopyBinding::const_iterator end = transform_->getBindings()->end(); for(VectorOfCopyBinding::const_iterator it = transform_->getBindings()->begin(); it != end; ++it) { if((*it)->qname_ == 0) continue; Sequence values = (*it)->expr_->createResult(context)->toSequence(context); // Keep a record of the nodes that have been copied Result valIt = values; Item::Ptr val; while((val = valIt->next(context)).notNull()) { copiedNodes.insert((Node*)val.get()); } scope_.setVar((*it)->uri_, (*it)->name_, values); } // Get the pending update list PendingUpdateList pul = transform_->getModifyExpr()->createUpdateList(context); // Check that the targets of the pending updates are copied nodes for(PendingUpdateList::const_iterator i = pul.begin(); i != pul.end(); ++i) { Node::Ptr target = i->getTarget(); while(copiedNodes.find(target) == copiedNodes.end()) { target = target->dmParent(context); if(target.isNull()) { XQThrow3(StaticErrorException,X("UTransform::staticTyping"), X("The target node of an update expression in the transform expression is not a node from the copy clauses [err:XUDY0014]"), &(*i)); } } } // Apply the updates AutoDelete<UpdateFactory> ufactory(context->createUpdateFactory()); ufactory->applyUpdates(pul, context, transform_->getRevalidationMode()); // Execute the return expression result_ = transform_->getReturnExpr()->createResult(context); } Item::Ptr result = result_->next(context); if(result.isNull()) { result_ = 0; return 0; } return result; }
Sequence FunctionSentences::createSequence(DynamicContext* context, int flags) const { XPath2MemoryManager* memMgr = context->getMemoryManager(); // If the value of $operand1 is the empty sequence, the empty sequence is returned. Item::Ptr inputString = getParamNumber(1,context)->next(context); if(inputString.isNull()) return Sequence(memMgr); const XMLCh *input=inputString->asString(context); AutoDeallocate<XMLCh> buf(UnicodeTransformer::sentences(input, memMgr), memMgr); XMLCh* rb = buf.get(); XMLCh* start = NULL; Sequence resultSeq(0, memMgr); // Build sequence for (int i = 0; rb[i]; i++) { if (rb[i] != UTF8PROC_SB_MARK) continue; rb[i] = 0; if (rb[i+1] == 0 || rb[i+1] != UTF8PROC_SB_MARK) { if (start != NULL) resultSeq.addItem(context->getItemFactory()->createString(start, context)); start = rb + (i+1); } } return resultSeq; }
Sequence FunctionDoc::createSequence(DynamicContext* context, int flags) const { Item::Ptr uriArg = getParamNumber(1,context)->next(context); if(uriArg.isNull()) { return Sequence(context->getMemoryManager()); } const XMLCh *uri = uriArg->asString(context); // on Windows, we can have URIs using \ instead of /; let's normalize them if(uri != 0) { unsigned int len = XPath2Utils::uintStrlen(uri); AutoDeleteArray<XMLCh> newURI(new XMLCh[len + 1]); const XMLCh *src = uri; XMLCh *dst = newURI; while(*src != 0) { if(*src == '\\') *dst = '/'; else *dst = *src; ++src; ++dst; } *dst = 0; uri = context->getMemoryManager()->getPooledString(newURI); } if(!XPath2Utils::isValidURI(uri, context->getMemoryManager())) XQThrow(FunctionException, X("FunctionDoc::createSequence"), X("Invalid argument to fn:doc function [err:FODC0005]")); return context->resolveDocument(uri, this, context->getProjection() ? queryPathTree_ : 0); }
Result XQContextItem::result(DynamicContext *context, const LocationInfo *info) { const Item::Ptr item = context->getContextItem(); if(item.isNull()) { XQThrow3(DynamicErrorException,X("XQContextItem::result"), X("It is an error for the context item to be undefined when using it [err:XPDY0002]"), info); } return item; }
Sequence FunctionMinutesFromDateTime::createSequence(DynamicContext* context, int flags) const { XPath2MemoryManager* memMgr = context->getMemoryManager(); Item::Ptr arg = getParamNumber(1, context)->next(context); if(arg.isNull()) return Sequence(memMgr); return Sequence(((const ATDateTimeOrDerived*)arg.get())->getMinutes(context), memMgr); }
Result XQContextItem::createResult(DynamicContext* context, int flags) const { const Item::Ptr item = context->getContextItem(); if(item.isNull()) { XQThrow(DynamicErrorException,X("XQContextItem::ContextItemResult::createResult"), X("It is an error for the context item to be undefined when using it [err:XPDY0002]")); } return item; }
Sequence FunctionName::createSequence(DynamicContext* context, int flags) const { XPath2MemoryManager* mm = context->getMemoryManager(); Item::Ptr arg = getParamNumber(1,context)->next(context); if(arg.isNull()) return Sequence(context->getItemFactory()->createString(XMLUni::fgZeroLenString, context), mm); return Sequence(FunctionString::string_item(((Node*)arg.get())->dmNodeName(context), context), mm); }
Sequence FunctionConcat::createSequence(DynamicContext* context, int flags) const { XMLBuffer result; for(unsigned int i = 1; i <= getNumArgs(); ++i) { Item::Ptr item = getParamNumber(i,context)->next(context); if(!item.isNull()) { result.append(item->asString(context)); } } return Sequence(context->getItemFactory()->createString(result.getRawBuffer(), context), context->getMemoryManager()); }
virtual Item::Ptr nextOrTail(Result &tail, DynamicContext *context) { if(_position.isNull()) { _position = (const ATDecimalOrDerived*)_func->getParamNumber(2, context)->next(context).get(); _one = context->getItemFactory()->createInteger(1, context); _i = _one; _target = ClosureResult::create(_func->getArguments()[0], context); if(!_position->greaterThan(_one, context)) { _inserts = _func->getParamNumber(3, context); _doInserts = true; } } Item::Ptr result = 0; while(result.isNull()) { if(_doInserts) { result = _inserts->next(context); if(result.isNull()) { // Tail call optimisation tail = _target; return 0; } } else { result = _target->next(context); _i = _i->add(_one, context); if(result.isNull()) { // Tail call optimisation tail = ClosureResult::create(_func->getArguments()[2], context); return 0; } else if(_position->equals((const AnyAtomicType*)_i.get(), context)) { _inserts = _func->getParamNumber(3, context); _doInserts = true; } } } return result; }
Sequence FunctionCaseFold::createSequence(DynamicContext* context, int flags) const { XPath2MemoryManager *memMgr = context->getMemoryManager(); Item::Ptr arg = getParamNumber(1, context)->next(context); if(arg.isNull()) { return Sequence(context->getItemFactory()->createString(XMLUni::fgZeroLenString, context), memMgr); } AutoDeallocate<XMLCh> buf(UnicodeTransformer::caseFold(arg->asString(context), memMgr), memMgr); return Sequence(context->getItemFactory()->createString(buf.get(), context), memMgr); }
Numeric::Ptr NumericFunction::getNumericParam(unsigned int number, DynamicContext *context, int flags) const { Result arg = XQFunction::getParamNumber(number, context, flags); Item::Ptr item = arg->next(context); if(item.isNull()) { return 0; } else if(item->isAtomicValue() && ((const AnyAtomicType *)item.get())->isNumericValue()) { return (const Numeric *)item.get(); } else { XQThrow(FunctionException,X("NumericFunction::getParamNumber"), X("Non-numeric argument in numeric function [err:XPTY0004]")); } }
Sequence FunctionParseXML::createSequence(DynamicContext* context, int flags) const { Item::Ptr item = getParamNumber(1, context)->next(context); if(item.isNull()) return Sequence(context->getMemoryManager()); const XMLCh *xml = item->asString(context); MemBufInputSource src((XMLByte*)xml, XMLString::stringLen(xml) * sizeof(XMLCh), name); src.setEncoding(XMLUni::fgUTF16EncodingString); try { return Sequence(context->parseDocument(src, this, context->getProjection() ? queryPathTree_ : 0), context->getMemoryManager()); } catch(XMLParseException &e) { XQThrow(FunctionException, X("FunctionParseXML::createSequence"), e.getError()); } }
Sequence FunctionStringLength::createSequence(DynamicContext* context, int flags) const { XPath2MemoryManager *mm = context->getMemoryManager(); Item::Ptr strParm = getParamNumber(1,context)->next(context); if(strParm.isNull()) return Sequence(context->getItemFactory()->createInteger(0, context), mm); const XMLCh *str = strParm->asString(context); long length = 0; while(*str) { ++length; if(RegxUtil::isHighSurrogate(*str)) ++str; ++str; } return Sequence(context->getItemFactory()->createInteger(length, context), mm); }
Item::Ptr next(DynamicContext *context) { Item::Ptr result; while((result = stepResult_->next(context)).isNull()) { context->testInterrupt(); Item::Ptr item = parent_->next(context); if(item.isNull()) { return 0; } if(!item->isNode()) { XQThrow(TypeErrorException,X("StepResult::next"), X("An attempt was made to perform an axis step when the Context Item was not a node [err:XPTY0020]")); } stepResult_ = ((Node*)item.get())->getAxisResult(step_->getAxis(), step_->getNodeTest(), context, this); } return result; }
Item::Ptr SequenceType::TypeMatchesResult::next(DynamicContext *context) { Item::Ptr item = _parent->next(context); if(item.isNull()) { _parent = 0; } else if(!_seqType->getItemType()->matches(item, context)) { XMLBuffer buf; buf.set(X("Sequence does not match type ")); _seqType->toBuffer(buf); buf.append(X(" - found item of type ")); item->typeToBuffer(context, buf); buf.append(X(" [")); buf.append(_errorCode); buf.append(X("]")); XQThrow(XPath2TypeMatchException, X("SequenceType::MatchesResult::next"), buf.getRawBuffer()); } return item; }
virtual Item::Ptr nextOrTail(Result &tail, DynamicContext *context) { Item::Ptr item = result_->next(context); while(item.isNull()) { const ASTNode *ast = *i_; ++i_; if(i_ == ast_->getChildren().end()) { // Tail call optimisation tail = ClosureResult::create(ast, context); return 0; } result_ = ast->createResult(context); item = result_->next(context); } return item; }
Item::Ptr SequenceType::OccurrenceMatchesResult::next(DynamicContext *context) { Item::Ptr item = _parent->next(context); // "SequenceType matching between a given value and a given SequenceType is performed as follows: // If the SequenceType is empty, the match succeeds only if the value is an empty sequence." if(_seqType->getItemType() == NULL && item.notNull()) { XMLBuffer buf; buf.set(X("Sequence does not match type ")); _seqType->toBuffer(buf); buf.append(X(" - the sequence contains items [")); buf.append(X(" [")); buf.append(_errorCode); buf.append(X("]")); XQThrow(XPath2TypeMatchException, X("SequenceType::OccurrenceMatchesResult::next"), buf.getRawBuffer()); } // "If the SequenceType contains an ItemType and an OccurrenceIndicator, the match succeeds only if // the number of items in the value matches the OccurrenceIndicator and each of these items matches the ItemType. " if(_seqType->getItemType() && (_seqType->getOccurrenceIndicator() == PLUS || _seqType->getOccurrenceIndicator() == EXACTLY_ONE) && item.isNull()) { XMLBuffer buf; buf.set(X("Sequence does not match type ")); _seqType->toBuffer(buf); buf.append(X(" - the sequence does not contain items [")); buf.append(_errorCode); buf.append(X("]")); XQThrow(XPath2TypeMatchException, X("SequenceType::OccurrenceMatchesResult::next"), buf.getRawBuffer()); } // "If the SequenceType is an ItemType with no OccurrenceIndicator, the match succeeds only if // the value contains precisely one item and that item matches the ItemType " if(_seqType->getItemType() && (_seqType->getOccurrenceIndicator() == EXACTLY_ONE || _seqType->getOccurrenceIndicator() == QUESTION_MARK) && item.notNull()) { // Do the tests on the number of items up front, // since often functions that cast to a single or // optional item only call next once. - jpcs Item::Ptr second = _parent->next(context); if(second.isNull()) { _parent = 0; } else { XMLBuffer buf; buf.set(X("Sequence does not match type ")); _seqType->toBuffer(buf); buf.append(X(" - the sequence contains more than one item [")); buf.append(_errorCode); buf.append(X("]")); XQThrow(XPath2TypeMatchException, X("SequenceType::OccurrenceMatchesResult::next"), buf.getRawBuffer()); } } if(item.isNull()) { *resultPointer_ = 0; } else { *resultPointer_ = _parent; } return item; }
Sequence FunctionUnparsedText::createSequence(DynamicContext* context, int flags) const { Item::Ptr uriArg = getParamNumber(1, context)->next(context); if(uriArg.isNull()) { return Sequence(context->getMemoryManager()); } const XMLCh *uri = uriArg->asString(context); if(!XPath2Utils::isValidURI(uri, context->getMemoryManager())) XQThrow(FunctionException, X("FunctionUnparsedText::createSequence"), X("The argument to fn:unparsed-text() is not a valid URI [err:XTDE1170]")); // TBD Implement a URIResolver method for resolving unparsed text - jpcs const XMLCh *baseUri = context->getBaseURI(); InputSource *srcToUse = 0; if(context->getXMLEntityResolver()){ XMLResourceIdentifier resourceIdentifier(XMLResourceIdentifier::UnKnown, uri, 0, XMLUni::fgZeroLenString, baseUri); srcToUse = context->getXMLEntityResolver()->resolveEntity(&resourceIdentifier); } if(srcToUse == 0) { try { // Resolve the uri against the base uri XMLURL urlTmp; if(baseUri && *baseUri) { urlTmp.setURL(baseUri, uri); } else { urlTmp.setURL(uri); } srcToUse = new URLInputSource(urlTmp); } catch(const MalformedURLException &e) { } } if(srcToUse == 0) { // It's not a URL, so let's assume it's a local file name. if(baseUri && *baseUri) { AutoDeallocate<XMLCh> tmpBuf(XMLPlatformUtils::weavePaths(baseUri, uri), XMLPlatformUtils::fgMemoryManager); srcToUse = new LocalFileInputSource(tmpBuf); } else { srcToUse = new LocalFileInputSource(uri); } } Janitor<InputSource> janIS(srcToUse); if(getNumArgs() == 2) { const XMLCh *encoding = getParamNumber(2, context)->next(context)->asString(context); srcToUse->setEncoding(encoding); } XMLBuffer result; try { BinInputStream *stream = srcToUse->makeStream(); if(stream == NULL) { XMLBuffer buf; buf.set(X("Cannot read unparsed content from ")); buf.append(uri); buf.append(X(" [err:XTDE1170]")); XQThrow2(FunctionException,X("FunctionUnparsedText::createSequence"), buf.getRawBuffer()); } Janitor<BinInputStream> janStream(stream); #ifdef HAVE_GETCONTENTTYPE if(FunctionMatches::matches(stream->getContentType(), X("(text|application)/(xml|[^ +;]+\\+xml)"), X("i"))) { srcToUse->setEncoding(0); srcToUse->setEncoding(FindXMLEncoding().start(*srcToUse, context)); } #endif XPath2Utils::readSource(stream, context->getMemoryManager(), result, srcToUse->getEncoding()); } catch(XMLException &e) { XMLBuffer buf; buf.set(X("Exception reading unparsed content: ")); buf.append(e.getMessage()); buf.append(X(" [err:XTDE1190]")); XQThrow2(FunctionException,X("FunctionUnparsedText::createSequence"), buf.getRawBuffer()); } return Sequence(context->getItemFactory()->createString(result.getRawBuffer(), context), context->getMemoryManager()); }