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); }
Sequence FunctionStringToCodepoints::createSequence(DynamicContext* context, int flags) const { Sequence param1 = getParamNumber(1,context)->toSequence(context); if(param1.isEmpty()) return param1; const ATStringOrDerived::Ptr str = (const ATStringOrDerived::Ptr )param1.first(); return str->asCodepoints(context)->toSequence(context); }
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); }
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 FunctionCount::createSequence(DynamicContext* context, int flags) const { Result arg = getParamNumber(1,context); long length = 0; while(arg->next(context).notNull()) { ++length; } return Sequence(context->getItemFactory()->createInteger(length, context), context->getMemoryManager()); }
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()); }
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); }
Sequence FunctionQName::createSequence(DynamicContext* context, int flags) const { Sequence paramURIseq = getParamNumber(1, context)->toSequence(context); Sequence paramLocalseq = getParamNumber(2, context)->toSequence(context); const XMLCh* uri = NULL; if(!paramURIseq.isEmpty()) uri=paramURIseq.first()->asString(context); const XMLCh* local = paramLocalseq.first()->asString(context); if(!XERCES_CPP_NAMESPACE_QUALIFIER XMLChar1_0::isValidQName(local, XERCES_CPP_NAMESPACE_QUALIFIER XMLString::stringLen(local))) XQThrow(FunctionException,X("FunctionQName::createSequence"),X("The second argument to fn:QName is not a valid xs:QName [err:FOCA0002]")); const XMLCh* prefix = XPath2NSUtils::getPrefix(local, context->getMemoryManager()); if((uri==NULL || *uri==0) && !(prefix==NULL || *prefix==0)) XQThrow(FunctionException,X("FunctionQName::createSequence"),X("The second argument to fn:QName specifies a prefix, but the specified uri is empty [err:FOCA0002]")); local = XPath2NSUtils::getLocalName(local); //Construct QName here Sequence result(context->getItemFactory()->createQName(uri, prefix, local, context), context->getMemoryManager()); return result; }
Sequence FunctionSubstring::createSequence(DynamicContext* context, int flags) const { XPath2MemoryManager* memMgr = context->getMemoryManager(); Sequence string=getParamNumber(1, context)->toSequence(context); if(string.isEmpty()) return Sequence(context->getItemFactory()->createString(XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgZeroLenString, context), memMgr); ATStringOrDerived::Ptr str = (const ATStringOrDerived::Ptr )string.first(); Sequence startingLoc=getParamNumber(2,context)->toSequence(context); ATDoubleOrDerived::Ptr index = (const ATDoubleOrDerived::Ptr )startingLoc.first(); ATDoubleOrDerived::Ptr subStrLength; if(getNumArgs()>2) { Sequence length=getParamNumber(3,context)->toSequence(context); subStrLength=(const ATDoubleOrDerived::Ptr )length.first(); } else { subStrLength=(const ATDoubleOrDerived::Ptr )context->getItemFactory()->createDouble((long)((const ATStringOrDerived*)str)->getLength(), context); } return Sequence(((const ATStringOrDerived*)str)->substring(index, subStrLength, context), memMgr); }
Sequence FunctionTimezoneFromDate::createSequence(DynamicContext* context, int flags) const { XPath2MemoryManager* memMgr = context->getMemoryManager(); Sequence arg=getParamNumber(1,context)->toSequence(context); if(arg.isEmpty()) return Sequence(memMgr); const ATDateOrDerived *date = (const ATDateOrDerived*)(const Item*)arg.first(); // If $srcval does not contain a timezone, the result is the empty sequence if (date->hasTimezone() == false) { return Sequence(memMgr); } const Timezone::Ptr timezone = date->getTimezone(); return Sequence( (const Item::Ptr )timezone->asDayTimeDuration(context), memMgr ); }
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); }
Sequence FunctionBaseURI::createSequence(DynamicContext* context, int flags) const { Node::Ptr node = (Node*)getParamNumber(1, context)->next(context).get(); if(node.isNull()) return Sequence(context->getMemoryManager()); return node->dmBaseURI(context); }
Sequence FunctionReplace::createSequence(DynamicContext* context, int flags) const { XPath2MemoryManager* memMgr = context->getMemoryManager(); const XMLCh* input = XMLUni::fgZeroLenString; Item::Ptr inputString = getParamNumber(1,context)->next(context); if(inputString.notNull()) input = inputString->asString(context); const XMLCh *pattern = getParamNumber(2,context)->next(context)->asString(context); const XMLCh *replacement = getParamNumber(3,context)->next(context)->asString(context); const XMLCh *ptr; for(ptr = replacement; *ptr != chNull; ++ptr) { if(*ptr == chDollarSign) { ++ptr; //check that after the '$' is a digit if(!XMLString::isDigit(*ptr)) XQThrow(FunctionException, X("FunctionReplace::createSequence"), X("Invalid replacement pattern - '$' without following digit [err:FORX0004]")); } else if(*ptr == chBackSlash) { ++ptr; //check that after the '\' is a '$' or '\' if(*ptr != chDollarSign && *ptr != chBackSlash) { XQThrow(FunctionException, X("FunctionReplace::createSequence"), X("Invalid replacement pattern - '\\' without following '$' or '\\' [err:FORX0004]")); } } } const XMLCh *options = XMLUni::fgZeroLenString; if(getNumArgs()>3) options=getParamNumber(4,context)->next(context)->asString(context); //Check that the options are valid - throw an exception if not (can have s,m,i and x) //Note: Are allowed to duplicate the letters. const XMLCh* cursor=options; for(; *cursor != 0; ++cursor){ switch(*cursor) { case chLatin_s: case chLatin_m: case chLatin_i: case chLatin_x: break; default: XQThrow(FunctionException, X("FunctionReplace::createSequence"),X("Invalid regular expression flags [err:FORX0001].")); } } // Now attempt to replace try { AutoDeallocate<const XMLCh> result(replace(input, pattern, replacement, options, memMgr), memMgr); return Sequence(context->getItemFactory()->createString(result.get(), context), memMgr); } catch (ParseException &e){ XMLBuffer buf(1023, memMgr); buf.set(X("Invalid regular expression: ")); buf.append(e.getMessage()); buf.append(X(" [err:FORX0002]")); XQThrow(FunctionException, X("FunctionReplace::createSequence"), buf.getRawBuffer()); } catch (RuntimeException &e){ if(e.getCode()==XMLExcepts::Regex_RepPatMatchesZeroString) XQThrow(FunctionException, X("FunctionReplace::createSequence"), X("The pattern matches the zero-length string [err:FORX0003]")); else if(e.getCode()==XMLExcepts::Regex_InvalidRepPattern) XQThrow(FunctionException, X("FunctionReplace::createSequence"), X("Invalid replacement pattern [err:FORX0004]")); else XQThrow(FunctionException, X("FunctionReplace::createSequence"), e.getMessage()); } // Never happens }
Sequence FunctionNormalizeUnicode::createSequence(DynamicContext* context, int flags) const { XPath2MemoryManager* memMgr = context->getMemoryManager(); Sequence strParm=getParamNumber(1,context)->toSequence(context); if(strParm.isEmpty()) { return Sequence(context->getItemFactory()->createString(XMLUni::fgZeroLenString, context), memMgr); } const XMLCh *str = strParm.first()->asString(context); static const XMLCh fg_NFC[] = { chLatin_N, chLatin_F, chLatin_C, chNull }; static const XMLCh fg_NFD[] = { chLatin_N, chLatin_F, chLatin_D, chNull }; static const XMLCh fg_NFKC[] = { chLatin_N, chLatin_F, chLatin_K, chLatin_C, chNull }; static const XMLCh fg_NFKD[] = { chLatin_N, chLatin_F, chLatin_K, chLatin_D, chNull }; static const XMLCh fg_fully[] = { chLatin_F, chLatin_U, chLatin_L, chLatin_L, chLatin_Y, chDash, chLatin_N, chLatin_O, chLatin_R, chLatin_M, chLatin_A, chLatin_L, chLatin_I, chLatin_Z, chLatin_E, chLatin_D, chNull }; const XMLCh* normalization = fg_NFC; if(getNumArgs()==2) { Sequence normParam=getParamNumber(2,context)->toSequence(context); const XMLCh *src = normParam.first()->asString(context); normalization = XPath2Utils::toUpper(src, memMgr); if (XMLString::stringLen(normalization) > 0) { unsigned int i; // remove leading spaces for(i = 0; i < XMLString::stringLen(normalization); i++) { XMLCh ch = normalization[i]; if((ch != 0x9) && (ch != 0xA) && (ch != 0xD) && (ch != 0x20)) break; } const XMLCh *frontChop = XPath2Utils::subString(normalization, i, XPath2Utils::uintStrlen(normalization)-i, memMgr); // remove trailing spaces for(i = XPath2Utils::uintStrlen(frontChop)-1; i !=0 ; i--) { XMLCh ch = frontChop[i]; if((ch != 0x9) && (ch != 0xA) && (ch != 0xD) && (ch != 0x20)) break; } normalization = XPath2Utils::subString(frontChop, 0, i+1, memMgr); } } if(XMLString::stringLen(normalization) == 0) { return Sequence(context->getItemFactory()->createString(str, context), memMgr); } else { AutoDeallocate<XMLCh> buf(0, memMgr); if(XPath2Utils::equals(normalization, fg_NFC)) { buf.set(UnicodeTransformer::normalizeC(str, memMgr)); } else if(XPath2Utils::equals(normalization, fg_NFD)) { buf.set(UnicodeTransformer::normalizeD(str, memMgr)); } else if(XPath2Utils::equals(normalization, fg_NFKC)) { buf.set(UnicodeTransformer::normalizeKC(str, memMgr)); } else if(XPath2Utils::equals(normalization, fg_NFKD)) { buf.set(UnicodeTransformer::normalizeKD(str, memMgr)); } else if(XPath2Utils::equals(normalization, fg_fully)) { XQThrow(FunctionException, X("FunctionNormalizeUnicode::createSequence"), X("Unsupported normalization form [err:FOCH0003].")); } else { XQThrow(FunctionException, X("FunctionNormalizeUnicode::createSequence"), X("Invalid normalization form [err:FOCH0003].")); } return Sequence(context->getItemFactory()->createString(buf.get(), context), memMgr); } // Never reached return Sequence(memMgr); }
BoolResult FunctionEmpty::boolResult(DynamicContext* context) const { return getParamNumber(1,context)->next(context).isNull(); }