Beispiel #1
0
bool
IndexKeysIterator::nextImpl(
    store::Item_t& result,
    PlanState& aPlanState) const
{
  store::Item_t    lQName;
  IndexDecl_t      indexDecl;
  store::IndexKey  lKey;

  store::Item_t lKeyNodeName;
  GENV_ITEMFACTORY->createQName(lKeyNodeName,
      static_context::ZORBA_STORE_UNORDERED_MAPS_FN_NS,
      "", "key");

  IndexKeysIteratorState* state;
  DEFAULT_STACK_INIT(IndexKeysIteratorState, state, aPlanState);

  consumeNext(lQName, theChildren[0].getp(), aPlanState);

  if ((indexDecl = theSctx->lookup_index(lQName)) == NULL)
  {
    throw XQUERY_EXCEPTION(
      zerr::ZDDY0021_INDEX_NOT_DECLARED,
      ERROR_PARAMS( lQName->getStringValue() ),
      ERROR_LOC( loc )
    );
  }

  state->theIndex = GENV_STORE.getIndex(lQName);

  if (!state->theIndex)
  {
    throw XQUERY_EXCEPTION(
      zerr::ZDDY0023_INDEX_DOES_NOT_EXIST,
      ERROR_PARAMS( lQName->getStringValue() ),
      ERROR_LOC( loc )
    );
  }

  state->theIter = state->theIndex->keys();

  state->theIter->open();

  // generate result elements of the form
  // <key>
  //   <attribute value="key1_value"/>
  //   <attribute value="key2_value"/>
  //   <attribute value="key3_value"/>
  // </key>
  while (state->theIter->next(lKey))
  {
    IndexUtil::createIndexKeyElement(
        state->theIndex->getSpecification().theIsGeneral,
        result, lKey, static_context::ZORBA_STORE_STATIC_INDEXES_DML_FN_NS
      );
    STACK_PUSH(true, state);
  }

  STACK_END(state);
}
Beispiel #2
0
bool DivideOperation::compute<store::XS_DT_DURATION,store::XS_DOUBLE>
( store::Item_t& result,
  dynamic_context* dctx,
  const TypeManager* tm,
  const QueryLoc* loc,
  const store::Item* i0,
  const store::Item* i1 )
{
  std::unique_ptr<Duration> d;

  if( i1->getDoubleValue().isPosInf() || i1->getDoubleValue().isNegInf() )
  {
    d.reset(new Duration());
  }
  else if ( i1->getDoubleValue().isZero() )
    throw XQUERY_EXCEPTION( err::FODT0002, ERROR_LOC( loc ) );
  else if ( i1->getDoubleValue().isNaN() )
    throw XQUERY_EXCEPTION( err::FOCA0005, ERROR_LOC( loc ) );
  else try {
    d.reset(i0->getDayTimeDurationValue() / i1->getDoubleValue());
  } catch (XQueryException& e) {
    set_source(e, *loc);
    throw;
  }

  return GENV_ITEMFACTORY->createDayTimeDuration(result, d.get());
}
Beispiel #3
0
void areNodeModifiersViolated(
    const static_context* aSctx,
    const store::Item* aTarget,
    const QueryLoc& aLoc)
{
  const store::Collection* lColl = aTarget->getCollection();
  if (lColl != 0 && !lColl->isDynamic()) 
  {
    const StaticallyKnownCollection* lDeclColl = 
    aSctx->lookup_collection(lColl->getName());

    if (lDeclColl == NULL)
    {
      throw XQUERY_EXCEPTION(zerr::ZDDY0001_COLLECTION_NOT_DECLARED,
                             ERROR_PARAMS(lColl->getName()->getStringValue()),
                             ERROR_LOC(aLoc));
    }

    switch(lDeclColl->getNodeModifier()) 
    {
    case StaticContextConsts::read_only:
      throw XQUERY_EXCEPTION(zerr::ZDDY0010_COLLECTION_CONST_NODE_UPDATE,
                             ERROR_PARAMS( lColl->getName()->getStringValue() ),
                             ERROR_LOC(aLoc));

    case StaticContextConsts::mutable_node:
      // good to go
      break;
    }
  }
}
Beispiel #4
0
bool
ZorbaValidateInPlaceIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
  store::Item_t node;

  PlanIteratorState* state;
  store::PUL_t pul;

  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  if (consumeNext(node, theChild.getp(), planState))
  {
    // verify that if the element being revalidated is an element it is the root
    if (node->getNodeKind()==store::StoreConsts::elementNode &&
        node->getParent() &&
        node->getParent()->getNodeKind()!=store::StoreConsts::documentNode)
      throw XQUERY_EXCEPTION( zerr::ZAPI0090_CANNOT_VALIDATE_NON_ROOT, ERROR_LOC( loc ) );

    pul = GENV_ITEMFACTORY->createPendingUpdateList();

    pul->addRevalidate(&loc,node);

    result.transfer(pul);
    STACK_PUSH(true, state);
  }

  STACK_END(state);
}
Beispiel #5
0
bool
DeleteIterator::nextImpl(store::Item_t& result, PlanState& aPlanState) const
{ 
  store::Item_t target;
  std::unique_ptr<store::PUL> pul;

  PlanIteratorState* state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, aPlanState);

  pul.reset(GENV_ITEMFACTORY->createPendingUpdateList());

  while (consumeNext(target, theChild, aPlanState))
  {
    if (!target->isNode())
      throw XQUERY_EXCEPTION( err::XUTY0007, ERROR_LOC( loc ) );

    areNodeModifiersViolated(theSctx, target, loc);

    pul->addDelete(&loc, target);

  }
  result = pul.release();
  STACK_PUSH(true, state);
  STACK_END(state);
}
Beispiel #6
0
void relpath_expr::compute_scripting_kind()
{
  theScriptingKind = UNKNOWN_SCRIPTING_KIND;

  for (unsigned i = 0; i < size(); ++i)
  {
    expr* step = theSteps[i];

    if (step->is_updating())
    {
      throw XQUERY_EXCEPTION(err::XUST0001,
                             ERROR_PARAMS(ZED(XUST0001_Generic)),
                             ERROR_LOC(get_loc()));
    }

    theScriptingKind |= step->get_scripting_detail();
  }

  theScriptingKind &= ~VACUOUS_EXPR;

  if (is_sequential(theScriptingKind))
    theScriptingKind &= ~SIMPLE_EXPR;

  checkScriptingKind();
}
Beispiel #7
0
ModuleInfo* XQueryCompiler::parseInfo(
    std::istream& aXQuery,
    const zstring& aFileName)
{
  parsenode_t lParseNode = parse(aXQuery, aFileName);

  if (typeid (*lParseNode) == typeid (ParseErrorNode))
  {
    ParseErrorNode* pen = static_cast<ParseErrorNode *>(lParseNode.getp());
    throw XQUERY_EXCEPTION_VAR(pen->err, 
    ERROR_PARAMS(pen->msg), ERROR_LOC(pen->get_location()));
  }

  LibraryModule* lLibModule = dynamic_cast<LibraryModule*>(lParseNode.getp());

  zstring lTargetNamespace;

  if (lLibModule)
  {
    ModuleDecl* lDecl = lLibModule->get_decl().getp();
    lTargetNamespace = lDecl->get_target_namespace();
  }

  return new ModuleInfoImpl(lTargetNamespace);
}
/*******************************************************************************
  14.9.2 fn:parse-xml-fragment
********************************************************************************/
bool FnParseXmlFragmentIterator::nextImpl(
    store::Item_t& result,
    PlanState& planState) const
{
  zstring docString;

  FnParseXmlFragmentIteratorState* state;
  DEFAULT_STACK_INIT(FnParseXmlFragmentIteratorState, state, planState);

  if (consumeNext(result, theChildren[0].getp(), planState))
  {
    if (result->isStreamable())
    {
      state->theFragmentStream.theStream = &result->getStream();
    }
    else
    {
      result->getStringValue2(docString);
      state->theFragmentStream.theIss = new std::istringstream(docString.c_str());
      state->theFragmentStream.theStream = state->theFragmentStream.theIss;
    }

    state->theProperties.setBaseUri(theSctx->get_base_uri());
    state->theProperties.setParseExternalParsedEntity(true);
    state->theProperties.setStoreDocument(false);

    state->baseUri = state->theProperties.getBaseUri();    

    // create only one document node holding all fragment nodes
    state->theFragmentStream.only_one_doc_node = 1;
       
    try
    {
      result = GENV.getStore().loadDocument(state->baseUri,
                                            state->docUri,
                                            state->theFragmentStream,
                                            state->theProperties);
    }
    catch ( ZorbaException const &e )
    {
      if ( !state->theProperties.getNoError() )
      {
        XQueryException xe(
          XQUERY_EXCEPTION(err::FODC0006,
          ERROR_PARAMS( "fn:parse-xml-fragment()", e.what() ),
          ERROR_LOC( loc )));

        set_data( xe, e );
        throw xe;
      }
      result = nullptr;
    }

    if (result != NULL)
      STACK_PUSH(true, state);
  } // if 

  STACK_END(state);
}
Beispiel #9
0
bool DivideOperation::compute<store::XS_DT_DURATION, store::XS_DT_DURATION>(
    store::Item_t& result,
    dynamic_context* dctx,
    const TypeManager* tm,
    const QueryLoc* loc,
    const store::Item* i0,
    const store::Item* i1 )
{
  xs_dayTimeDuration otherDTDuration = i1->getDayTimeDurationValue();
  if (otherDTDuration.isZero())  
      throw XQUERY_EXCEPTION( err::FOAR0001, ERROR_LOC(loc));
  xs_decimal d = i0->getDayTimeDurationValue() / otherDTDuration;
  return GENV_ITEMFACTORY->createDecimal(result, d);
}
Beispiel #10
0
bool IntegerDivideOperation::compute<store::XS_DOUBLE,store::XS_DOUBLE>(
    store::Item_t& result,
    dynamic_context* /* dctx */,
    const TypeManager* /* tm */,
    const QueryLoc* loc,
    const store::Item* i0,
    const store::Item* i1 )
{
  xs_double d0 = i0->getDoubleValue();
  xs_double d1 = i1->getDoubleValue();

  if ( d1 == numeric_consts<xs_double>::zero() )
  {
    throw XQUERY_EXCEPTION( err::FOAR0001, ERROR_LOC( loc ) );
  }

  if (i0->isNaN() || i1->isNaN()) 
  {
    throw XQUERY_EXCEPTION(
      err::FOAR0002, ERROR_PARAMS( ZED( DivisionNoNaN ) ), ERROR_LOC( loc )
    );
  }
  if (i0->isPosOrNegInf()) 
  {
    throw XQUERY_EXCEPTION(
      err::FOAR0002, ERROR_PARAMS( ZED( DivisionNoINF ) ), ERROR_LOC( loc )
    );
  }

  if (i0->isPosOrNegInf()) {
    // idiv with +-INF divisor has 0 as result
    return GENV_ITEMFACTORY->createInteger(result, numeric_consts<xs_integer>::zero());
  }

  xs_integer const lInteger( d0 / d1 );
  return GENV_ITEMFACTORY->createInteger (result,  lInteger );
}
Beispiel #11
0
bool
ValidateIterator::nextImpl(store::Item_t& result, PlanState& planState) const 
{
  store::Item_t item;
  store::Item_t tmp;

  PlanIteratorState* aState;
  DEFAULT_STACK_INIT(PlanIteratorState, aState, planState);

  if (consumeNext(item, theChild, planState))
  {
    if (consumeNext(tmp, theChild, planState))
    {
      throw XQUERY_EXCEPTION( err::XQTY0030, ERROR_LOC( loc ) );
      // STACK_PUSH(false, aState); -- THIS IS NEVER REACHED
    }
    else
    {
      STACK_PUSH(Validator::effectiveValidationValue(result,
                                                     item,
                                                     typeName,
                                                     typemgr.getp(),
                                                     validationMode,
                                                     theSctx,
                                                     this->loc),
                 aState);
    }
  }
  else
  {
    throw XQUERY_EXCEPTION( err::XQTY0030, ERROR_LOC( loc ) );
    // STACK_PUSH(false, aState); -- THIS IS NEVER REACHED
  }

  STACK_END (aState);
}
Beispiel #12
0
bool DivideOperation::compute<store::XS_INTEGER,store::XS_INTEGER>(
    store::Item_t& result,
    dynamic_context* /* dctx */,
    const TypeManager* /* tm */,
    const QueryLoc* loc,
    const store::Item* i0,
    const store::Item* i1 )
{
  xs_decimal const ll0(i0->getIntegerValue());
  xs_decimal const ll1(i1->getIntegerValue());
  if ( ll1.sign() == 0 )
  {
    throw XQUERY_EXCEPTION( err::FOAR0001, ERROR_LOC( loc ) );
  }
  return GENV_ITEMFACTORY->createDecimal (result,  ll0 / ll1 );
}
Beispiel #13
0
bool DivideOperation::compute<store::XS_DECIMAL,store::XS_DECIMAL>(
    store::Item_t& result,
    dynamic_context* /*dctx*/,
    const TypeManager* /* tm */,
    const QueryLoc* loc,
    const store::Item* i0,
    const store::Item* i1)
{
  xs_decimal ld0 = i0->getDecimalValue();
  xs_decimal ld1 = i1->getDecimalValue();
  if ( ld1.sign() == 0 )
  {
    throw XQUERY_EXCEPTION( err::FOAR0001, ERROR_LOC( loc ) );
  }
  return GENV_ITEMFACTORY->createDecimal (result,  ld0 / ld1 );
}
Beispiel #14
0
bool XMLtoJSONInternal::nextImpl( store::Item_t& result,
                                  PlanState &planState ) const {
  store::Item_t xml_item;
  options_type options;

  PlanIteratorState *state;
  DEFAULT_STACK_INIT( PlanIteratorState, state, planState );

  ZORBA_ASSERT( theChildren.size() == 2 );
  consumeNext( xml_item, theChildren[1], planState );
  get_options( xml_item, &options );

  consumeNext( xml_item, theChildren[0], planState );
  try {
    options_type::mapped_type const &format_opt = options[ "json-format" ];
    ZORBA_ASSERT( !format_opt.empty() );

    switch ( xml_item->getNodeKind() ) {
      case store::StoreConsts::elementNode:
        if ( format_opt == "Snelson" )
          snelson::xml_to_json( xml_item, &result );
        else if ( format_opt == "JsonML" || format_opt == "JsonML-array" )
          jsonml_array::xml_to_json( xml_item, &result );
        else if ( format_opt == "JsonML-object" )
          jsonml_object::xml_to_json( xml_item, &result );
        else
          ZORBA_ASSERT( false );
        break;
      default:
        throw XQUERY_EXCEPTION(
          zerr::ZJSE0001_NOT_ELEMENT_NODE,
          ERROR_LOC( loc )
        );
    } // switch
  }
  catch ( ZorbaException &e ) {
    set_source( e, loc );
    throw;
  }

  STACK_PUSH( !!result, state );
  STACK_END( state );
}
Beispiel #15
0
void relpath_expr::add_back(expr* step)
{
  if (step->is_updating())
  {
    throw XQUERY_EXCEPTION(err::XUST0001,
                           ERROR_PARAMS(ZED(XUST0001_Generic)),
                           ERROR_LOC(get_loc()));
  }

  theScriptingKind |= step->get_scripting_detail();

  if (theScriptingKind & VACUOUS_EXPR)
    theScriptingKind &= ~VACUOUS_EXPR;

  if (is_sequential(theScriptingKind))
    theScriptingKind &= ~SIMPLE_EXPR;

  checkScriptingKind();

  theSteps.push_back(step);
}
Beispiel #16
0
// ---------------------------------------------------------------------------
//  LoadSchemaErrorHandler: Overrides of the SAX ErrorHandler interface
// ---------------------------------------------------------------------------
void LoadSchemaErrorHandler::error(const XERCES_CPP_NAMESPACE::SAXParseException& e)
{
  zstring system_id, public_id;
  if ( e.getSystemId() )
    system_id = StrX( e.getSystemId() ).localFormOrDefault( "" );
  if ( e.getPublicId() )
    public_id = StrX( e.getPublicId() ).localFormOrDefault( "" );

  theSawErrors = true;
  throw XQUERY_EXCEPTION(
    err::XQST0059,
    ERROR_PARAMS(
      ZED( XQST0059_XercesMessage ),
      e.getLineNumber(),
      e.getColumnNumber(),
      system_id,
      public_id,
      StrX( e.getMessage() ).localFormOrDefault( "" )
    ),
    ERROR_LOC( theQueryLoc )
  );
}
Beispiel #17
0
/******************************************************************************
  Create a dummy main module to wrap a library module.
******************************************************************************/
parsenode_t XQueryCompiler::createMainModule(
    parsenode_t aLibraryModule,
    std::istream& aXQuery,
    const zstring& aFileName)
{
  //get the namespace from the LibraryModule
  LibraryModule* mod_ast = dynamic_cast<LibraryModule *>(&*aLibraryModule);
  if (!mod_ast)
    throw ZORBA_EXCEPTION(zerr::ZAPI0002_XQUERY_COMPILATION_FAILED,
    ERROR_PARAMS(ZED(BadLibraryModule)));

  const zstring& lib_namespace = mod_ast->get_decl()->get_target_namespace();

  URI lURI(lib_namespace);
  if(!lURI.is_absolute())
  {
    throw XQUERY_EXCEPTION(err::XQST0046,
    ERROR_PARAMS(lURI.toString(), ZED(MustBeAbsoluteURI)),
      ERROR_LOC(mod_ast->get_decl()->get_location()));
  }

  // Set up the original query stream as the result of resolving the
  // library module's URI
  aXQuery.clear();
  aXQuery.seekg(0);

  FakeLibraryModuleURLResolver* aFakeResolver =
    new FakeLibraryModuleURLResolver(aFileName, aXQuery);

  theCompilerCB->theRootSctx->add_url_resolver(aFakeResolver);

  // create a dummy main module and parse it
  std::stringstream lDocStream;
  zstring tmp;
  zorba::xml::escape(lib_namespace, &tmp);
  lDocStream << "import module namespace m = '" << tmp << "'; 1";
  return parse(lDocStream, aFileName);
}
Beispiel #18
0
bool EitherNodesOrAtomicsIterator::nextImpl(
    store::Item_t& result,
    PlanState& planState) const
{
  EitherNodesOrAtomicsIteratorState* state;
  DEFAULT_STACK_INIT(EitherNodesOrAtomicsIteratorState, state, planState);

  if (CONSUME(result, 0))
  {
    state->atomics = !result->isNode();

    STACK_PUSH(true, state);

    while (CONSUME(result, 0))
    {
      if (state->atomics == result->isNode())
        throw XQUERY_EXCEPTION(err::XPTY0018, ERROR_LOC(loc));

      STACK_PUSH(true, state);
    }
  }

  STACK_END(state);
}
Beispiel #19
0
void SchemaValidatorImpl::validateAfterUpdate(
    store::Item* item,
    zorba::store::PUL* pul,
    const QueryLoc& loc)
{
  ZORBA_ASSERT(item->isNode());

  TypeManager* typeManager = theSctx->get_typemanager();

  StaticContextConsts::validation_mode_t mode = theSctx->validation_mode();

  if (mode == StaticContextConsts::skip_validation)
    return;

  bool isLax = (mode == StaticContextConsts::lax_validation);

  Schema* schema = typeManager->getSchema();
  if ( !schema )
  {
    // no schema available no change to pul
    return;
  }

  EventSchemaValidator schemaValidator =
      EventSchemaValidator(typeManager,
                           schema->getGrammarPool(),
                           isLax,
                           theLoc);

  switch ( item->getNodeKind() )
  {
  case store::StoreConsts::documentNode:
  {
    //cout << "Validate after update document" << "\n"; cout.flush();

    schemaValidator.startDoc();

    store::NsBindings bindings;
    namespace_context nsCtx = namespace_context(theSctx, bindings);

    std::vector<store::Item_t> typedValues;
    processChildren(pul,
                    nsCtx,
                    typeManager,
                    schemaValidator,
                    item->getChildren(),
                    typedValues,
                    loc);
    
    schemaValidator.endDoc();
    
    //cout << "End Validate after update doc" << "\n"; cout.flush();
    return;
  }
  case store::StoreConsts::elementNode:
  {
    //cout << "Validate after update element" << "\n"; cout.flush();
      
    schemaValidator.startDoc();

    processElement(pul,
                   typeManager,
                   schemaValidator,
                   item,
                   loc);

    schemaValidator.endDoc();

    //cout << "End Validate after update elem" << "\n"; cout.flush();
    return;
  }
  default:
    throw XQUERY_EXCEPTION(
      err::XQDY0061,
      ERROR_PARAMS( ZED( NotDocOrElementNode ) ),
      ERROR_LOC( theLoc )
    );
  }
}
Beispiel #20
0
parsenode_t XQueryCompiler::parse(std::istream& aXQuery, const zstring& aFileName)
{
  // TODO: move these out
  if (Properties::instance().getPrintAST())
  {
    theCompilerCB->theConfig.parse_cb = print_ast_tree;
  }

  std::stringstream xquery_stream;

#ifdef ZORBA_XQUERYX
  char* converted_xquery_str = NULL;
  std::string   xquery_str;
  bool is_xqueryx = false;

  {
    char strtemp[1000];
    do
    {
      strtemp[0] = 0;
      aXQuery.read(strtemp, sizeof(strtemp)-1);
      strtemp[aXQuery.gcount()] = 0;
      xquery_str += strtemp;
    }
    while(aXQuery.gcount() == (sizeof(strtemp)-1));
  }

  XQueryXConvertor* xqxconvertor = GENV.getXQueryXConvertor();

  if(xqxconvertor->isXQueryX((char*)xquery_str.c_str()))
  {
    // identify XQueryX by content:
    // root tag =
    // "<prefix:module ... xmlns:prefix="http://www.w3.org/2005/XQueryX" ... > "

    is_xqueryx = true;
    //translate from xqueryx to xquery using XSLT
    //read all input stream into std::string

    converted_xquery_str = xqxconvertor->XQueryX2XQuery(xquery_str.c_str());

#ifndef NDEBUG
    printf ("\n\n%s", converted_xquery_str);  // debug
#endif
    xquery_stream << converted_xquery_str;
  }
  else
  {
    xquery_stream << xquery_str;
  }
#else // ZORBA_XQUERYX

  xquery_stream << aXQuery.rdbuf();
#endif

  theCompilerCB->setPhase(CompilerCB::PARSING);

  parsenode_t node;
  theCompilerCB->setPhase(CompilerCB::NONE);
  
  bool lXQueryMode = getLanguageMode(xquery_stream);

  if (lXQueryMode)
  {
    xquery_driver lDriver(&*theCompilerCB, xquery_driver::XQUERY_GRAMMAR);
    lDriver.parse_stream(xquery_stream, aFileName);
    node =  lDriver.get_expr();
  }
  else
  {
    xquery_driver lDriver(&*theCompilerCB, xquery_driver::JSONIQ_GRAMMAR);
    lDriver.parse_stream(xquery_stream, aFileName);
    node =  lDriver.get_expr();
  }

#ifdef ZORBA_XQUERYX
  if (is_xqueryx)
  {
    xqxconvertor->freeResult(converted_xquery_str);
  }
#endif



  if (typeid (*node) == typeid (ParseErrorNode))
  {
    ParseErrorNode* pen = static_cast<ParseErrorNode *>(&*node);
    throw XQUERY_EXCEPTION_VAR(pen->err, 
    ERROR_PARAMS(pen->msg), ERROR_LOC(pen->get_location()));
  }

  return node;
}
Beispiel #21
0
bool
TransformIterator::nextImpl(store::Item_t& result, PlanState& aPlanState) const
{
  std::vector<ForVarIter_t>::const_iterator varRefIte; 
  std::vector<ForVarIter_t>::const_iterator varRefEnd;
  store::Item_t pulItem;
  store::Item_t validationPul;
  store::PUL_t pul;
  store::Item_t temp;
  store::Item_t lItem;
  store::Item_t copyNode;
  store::CopyMode copymode;
  bool typePreserve;
  bool nsPreserve;
  bool nsInherit;

  PlanIteratorState* aState;
  DEFAULT_STACK_INIT(PlanIteratorState, aState, aPlanState);

  pul = GENV_ITEMFACTORY->createPendingUpdateList(true);

  typePreserve = (theSctx->construction_mode() == StaticContextConsts::cons_preserve ?
                  true : false);
  nsPreserve = theSctx->preserve_ns();
  nsInherit = theSctx->inherit_ns();

  copymode.set(true, typePreserve, nsPreserve, nsInherit);

  {
    csize numCopyClauses = theCopyClauses.size(); 
    std::vector<store::Item*> copyNodes;
    copyNodes.reserve(numCopyClauses);

    // For each copy var compute the target node and bind that node to all
    // references of the copy var.
    for (csize i = 0; i < numCopyClauses; i++)
    {
      const CopyClause& copyClause = theCopyClauses[i];

      if (!consumeNext(copyNode, copyClause.theInput, aPlanState) ||
          (!copyNode->isNode()
           && !copyNode->isJSONItem()
          ))
      {
        throw XQUERY_EXCEPTION(err::XUTY0013, ERROR_LOC(loc));
      }

      if (consumeNext(temp, copyClause.theInput, aPlanState))
      {
        throw XQUERY_EXCEPTION(err::XUTY0013, ERROR_LOC(loc));
      }

      if (!copyClause.theCopyVars.empty())
      {
        copyNodes.push_back(copyNode->copy(NULL, copymode));

        varRefIte = copyClause.theCopyVars.begin();
        varRefEnd = copyClause.theCopyVars.end();
        for(; varRefIte != varRefEnd; ++varRefIte)
        {
          (*varRefIte)->bind(copyNodes.back(), aPlanState);
        }
      }
    }

    // Generate the PUL for the modify clause. Assumption: Codegen did the
    // check if theModifyIter is an updating expr, empty seq producing expr
    // or an error expr. If a PUL is generated, then apply its updates.
    while (consumeNext(pulItem, theModifyIter, aPlanState))
    {
      if (pulItem->isPul())
      {
        pul->mergeUpdates(pulItem);
      }
    }

    // check that every target node in the lPul is inside the tree rooted
    // at some of the copied nodes.
    pul->checkTransformUpdates(copyNodes);

    // apply the pul
    static_cast<ForVarIterator*>(thePulHolderIter.getp())->bind(pul.getp(), aPlanState);
    consumeNext(temp, theApplyIter, aPlanState);
  }

  // Compute and return the results
  while (consumeNext(result, theReturnIter, aPlanState))
  {
    STACK_PUSH(true, aState); 
  }

  STACK_END (aState);
}
void processOptions(store::Item_t item, store::LoadProperties& props, static_context* theSctx, const QueryLoc& loc)
{
  URI lValidatedBaseUri;
  store::Item_t child, tempItem;

  if (item.getp() == NULL)
    return;

#ifndef ZORBA_NO_XMLSCHEMA
  if (item->isValidated())
  {
    if (item->getNodeName() == NULL
        ||
        item->getNodeName()->getNamespace() != static_context::ZORBA_XML_FN_OPTIONS_NS)
    {
      throw XQUERY_EXCEPTION(zerr::ZXQD0003_INCONSISTENT_PARSE_FRAGMENT_OPTIONS,
                             ERROR_PARAMS(ZED(ParseFragmentInvalidOptions)), ERROR_LOC( loc ));
    }
  }
  else
  {
    tempItem = NULL; // used as the effectiveValidationValue()'s typeName
    Validator::effectiveValidationValue(
        item,
        item,
        tempItem,
        theSctx->get_typemanager(),
        ParseConstants::val_strict,
        theSctx,
        loc);
  }
#endif

  store::Iterator_t children = item->getChildren();
  children->open();

  while (children->next(child))
  {
    if (child->getNodeKind() != store::StoreConsts::elementNode)
      continue;

    if (child->getNodeName()->getLocalName() == "base-uri")
    {
      store::Item_t attr = getFirstAttribute(child);

      try {
        lValidatedBaseUri = URI(attr->getStringValue());
      } catch (ZorbaException const& /* e */) {
        throw XQUERY_EXCEPTION(
          err::FODC0007,
          ERROR_PARAMS( attr->getStringValue() ),
          ERROR_LOC( loc )
        );
      }

      if (!lValidatedBaseUri.is_absolute()) {
        throw XQUERY_EXCEPTION(
          err::FODC0007,
          ERROR_PARAMS( lValidatedBaseUri.toString() ),
          ERROR_LOC( loc )
        );
      }

      props.setBaseUri(attr->getStringValue());
    }
    else if (child->getNodeName()->getLocalName() == "no-error")
      props.setNoError(true);
    else if (child->getNodeName()->getLocalName() == "strip-boundary-space")
      props.setStripWhitespace(true);
    else if (child->getNodeName()->getLocalName() == "schema-validate")
    {
      store::Item_t attr = getFirstAttribute(child);
      if (attr->getStringValue() == "strict")
        props.setSchemaStrictValidate(true);
      else
        props.setSchemaLaxValidate(true);
    }
    else if (child->getNodeName()->getLocalName() == "DTD-validate")
      props.setDTDValidate(true);
    else if (child->getNodeName()->getLocalName() == "DTD-load")
      props.setDTDLoad(true);
    else if (child->getNodeName()->getLocalName() == "default-DTD-attributes")
      props.setDefaultDTDAttributes(true);
    else if (child->getNodeName()->getLocalName() == "parse-external-parsed-entity")
    {
      props.setParseExternalParsedEntity(true);
      store::Item_t attr;
      store::Iterator_t attribs = child->getAttributes();
      attribs->open();
      while (attribs->next(attr))
      {
        if (attr->getNodeName()->getLocalName() == "skip-root-nodes")
          props.setSkipRootNodes(ztd::aton<xs_int>(attr->getStringValue().c_str()));
        else if (attr->getNodeName()->getLocalName() == "skip-top-level-text-nodes")
          props.setSkipTopLevelTextNodes(true);
        else if (attr->getNodeName()->getLocalName() == "error-on-doctype")
          props.setErrorOnDoctype(true);
      }
      attribs->close();
    }
    else if (child->getNodeName()->getLocalName() == "substitute-entities")
      props.setSubstituteEntities(true);
    else if (child->getNodeName()->getLocalName() == "xinclude-substitutions")
      props.setXincludeSubstitutions(true);
    else if (child->getNodeName()->getLocalName() == "remove-redundant-ns")
      props.setRemoveRedundantNS(true);
    else if (child->getNodeName()->getLocalName() == "no-CDATA")
      props.setNoCDATA(true);
    else if (child->getNodeName()->getLocalName() == "no-xinclude-nodes")
      props.setNoXIncludeNodes(true);
    else if (child->getNodeName()->getLocalName() == "no-network-access")
      props.setNoNetworkAccess(true);
  }

  children->close();

  if (props.getSchemaLaxValidate() + props.getSchemaStrictValidate() +
      props.getDTDValidate() + props.getParseExternalParsedEntity() > 1)
  {
    throw XQUERY_EXCEPTION(zerr::ZXQD0003_INCONSISTENT_PARSE_FRAGMENT_OPTIONS,
                           ERROR_PARAMS(ZED(ParseFragmentOptionCombinationNotAllowed)), ERROR_LOC( loc ));
  }
}
Beispiel #23
0
bool
ReplaceIterator::nextImpl(store::Item_t& result, PlanState& aPlanState) const
{
  bool elemParent;
  store::StoreConsts::NodeKind lTargetKind;
  store::StoreConsts::NodeKind lWithKind;
  store::Item_t lWith;
  store::Item_t lTarget;
  store::Item_t lParent;
  store::Item_t temp;
  std::vector<store::Item_t> lNodes(16);
  ulong lNumNodes = 0;
  std::unique_ptr<store::PUL> lPul;

  store::CopyMode lCopyMode;
  bool typePreserve;
  bool nsPreserve;
  bool nsInherit;

  PlanIteratorState* lState;
  DEFAULT_STACK_INIT(PlanIteratorState, lState, aPlanState);
  
  typePreserve = (theSctx->construction_mode() == StaticContextConsts::cons_preserve ?
                  true : false);
  nsPreserve = theSctx->preserve_ns();
  nsInherit = theSctx->inherit_ns();

  lCopyMode.set(theDoCopy, typePreserve, nsPreserve, nsInherit);

  if (!consumeNext(lTarget, theChild0, aPlanState))
    throw XQUERY_EXCEPTION(err::XUDY0027, ERROR_LOC(loc));

  if (consumeNext(temp, theChild0, aPlanState))
    throw XQUERY_EXCEPTION(err::XUTY0008, ERROR_LOC(loc));

  if (!lTarget->isNode())
     throw XQUERY_EXCEPTION(err::XUTY0008, ERROR_LOC(loc));

  lTargetKind = lTarget->getNodeKind();

  if (!( lTargetKind == store::StoreConsts::elementNode ||
         lTargetKind == store::StoreConsts::attributeNode ||
         lTargetKind == store::StoreConsts::textNode ||
         lTargetKind == store::StoreConsts::commentNode ||
         lTargetKind == store::StoreConsts::piNode))
  {
    throw XQUERY_EXCEPTION(err::XUTY0008, ERROR_LOC(loc));
  }

  if (theType == store::UpdateConsts::NODE) // replace node ...
  {
    if (lTarget->getParent() == 0)
    {
      throw XQUERY_EXCEPTION(err::XUDY0009, ERROR_LOC(loc));
    }

    lParent = lTarget->getParent();

    elemParent = (lParent->getNodeKind() == store::StoreConsts::elementNode);

    // Do not preserve the type of the source nodes (we do this here so that
    // we don't have to use the upd::setToUntyped() primitive later, during
    // the application of the PUL).
    if (lCopyMode.theTypePreserve &&
        (!elemParent ||
         lParent->getType()->equals(GENV_TYPESYSTEM.XS_UNTYPED_QNAME)))
      lCopyMode.theTypePreserve = false;
    
    if (lTargetKind == store::StoreConsts::attributeNode)
    {
      while (consumeNext(lWith, theChild1, aPlanState)) 
      {
        if (!lWith->isNode() ||
            lWith->getNodeKind() != store::StoreConsts::attributeNode)
        {
          throw XQUERY_EXCEPTION(err::XUTY0011, ERROR_LOC(loc));
        }

        lWith = lWith->copy(NULL, lCopyMode);

        lNodes[lNumNodes++].transfer(lWith);

        if (lNumNodes == lNodes.size())
          lNodes.resize(2 * lNumNodes);
      }
    }
    else
    {
      while (consumeNext(lWith, theChild1, aPlanState))
      {
        if (!lWith->isNode())
          throw XQUERY_EXCEPTION(err::XUTY0010, ERROR_LOC(loc));

        lWithKind = lWith->getNodeKind();

        if (!(lWithKind == store::StoreConsts::elementNode
              || lWithKind == store::StoreConsts::textNode
              || lWithKind == store::StoreConsts::commentNode
              || lWithKind == store::StoreConsts::piNode))
        {
          throw XQUERY_EXCEPTION(err::XUTY0010, ERROR_LOC(loc));
        }

        lWith = lWith->copy(NULL, lCopyMode);

        lNodes[lNumNodes++].transfer(lWith);

        if (lNumNodes == lNodes.size())
          lNodes.resize(2 * lNumNodes);
      }
    }

    areNodeModifiersViolated(theSctx, lTarget, loc);

    lPul.reset(GENV_ITEMFACTORY->createPendingUpdateList());

    lNodes.resize(lNumNodes);
    lPul->addReplaceNode(&loc, lTarget, lNodes);
  }
  else // replace value of node ...
  {
    lPul.reset(GENV_ITEMFACTORY->createPendingUpdateList());

    zstring content;
    store::Item_t typedVal;
    store::Iterator_t typedIter;
    bool haveContent = false;

    if (consumeNext(lWith, theChild1, aPlanState))
    {
      haveContent = true;

      if (lWith->isAtomic())
      {
        lWith->getStringValue2(content);
      }
      else
      {
        lWith->getTypedValue(typedVal, typedIter);

        if (typedIter == NULL)
        {
          typedVal->getStringValue2(content);
        }
        else
        {
          typedIter->open();

          if (typedIter->next(typedVal))
          {
            typedVal->getStringValue2(content);

            while (typedIter->next(typedVal))
            {
              content += " ";
              typedVal->appendStringValue(content);
            }
          }

          typedIter->close();
        }
      }
      
      while (consumeNext(lWith, theChild1, aPlanState))
      {
        content += " ";

        if (lWith->isAtomic())
        {
          lWith->appendStringValue(content);
        }
        else
        {
          lWith->getTypedValue(typedVal, typedIter);

          if (typedIter == NULL)
          {
            typedVal->appendStringValue(content);
          }
          else
          {
            typedIter->open();

            if (typedIter->next(typedVal))
            {
              typedVal->appendStringValue(content);

              while (typedIter->next(typedVal))
              {
                content += " ";
                typedVal->appendStringValue(content);
              }
            }

            typedIter->close();
          }
        }
      }
    }

    if (lTargetKind == store::StoreConsts::elementNode)
    {
      if (haveContent)
        GENV_ITEMFACTORY->createTextNode(lWith, NULL, content);
      else
        lWith = NULL;

      areNodeModifiersViolated(theSctx, lTarget, loc);

      lPul->addReplaceContent(&loc, lTarget, lWith);
    }
    else
    {
      if (lTargetKind == store::StoreConsts::commentNode &&
          (content.find("--") != zstring::npos || ZA_ENDS_WITH(content, "-")))
      {
        throw XQUERY_EXCEPTION(err::XQDY0072, ERROR_LOC(loc));
      }
      else if (lTargetKind == store::StoreConsts::piNode &&
               content.find("?>") != zstring::npos)
      {
        throw XQUERY_EXCEPTION(err::XQDY0026, ERROR_LOC(loc));
      }

      areNodeModifiersViolated(theSctx, lTarget, loc);

      if (content.empty() && lTargetKind == store::StoreConsts::textNode)
      {
        store::Item_t temp = lTarget;
        lPul->addReplaceValue(&loc, temp, content);
        lPul->addDelete(&loc, lTarget);
      }
      else
      {
        lPul->addReplaceValue(&loc, lTarget, content);
      }
    }
  }

  result = lPul.release();
  STACK_PUSH(true, lState);

  STACK_END (lState);
}
/*******************************************************************************
  14.9.1.1 fn-zorba-xml:canonicalize
********************************************************************************/
bool FnZorbaCanonicalizeIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
  zstring lDocString;
  xmlDocPtr lDoc;
  xmlChar* lResult;
  std::istream* lInstream = NULL;
  char buf[1024];
  store::Item_t tempItem;

  FnZorbaCanonicalizeIteratorState* state;
  DEFAULT_STACK_INIT(FnZorbaCanonicalizeIteratorState, state, planState);
  // Read the XML string
  // if the XML string is a streamable string it will have to be materialized
  // since the libxml2 xmlReadMemory functions can't work with streamable strings
  consumeNext(result, theChildren[0].getp(), planState);

  // read options
  if (theChildren.size() == 2)
  {
    consumeNext(tempItem, theChildren[1].getp(), planState);
    zorba::processOptions(tempItem, state->theProperties, theSctx, loc);
  }

  try
  {
   if (result->isStreamable())
    {
      lInstream = &result->getStream();
      while (lInstream->good())
      {
        lInstream->read(buf, 1024);
        lDocString.append(buf, static_cast<zstring::size_type>(lInstream->gcount()));
      }
    }
    else
    {
      result->getStringValue2(lDocString);  
    }
   int lOptions = XML_PARSE_NOERROR | state->theProperties.toLibXmlOptions();
   lDoc = xmlReadMemory(lDocString.c_str(), lDocString.size(), "input.xml", NULL, lOptions);
    if (!lDoc)
    {
      zstring lErrorMsg;
      lErrorMsg = "\"" + lDocString + "\"";
      throw XQUERY_EXCEPTION(err::FOCZ0001, ERROR_PARAMS("x:canonicalize()", lErrorMsg ), ERROR_LOC(loc));
    }

    xmlC14NDocDumpMemory(lDoc, NULL, 2/*XML_C14N_1_1*/, NULL, 1, &lResult);
    lDocString = zstring((char*)lResult);    
    xmlFree(lResult);
    xmlFreeDoc(lDoc);
  }
  catch ( std::exception const& )
  {
      zstring lErrorMsg;
      lErrorMsg = "\"" + lDocString + "\"";
      throw XQUERY_EXCEPTION(err::FOCZ0001, ERROR_PARAMS("x:canonicalize()", lErrorMsg ), ERROR_LOC(loc));
  }
  STACK_PUSH(GENV_ITEMFACTORY->createString(result, lDocString), state);
  STACK_END(state);
}
bool FnZorbaParseXmlFragmentIterator::nextImpl(
    store::Item_t& result,
    PlanState& planState) const
{
  store::Store& lStore = GENV.getStore();
  zstring docString;
  store::Item_t tempItem;
  bool validated = true;

  FnZorbaParseXmlFragmentIteratorState* state;
  DEFAULT_STACK_INIT(FnZorbaParseXmlFragmentIteratorState, state, planState);

  if (consumeNext(result, theChildren[0].getp(), planState))
  {
    if (result->isStreamable())
    {
      state->theFragmentStream.theStream = &result->getStream();
      state->theFragmentStream.setStreamReleaser(result->getStreamReleaser());
      result->setStreamReleaser(nullptr);
    }
    else
    {
      result->getStringValue2(docString);
      state->theFragmentStream.theIss = new std::istringstream(docString.c_str());
      state->theFragmentStream.theStream = state->theFragmentStream.theIss;
    }

    // read options
    consumeNext(tempItem, theChildren[1].getp(), planState);
    state->theProperties.setBaseUri(theSctx->get_base_uri());
    state->theProperties.setStoreDocument(false);
    state->theProperties.setUseCachedDocument(false);
    processOptions(tempItem, state->theProperties, theSctx, loc);
    state->theProperties.setCreateDocParentLink(false);

    // baseURI serves both as the base URI used by the XML parser
    // to resolve relative entity references within the document,
    // and as the base URI of the document node that is returned.
    state->baseUri = state->theProperties.getBaseUri();
    state->docUri = state->theProperties.getBaseUri();


    ////////////////////////////////////////////////////////////////////////
    // External parsed entity processing
    ////////////////////////////////////////////////////////////////////////
    if (state->theProperties.getParseExternalParsedEntity())
    {
      state->theFragmentStream.root_elements_to_skip =
      state->theProperties.getSkipRootNodes();

      while ( ! state->theFragmentStream.stream_is_consumed())
      {
        try
        {
          result = lStore.loadDocument(state->baseUri,
                                       state->docUri,
                                       state->theFragmentStream,
                                       state->theProperties);
        }
        catch ( ZorbaException const &e )
        {
          if ( !state->theProperties.getNoError() )
          {
            XQueryException xe(
              XQUERY_EXCEPTION(
                err::FODC0006,
                ERROR_PARAMS( "parse-xml:parse()", e.what() ),
                ERROR_LOC( loc )
              )
            );
            set_data( xe, e );
            throw xe;
          }
          result = nullptr;
        }

        if (result == NULL)
          continue;

        // Return the children of document node
        state->theFragmentStream.children = result->getChildren();
        while (state->theFragmentStream.children->next(result) && result != NULL)
        {
          if (state->theProperties.getSkipTopLevelTextNodes() && result->getNodeKind() == store::StoreConsts::textNode)
            continue;

          STACK_PUSH(true, state);
        }
      }
    }
    ////////////////////////////////////////////////////////////////////////
    // XML document processing
    ////////////////////////////////////////////////////////////////////////
    else  // if (!state->theProperties.getEnableExtParsedEntity())
    {
      try 
      {
        result = lStore.loadDocument(state->baseUri, state->docUri, *state->theFragmentStream.theStream, state->theProperties);
      }
      catch ( ZorbaException const &e )
      {
        if ( !state->theProperties.getNoError() )
        {
          XQueryException xe(
            XQUERY_EXCEPTION(
              err::FODC0006,
              ERROR_PARAMS( "parse-xml:parse()", e.what() ),
              ERROR_LOC( loc )
            )
          );
          set_data( xe, e );
          throw xe;
        }
        result = nullptr;
      }

      if (result != NULL)
      {
#ifndef ZORBA_NO_XMLSCHEMA
        if (state->theProperties.getSchemaLaxValidate() ||
            state->theProperties.getSchemaStrictValidate())
        {
          try
          {
            tempItem = NULL; // used as the effectiveValidationValue()'s typeName
            validated = Validator::effectiveValidationValue(
                          result,
                          result,
                          tempItem,
                          theSctx->get_typemanager(),
                          state->theProperties.getSchemaLaxValidate() ? ParseConstants::val_lax : ParseConstants::val_strict,
                          theSctx,
                          this->loc);
          }
          catch (ZorbaException& /*e*/)
          {
            if ( ! state->theProperties.getNoError())
              throw;
            else
            {
              result = NULL;
              validated = false;
            }
          }
        }
#endif
        // Ignore the schema validation options if Zorba is built without schema support

        STACK_PUSH(validated, state);
      } // if (result != NULL)
    } // if (state->theProperties.getEnableExtParsedEntity())
  } // if (consumeNext(result, theChildren[0].getp(), planState))

  STACK_END(state);
}
Beispiel #26
0
bool
SerializeURIIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
  store::Item_t     lItemURI, lItemKey;
  zorba::zstring    lStrValue, lStrKey, lStrRes;
  store::Iterator_t lKeys;
  URI               uri = URI();
  int               lIntPort = 0;
  bool              lHasSchemeField, lHasOpaqueField, lHasNotOpaqueField;

  PlanIteratorState* state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  consumeNext(lItemURI, theChildren[0].getp(), planState);

  lHasSchemeField = lHasOpaqueField = lHasNotOpaqueField = false;
  if(lItemURI->isObject()) {
    lKeys = lItemURI->getObjectKeys();
    if(!lKeys.isNull()){
      lKeys->open();
      while(lKeys->next(lItemKey)){
        lStrKey = lItemKey->getStringValue();
        lStrValue = lItemURI->getObjectValue(lItemKey)->getStringValue();
        if(lStrKey == SCHEME_NAME && !lStrValue.empty()){
          uri.set_scheme(lStrValue);
          lHasSchemeField = true;
        } else if(lStrKey == OPAQUE_PART_NAME && !lStrValue.empty()){
          uri.set_opaque_part(lStrValue);
          lHasOpaqueField = true;
        } else if(lStrKey == AUTHORITY_NAME && !lStrValue.empty()){
          uri.set_reg_based_authority(lStrValue);
          lHasNotOpaqueField = true;
        } else if(lStrKey == USER_INFO_NAME && !lStrValue.empty()){
          uri.set_user_info(lStrValue);
          lHasNotOpaqueField = true;
        } else if(lStrKey == HOST_NAME && !lStrValue.empty()){
          uri.set_host(lStrValue);
          lHasNotOpaqueField = true;
        } else if(lStrKey == PORT_NAME){
          sscanf(lStrValue.str().c_str(), "%d", &lIntPort);
          if(lIntPort != 0){
            uri.set_port(lIntPort);
            lHasNotOpaqueField = true;
          }
        } else if(lStrKey == PATH_NAME && !lStrValue.empty()){
          uri.set_path(lStrValue);
          lHasNotOpaqueField = true;
        } else if(lStrKey == QUERY_NAME){
          uri.set_query(lStrValue);
          lHasNotOpaqueField = true;
        } else if(lStrKey == FRAGMENT_NAME){
          uri.set_fragment(lStrValue);
        }
      }
      lKeys->close();
    }
  }

  // check for errors
  if(lHasOpaqueField && lHasNotOpaqueField)
  {
    throw XQUERY_EXCEPTION(
      zuri::OPAQUE_COMB_NOT_VALID,
      ERROR_LOC( loc )
    );
  }
  if(lHasOpaqueField && !lHasSchemeField)
  {
    throw XQUERY_EXCEPTION(
      zuri::OPAQUE_WITHOUT_SCHEME,
      ERROR_LOC( loc )
    );
  }
  if(lHasSchemeField && !uri.get_encoded_path().empty() && (uri.get_encoded_path().substr(0,1) != "/"))
  {
    throw XQUERY_EXCEPTION(
      zuri::INVALID_ABSOLUTE_PATH,
      ERROR_LOC( loc )
    );
  }
  
  lStrRes = zorba::zstring(uri.toString());
  STACK_PUSH(GENV_ITEMFACTORY->createString(result, lStrRes), state );

  STACK_END (state);
}
Beispiel #27
0
bool
DecodeURIIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
  store::Item_t lString, lDecodePlus, lEncoding;
  zstring       lDecodedString, lCharset;

  PlanIteratorState* state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  consumeNext(lString, theChildren[0].getp(), planState);
  consumeNext(lDecodePlus, theChildren[1].getp(), planState);
  consumeNext(lEncoding, theChildren[2].getp(), planState);

  lString->getStringValue2(lDecodedString);
  lEncoding->getStringValue2(lCharset);

  if (lDecodePlus->getBooleanValue())
  {
    std::replace( lDecodedString.begin(), lDecodedString.end(), '+', ' ' );
  }

  uri::decode(lDecodedString);

  if (transcode::is_necessary(lCharset.c_str()))
  {
    if (!transcode::is_supported(lCharset.c_str()))
    {
      throw XQUERY_EXCEPTION(
        zuri::CHARSET_UNKNOWN,
        ERROR_PARAMS( lCharset ),
        ERROR_LOC( loc )
      );
    }

    try
    {
      transcode::stream<istringstream> lTranscoder(
          lCharset.c_str(),
          lDecodedString.c_str()
        );

      lDecodedString.clear();
      char buf[1024];
      while (lTranscoder.good())
      {
        lTranscoder.read(buf, 1024);
        lDecodedString.append(buf, static_cast<zstring::size_type>(lTranscoder.gcount()));
      }
    }
    catch (ZorbaException& e)
    {
      throw XQUERY_EXCEPTION(
        zerr::ZOSE0006_TRANSCODING_ERROR,
        ERROR_PARAMS( e.what() ),
        ERROR_LOC( loc )
      );
    }
  }

  STACK_PUSH(GENV_ITEMFACTORY->createString(result, lDecodedString), state );

  STACK_END (state);
}
Beispiel #28
0
bool InsertIterator::nextImpl(store::Item_t& result, PlanState& aPlanState) const
{
  store::StoreConsts::NodeKind targetKind;
  bool elemParent;
  bool elemTarget;
  store::Item_t parent;
  store::Item_t target;
  store::Item_t source;
  std::vector<store::Item_t> attrs(16);
  std::vector<store::Item_t> nodes(16);
  ulong numAttrs = 0;
  ulong numNodes = 0;
  std::unique_ptr<store::PUL> pul;
  store::Item_t temp;

  store::CopyMode lCopyMode;
  bool typePreserve;
  bool nsPreserve;
  bool nsInherit;

  PlanIteratorState* state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, aPlanState);

  typePreserve = (theSctx->construction_mode() == StaticContextConsts::cons_preserve ?
                  true : false);
  nsPreserve = theSctx->preserve_ns();
  nsInherit = theSctx->inherit_ns();

  lCopyMode.set(theDoCopy, typePreserve, nsPreserve, nsInherit);
  
  if (!consumeNext(target, theChild1, aPlanState))
    throw XQUERY_EXCEPTION( err::XUDY0027, ERROR_LOC( loc ) );

  if (theType == store::UpdateConsts::BEFORE ||
      theType == store::UpdateConsts::AFTER)
  {
    if (!target->isNode() ||
        target->getNodeKind() == store::StoreConsts::attributeNode ||
        target->getNodeKind() == store::StoreConsts::documentNode)
      throw XQUERY_EXCEPTION( err::XUTY0006, ERROR_LOC( loc ) );

    if (consumeNext(temp, theChild1, aPlanState))
      throw XQUERY_EXCEPTION( err::XUTY0006, ERROR_LOC( loc ) );

    if (target->getParent() == NULL)
      throw XQUERY_EXCEPTION( err::XUDY0029, ERROR_LOC( loc ) );

    parent = target->getParent();

    elemParent = (parent->getNodeKind() == store::StoreConsts::elementNode);

    // Do not preserve the type of the source nodes (we do this here so that
    // we don't have to use the upd::setToUntyped() primitive later, during
    // the application of the PUL).
    if (lCopyMode.theTypePreserve &&
        (!elemParent ||
         parent->getType()->equals(GENV_TYPESYSTEM.XS_UNTYPED_QNAME)))
      lCopyMode.theTypePreserve = false;

    while (consumeNext(source, theChild0, aPlanState))
    {
      ZORBA_FATAL(source->isNode(), "");

      if (source->getNodeKind() == store::StoreConsts::attributeNode)
      {
        if (numNodes > 0)
          throw XQUERY_EXCEPTION( err::XUTY0004, ERROR_LOC( loc ) );

        if (!elemParent)
          throw XQUERY_EXCEPTION( err::XUDY0030, ERROR_LOC( loc ) );

        attrs[numAttrs++].transfer(source);
        if (numAttrs == attrs.size())
          attrs.resize(2 * numAttrs);
      }
      else
      {
        nodes[numNodes++].transfer(source);
        if (numNodes == nodes.size())
          nodes.resize(2 * numNodes);
      }
    }

    areNodeModifiersViolated(theSctx, target, loc);

    pul.reset(GENV_ITEMFACTORY->createPendingUpdateList());

    if (numAttrs > 0)
    {
      attrs.resize(numAttrs);

      for (ulong i = 0; i < numAttrs; ++i)
        attrs[i] = attrs[i]->copy(NULL, lCopyMode);

      pul->addInsertAttributes(&loc, parent, attrs);
    }

    if (numNodes > 0)
    {
      nodes.resize(numNodes);

      for (ulong i = 0; i < numNodes; ++i)
        nodes[i] = nodes[i]->copy(NULL, lCopyMode);

      if (theType == store::UpdateConsts::BEFORE)
        pul->addInsertBefore(&loc, target, nodes);
      else
        pul->addInsertAfter(&loc, target, nodes);
    }

    result = pul.release();
    STACK_PUSH(result != NULL, state);
  }
  else
  {
    if (!target->isNode())
      throw XQUERY_EXCEPTION( err::XUTY0005, ERROR_LOC( loc ) );

    targetKind = target->getNodeKind();

    if (targetKind != store::StoreConsts::documentNode &&
        targetKind != store::StoreConsts::elementNode)
      throw XQUERY_EXCEPTION( err::XUTY0005, ERROR_LOC( loc ) );

    if (consumeNext(temp, theChild1, aPlanState))
      throw XQUERY_EXCEPTION( err::XUTY0005, ERROR_LOC( loc ) );

    elemTarget = (targetKind == store::StoreConsts::elementNode);

    if (lCopyMode.theTypePreserve &&
        (!elemTarget ||
         target->getType()->equals(GENV_TYPESYSTEM.XS_UNTYPED_QNAME)))
      lCopyMode.theTypePreserve = false;

    while (consumeNext(source, theChild0, aPlanState))
    {
      ZORBA_FATAL(source->isNode(), "");

      if (source->getNodeKind() == store::StoreConsts::attributeNode)
      {
        if (numNodes > 0)
          throw XQUERY_EXCEPTION( err::XUTY0004, ERROR_LOC( loc ) );

        if (!elemTarget)
          throw XQUERY_EXCEPTION( err::XUTY0022, ERROR_LOC( loc ) );

        attrs[numAttrs++].transfer(source);
        if (numAttrs == attrs.size())
          attrs.resize(2 * numAttrs);
      }
      else
      {
        nodes[numNodes++].transfer(source);
        if (numNodes == nodes.size())
          nodes.resize(2 * numNodes);
      }
    }

    areNodeModifiersViolated(theSctx, target, loc);

    pul.reset(GENV_ITEMFACTORY->createPendingUpdateList());

    if (numAttrs > 0)
    {
      attrs.resize(numAttrs);

      for (ulong i = 0; i < numAttrs; ++i)
        attrs[i] = attrs[i]->copy(NULL, lCopyMode);

      pul->addInsertAttributes(&loc, target, attrs);
    }

    if (numNodes > 0)
    {
      nodes.resize(numNodes);

      for (ulong i = 0; i < numNodes; ++i)
        nodes[i] = nodes[i]->copy(NULL, lCopyMode);

      if (theType == store::UpdateConsts::INTO)
        pul->addInsertInto(&loc, target, nodes);
      else if (theType == store::UpdateConsts::AS_FIRST_INTO)
        pul->addInsertFirst(&loc, target, nodes);
      else
        pul->addInsertLast(&loc, target, nodes);
    }

    result = pul.release();
    STACK_PUSH(result != NULL, state);
  }

  STACK_END (state);
}
DecimalFormat::DecimalFormat( bool is_default, const store::Item_t& qname,
                              ctor_properties_type const &properties,
                              QueryLoc const &loc ) :
  is_default_( is_default ),
  qname_( qname )
{
  for ( ctor_properties_type::size_type i = 0; i < properties.size() - 1;
        ++i ) {
    for ( ctor_properties_type::size_type j = i + 1; j < properties.size();
          ++j ) {
      if ( i == j )
        continue;
      if ( properties[i].first == properties[j].first ) {
        //
        // XQuery 3.0 4.10: It is a static error for a decimal format
        // declaration to define the same property more than once.
        //
        throw XQUERY_EXCEPTION(
          err::XQST0114,
          ERROR_PARAMS( properties[i].first ),
          ERROR_LOC( loc )
        );
      }
      if ( properties[i].second == properties[j].second ) {
        //
        // Ibid: It is a static error if, for any named or unnamed decimal
        // format, the properties representing characters used in a picture
        // string do not have distinct values.
        //
        throw XQUERY_EXCEPTION(
          err::XQST0098,
          ERROR_PARAMS(
            properties[i].second, properties[i].first, properties[j].first
          ),
          ERROR_LOC( loc )
        );
      }
    } // for ( ... j ... )
  } // for ( ... i ... )

  FOR_EACH( ctor_properties_type, property, properties )
    properties_[ property->first ] = property->second;

  struct property_attribute {
    char const *name;
    bool is_string;
    char const *default_value;
  };

  static property_attribute const attributes[] = {
    { "decimal-separator" , false, "."            },
    { "digit"             , false, "#"            },
    { "grouping-separator", false, ","            },
    { "infinity"          , true , "Infinity"     },
    { "minus-sign"        , false, "-"            },
    { "NaN"               , true , "Nan"          },
    { "pattern-separator" , false, ";"            },
    { "percent"           , false, "%"            },
    { "per-mille"         , false, "\xE2\x80\xB0" },
    { "zero-digit"        , false, "0"            },
    { 0, false, 0 }
  };

  for ( property_attribute const *attr = attributes; attr->name; ++attr ) {
    value_type &value = properties_[ attr->name ];
    if ( value.empty() )
      value = attr->default_value;
    else if ( !attr->is_string && utf8::length( value ) > 1 ) {
      //
      // Ibid: It is a static error for a decimal format declaration to specify
      // a value that is not valid for a given property.
      //
      throw XQUERY_EXCEPTION(
        err::XQST0097,
        ERROR_PARAMS( value, attr->name, ZED( XQST0097_MustBeChar ) ),
        ERROR_LOC( loc )
      );
    }
  }

  //
  // XQuery 3.0 2.1.1: zero-digit specifies the character used for the zero-
  // digit-symbol; the default value is the digit zero (0). This character must
  // be a digit (category Nd in the Unicode property database), and it must
  // have the numeric value zero.
  //
  value_type const &zero_digit = properties_[ "zero-digit" ];
  unicode::code_point const zero_digit_cp = utf8::decode( zero_digit.c_str() );
  unicode::code_point zero_cp;
  if ( !unicode::is_Nd( zero_digit_cp, &zero_cp ) || zero_digit_cp != zero_cp )
    throw XQUERY_EXCEPTION(
      err::XQST0097,
      ERROR_PARAMS( zero_digit, "zero-digit", ZED( XQST0097_MustBeZeroDigit ) ),
      ERROR_LOC( loc )
    );
}
Beispiel #30
0
bool
RenameIterator::nextImpl(store::Item_t& result, PlanState& aPlanState) const
{
  store::StoreConsts::NodeKind lTargetKind;
  store::Item_t lTarget;
  store::Item_t lNewname;
  store::Item_t qnameItem;
  store::Item_t temp;
  std::unique_ptr<store::PUL> lPul;

  PlanIteratorState* lState;
  DEFAULT_STACK_INIT(PlanIteratorState, lState, aPlanState);

  if (!consumeNext(lTarget, theChild0, aPlanState))
  {
    throw XQUERY_EXCEPTION( err::XUDY0027, ERROR_LOC( loc ) );
  }
  
  if (!lTarget->isNode())
    throw XQUERY_EXCEPTION(err::XUTY0012, ERROR_LOC(loc));

  lTargetKind = lTarget->getNodeKind();

  if (!(lTargetKind == store::StoreConsts::elementNode ||
        lTargetKind == store::StoreConsts::attributeNode ||
        lTargetKind == store::StoreConsts::piNode))
  {
    throw XQUERY_EXCEPTION(err::XUTY0012, ERROR_LOC(loc));
  }

  if (consumeNext(temp, theChild0, aPlanState))
  {
    throw XQUERY_EXCEPTION(err::XUTY0012, ERROR_LOC(loc));
  }

  areNodeModifiersViolated(theSctx, lTarget, loc);

  if (!consumeNext(lNewname, theChild1, aPlanState))
  {
    throw XQUERY_EXCEPTION(err::XPTY0004,
      ERROR_PARAMS( ZED( EmptySeqNoCastToQName ) ),
      ERROR_LOC( loc )
    );
  }

  if (consumeNext(temp, theChild1, aPlanState))
  {
    throw XQUERY_EXCEPTION(err::XPTY0004,
      ERROR_PARAMS( ZED( SeqNoCastToQName ) ),
      ERROR_LOC( loc )
    );
  }

  try
  {
    GenericCast::instance()->
    castToQName(qnameItem,
                lNewname,
                theNsCtx.getp(),
                (lTargetKind == store::StoreConsts::attributeNode),
                theSctx->get_typemanager(),
                loc);
  }
  catch (ZorbaException const& e)
  {
    if (e.diagnostic() != err::XPTY0004)
    {
      // the returned error codes are wrong for name casting => they must be changed
      throw XQUERY_EXCEPTION(
        err::XQDY0074, ERROR_PARAMS( "item" ), ERROR_LOC( loc )
      );
    }
    else
    {
      throw;
    }
  }

  lPul.reset(GENV_ITEMFACTORY->createPendingUpdateList());
  lPul->addRename(&loc, lTarget, qnameItem);

  result = lPul.release();
  STACK_PUSH(true, lState);

  STACK_END (lState);
}