Exemple #1
0
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);
}
Exemple #4
0
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);
}
Exemple #5
0
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());
}
Exemple #6
0
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);
}
Exemple #8
0
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;
}
Exemple #9
0
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 );
}
Exemple #11
0
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);
}
Exemple #13
0
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);
}
Exemple #14
0
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);
}
Exemple #16
0
BoolResult FunctionEmpty::boolResult(DynamicContext* context) const
{
  return getParamNumber(1,context)->next(context).isNull();
}