예제 #1
0
FAXPP_Error FaxppParserWrapper::parseInputSource(const InputSource &srcToUse, XPath2MemoryManager *m)
{
  reset();
  mm = m;

  // Create a BinInputStream
  BinInputStream *stream = srcToUse.makeStream();
  if(stream == NULL)
    XQThrow2(XMLParseException, X("FaxppParserWrapper::parseInputSource"), X("Document not found"));
  inputStreams.push_back(stream);

  // Initialize the parse
  FAXPP_Error err = FAXPP_init_parse_callback(parser, binInputStreamReadCallback, stream);

  // Set the correct base URI
  if(err == NO_ERROR && srcToUse.getSystemId()) {
    FAXPP_Text base = { (void*)srcToUse.getSystemId(), (XMLString::stringLen(srcToUse.getSystemId()) + 1) * sizeof(XMLCh) };
    err = FAXPP_set_base_uri(parser, &base);
  }

  // Force use of encoding set on InputSource (this is done by FunctionParseXML)
  if(err == NO_ERROR && srcToUse.getEncoding()) {
    FAXPP_DecodeFunction decode = FAXPP_string_to_decode(UTF8(srcToUse.getEncoding()));
    if(decode == 0) err = UNSUPPORTED_ENCODING;
    else FAXPP_set_decode(parser, decode);
  }
#if 0
  else if(stream->getContentType()) {
  }
#endif

  return err;
}
예제 #2
0
XQQuery *XQQuery::parseModule(const XMLCh *ns, const XMLCh *at, const LocationInfo *location) const
{
  InputSource* srcToUse = 0;
  if(m_context->getDocumentCache()->getXMLEntityResolver()){
    XMLResourceIdentifier resourceIdentifier(XMLResourceIdentifier::UnKnown, at, ns,
                                             XMLUni::fgZeroLenString, m_context->getBaseURI());
    srcToUse = m_context->getDocumentCache()->getXMLEntityResolver()->resolveEntity(&resourceIdentifier);
  }

  if(srcToUse==0) {
    try {
      XMLURL urlTmp(m_context->getBaseURI(), at);
      if (urlTmp.isRelative()) {
        throw MalformedURLException(__FILE__, __LINE__, XMLExcepts::URL_NoProtocolPresent);
      }
      srcToUse = new URLInputSource(urlTmp);
    }
    catch(const MalformedURLException&) {
      // It's not a URL, so let's assume it's a local file name.
      const XMLCh* baseUri=m_context->getBaseURI();
      if(baseUri && baseUri[0]) {
        XMLCh* tmpBuf = XMLPlatformUtils::weavePaths(baseUri, at);
        srcToUse = new LocalFileInputSource(tmpBuf);
        XMLPlatformUtils::fgMemoryManager->deallocate(tmpBuf);
      }
      else {
        srcToUse = new LocalFileInputSource(at);
      }
    }
  }
  Janitor<InputSource> janIS(srcToUse);

  XQQuery *module = m_moduleCache->getByURI(srcToUse->getSystemId());
  if(module) return module;

  AutoDelete<DynamicContext> ctxGuard(m_context->createModuleContext());
  DynamicContext *moduleCtx = ctxGuard.get();

  moduleCtx->setBaseURI(srcToUse->getSystemId());
  moduleCtx->setXMLEntityResolver(m_context->getXMLEntityResolver());

  AutoDelete<XQQuery> moduleGuard(new (XMLPlatformUtils::fgMemoryManager)
                                  XQQuery(ctxGuard.adopt(), true, m_moduleCache, XMLPlatformUtils::fgMemoryManager));
  module = moduleGuard;
  module->setFile(srcToUse->getSystemId());
  module->setModuleTargetNamespace(ns);

  // Put the unparsed module in the cache, to resolve loops correctly
  m_moduleCache->put(moduleGuard.adopt());

  XQilla::parse(*srcToUse, moduleCtx, XQilla::NO_STATIC_RESOLUTION, XMLPlatformUtils::fgMemoryManager, module);

  return module;
}
예제 #3
0
static FAXPP_Error staticEntityCallback(void *userData, FAXPP_Parser *parser, FAXPP_EntityType type,
                                        const FAXPP_Text *base_uri, const FAXPP_Text *systemid, const FAXPP_Text *publicid)
{
  FaxppParserWrapper *fw = (FaxppParserWrapper*)userData;

  try {
    // Resolve the entity
    const XMLCh *system16 = nullTerm(*systemid, fw->mm);
    const XMLCh *public16 = nullTerm(*publicid, fw->mm);

    InputSource* srcToUse = 0;
    if(fw->entityResolver){
      XMLResourceIdentifier resourceIdentifier(XMLResourceIdentifier::ExternalEntity, system16, 0,
                                               public16, (XMLCh*)base_uri->ptr);
      srcToUse = fw->entityResolver->resolveEntity(&resourceIdentifier);
    }

    if(srcToUse == 0) {
      srcToUse = DocumentCacheImpl::resolveURI(system16, (XMLCh*)base_uri->ptr);
    }
    Janitor<InputSource> janIS(srcToUse);

    // Create a BinInputStream
    BinInputStream *stream = srcToUse->makeStream();
    if(stream == NULL)
      return CANT_LOCATE_EXTERNAL_ENTITY;
    fw->inputStreams.push_back(stream);

    FAXPP_Error err = FAXPP_parse_external_entity_callback(parser, type, binInputStreamReadCallback, stream);

    // Set the correct base URI
    if(err == NO_ERROR) {
      FAXPP_Text base = { (void*)srcToUse->getSystemId(), (XMLString::stringLen(srcToUse->getSystemId()) + 1) * sizeof(XMLCh) };
      err = FAXPP_set_base_uri(parser, &base);
    }

    // Force use of encoding set on InputSource (this is done by FunctionParseXML)
    if(err == NO_ERROR && srcToUse->getEncoding()) {
      FAXPP_DecodeFunction decode = FAXPP_string_to_decode(UTF8(srcToUse->getEncoding()));
      if(decode == 0) err = UNSUPPORTED_ENCODING;
      else FAXPP_set_decode(parser, decode);
    }

    return err;
  }
  catch(...) {
    return CANT_LOCATE_EXTERNAL_ENTITY;
  }
}
예제 #4
0
// ---------------------------------------------------------------------------
//  XSAXMLScanner: XMLScanner virtual methods
// ---------------------------------------------------------------------------
//  This method will reset the scanner data structures, and related plugged
//  in stuff, for a new scan session. We get the input source for the primary
//  XML entity, create the reader for it, and push it on the stack so that
//  upon successful return from here we are ready to go.
void XSAXMLScanner::scanReset(const InputSource& src)
{
    fGrammar = fSchemaGrammar;
    fGrammarType = Grammar::SchemaGrammarType;
    fRootGrammar = fSchemaGrammar;

    fValidator->setGrammar(fGrammar);

    // Reset validation
    fValidate = true;

    //  And for all installed handlers, send reset events. This gives them
    //  a chance to flush any cached data.
    if (fDocHandler)
        fDocHandler->resetDocument();
    if (fEntityHandler)
        fEntityHandler->resetEntities();
    if (fErrorReporter)
        fErrorReporter->resetErrors();

    // Clear out the id reference list
    resetValidationContext();

    // Reset the Root Element Name
    if (fRootElemName) {
        fMemoryManager->deallocate(fRootElemName);//delete [] fRootElemName;
    }

    fRootElemName = 0;

    //  Reset the element stack, and give it the latest ids for the special
    //  URIs it has to know about.
    fElemStack.reset
    (
        fEmptyNamespaceId, fUnknownNamespaceId, fXMLNamespaceId, fXMLNSNamespaceId
    );

    if (!fSchemaNamespaceId)
        fSchemaNamespaceId  = fURIStringPool->addOrFind(SchemaSymbols::fgURI_XSI);

    // Reset some status flags
    fInException = false;
    fStandalone = false;
    fErrorCount = 0;
    fHasNoDTD = true;
    fSeeXsi = false;
    fDoNamespaces = true;
    fDoSchema = true;

    // Reset the validators
    fSchemaValidator->reset();
    fSchemaValidator->setErrorReporter(fErrorReporter);
    fSchemaValidator->setExitOnFirstFatal(fExitOnFirstFatal);
    fSchemaValidator->setGrammarResolver(fGrammarResolver);

    //  Handle the creation of the XML reader object for this input source.
    //  This will provide us with transcoding and basic lexing services.
    XMLReader* newReader = fReaderMgr.createReader
    (
        src
        , true
        , XMLReader::RefFrom_NonLiteral
        , XMLReader::Type_General
        , XMLReader::Source_External
        , fCalculateSrcOfs
    );

    if (!newReader) {
        if (src.getIssueFatalErrorIfNotFound())
            ThrowXMLwithMemMgr1(RuntimeException, XMLExcepts::Scan_CouldNotOpenSource, src.getSystemId(), fMemoryManager);
        else
            ThrowXMLwithMemMgr1(RuntimeException, XMLExcepts::Scan_CouldNotOpenSource_Warning, src.getSystemId(), fMemoryManager);
    }

    // Push this read onto the reader manager
    fReaderMgr.pushReader(newReader, 0);

    // and reset security-related things if necessary:
    if(fSecurityManager != 0) 
    {
        fEntityExpansionLimit = fSecurityManager->getEntityExpansionLimit();
        fEntityExpansionCount = 0;
    }
    fElemCount = 0;
    if (fUIntPoolRowTotal >= 32) 
    { // 8 KB tied up with validating attributes...
        fAttDefRegistry->removeAll();
        recreateUIntPool();
    }
    else
    {
        // note that this will implicitly reset the values of the hashtables,
        // though their buckets will still be tied up
        resetUIntPool();
    }
    fUndeclaredAttrRegistryNS->removeAll();
}
예제 #5
0
파일: XQQuery.cpp 프로젝트: kanbang/Colt
void XQQuery::importModule(const XMLCh* szUri, VectorOfStrings* locations, StaticContext* context, const LocationInfo *location)
{
  for(ImportedModules::iterator modIt = m_importedModules.begin();
      modIt != m_importedModules.end(); ++modIt) {
    if(XPath2Utils::equals((*modIt)->getModuleTargetNamespace(),szUri)) {
      XMLBuffer buf(1023,context->getMemoryManager());
      buf.set(X("Module for namespace '"));
      buf.append(szUri);
      buf.append(X("' has already been imported [err:XQST0047]"));
      XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), location);
    }
  }
  if(locations==NULL)
    locations=context->resolveModuleURI(szUri);
  if(locations==NULL || locations->empty()) {
    XMLBuffer buf(1023,context->getMemoryManager());
    buf.set(X("Cannot locate module for namespace "));
    buf.append(szUri);
    buf.append(X(" without the 'at <location>' keyword [err:XQST0059]"));
    XQThrow3(StaticErrorException,X("XQQuery::ImportModule"), buf.getRawBuffer(), location);
  }

  bool bFound=false;
  for(VectorOfStrings::iterator it=locations->begin();it!=locations->end();++it) {
    InputSource* srcToUse = 0;
    if (context->getDocumentCache()->getXMLEntityResolver()){
      XMLResourceIdentifier resourceIdentifier(XMLResourceIdentifier::UnKnown,
                                               *it, szUri, XMLUni::fgZeroLenString, 
                                               context->getBaseURI());
      srcToUse = context->getDocumentCache()->getXMLEntityResolver()->resolveEntity(&resourceIdentifier);
    }

    if(srcToUse==0) {
      try {
        XMLURL urlTmp(context->getBaseURI(), *it);
        if (urlTmp.isRelative()) {
          throw MalformedURLException(__FILE__, __LINE__, XMLExcepts::URL_NoProtocolPresent);
        }
        srcToUse = new URLInputSource(urlTmp);
      }
      catch(const MalformedURLException&) {
        // It's not a URL, so let's assume it's a local file name.
        const XMLCh* baseUri=context->getBaseURI();
        if(baseUri && baseUri[0]) {
          XMLCh* tmpBuf = XMLPlatformUtils::weavePaths(baseUri, *it);
          srcToUse = new LocalFileInputSource(tmpBuf);
          XMLPlatformUtils::fgMemoryManager->deallocate(tmpBuf);
        }
        else {
          srcToUse = new LocalFileInputSource(*it);
        }
      }
    }
    Janitor<InputSource> janIS(srcToUse);

    AutoDelete<DynamicContext> ctxGuard(context->createModuleContext());
    DynamicContext *moduleCtx = ctxGuard.get();

    moduleCtx->setBaseURI(srcToUse->getSystemId());
    LoopDetector loopDetector(context->getXMLEntityResolver(), szUri, location);
    moduleCtx->setXMLEntityResolver(&loopDetector);

    AutoDelete<XQQuery> pParsedQuery(XQilla::parse(*srcToUse, ctxGuard.adopt(), XQilla::NO_OPTIMIZATION));

    if(!pParsedQuery->getIsLibraryModule()) {
      XMLBuffer buf(1023,context->getMemoryManager());
      buf.set(X("The module at "));
      buf.append(srcToUse->getSystemId());
      buf.append(X(" is not a module"));
      XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), location);
    }
    if(!XERCES_CPP_NAMESPACE::XMLString::equals(szUri,pParsedQuery->getModuleTargetNamespace())) {
      XMLBuffer buf(1023,context->getMemoryManager());
      buf.set(X("The module at "));
      buf.append(srcToUse->getSystemId());
      buf.append(X(" specifies a different namespace [err:XQST0059]"));
      XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), location);
    }
    // now move the variable declarations and the function definitions into my context
    for(UserFunctions::iterator itFn = pParsedQuery->m_userDefFns.begin(); itFn != pParsedQuery->m_userDefFns.end(); ++itFn) {
      (*itFn)->setModuleDocumentCache(const_cast<DocumentCache*>(moduleCtx->getDocumentCache()));
      if((*itFn)->isTemplate()) {
        context->addTemplate(*itFn);
      }
      else if((*itFn)->getName()) {
        context->addCustomFunction(*itFn);
      }
    }
    for(GlobalVariables::iterator itVar = pParsedQuery->m_userDefVars.begin(); itVar != pParsedQuery->m_userDefVars.end(); ++itVar) {
      for(ImportedModules::const_iterator modIt = m_importedModules.begin();
          modIt != m_importedModules.end(); ++modIt) {
        for(GlobalVariables::const_iterator varIt = (*modIt)->m_userDefVars.begin();
            varIt != (*modIt)->m_userDefVars.end(); ++varIt) {
          if(XPath2Utils::equals((*varIt)->getVariableURI(), (*itVar)->getVariableURI()) &&
             XPath2Utils::equals((*varIt)->getVariableLocalName(), (*itVar)->getVariableLocalName())) {
            XMLBuffer buf(1023,context->getMemoryManager());
            buf.set(X("An imported variable {"));
            buf.append((*itVar)->getVariableURI());
            buf.append(X("}"));
            buf.append((*itVar)->getVariableLocalName());
            buf.append(X(" conflicts with an already defined global variable [err:XQST0049]."));
            XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), *varIt);
          }
        }
      }
    }

    moduleCtx->setXMLEntityResolver(context->getXMLEntityResolver());
    m_importedModules.push_back(pParsedQuery.adopt());

    bFound=true;
  }
  if(!bFound)
  {
    XMLBuffer buf(1023,context->getMemoryManager());
    buf.set(X("Cannot locate the module for namespace \""));
    buf.append(szUri);
    buf.append(X("\" [err:XQST0059]"));
    XQThrow3(StaticErrorException,X("XQQuery::ImportModule"), buf.getRawBuffer(), location);
  }
}
예제 #6
0
void FaxppDocumentCacheImpl::parseDocument(InputSource &srcToUse, EventHandler *handler, DynamicContext *context)
{
  XPath2MemoryManager *mm = context->getMemoryManager();

  if(doPSVI_) {
    validator_.setNextEventHandler(handler);
    events_ = &validator_;
  }
  else {
    events_ = handler;
  }

  FAXPP_Error err = wrapper_.parseInputSource(srcToUse, mm);

  if(err == OUT_OF_MEMORY)
    XQThrow2(XMLParseException, X("FaxppDocumentCacheImpl::loadDocument"), X("Out of memory"));

  if(err == UNSUPPORTED_ENCODING) {
    XQThrow2(XMLParseException, X("FaxppDocumentCacheImpl::loadDocument"), X("Unsupported encoding"));
  }

  location_.setLocationInfo(srcToUse.getSystemId(), 0, 0);

  try {

  unsigned int i;
  FAXPP_Attribute *attr;

  while(true) {
    err = FAXPP_next_event(wrapper_.parser);
    if(err != NO_ERROR) {
      // TBD add line and column information - jpcs
      XMLBuffer buf;
      buf.append(X("Error parsing document: "));
      buf.append(X(FAXPP_err_to_string(err)));
      XQThrow2(XMLParseException, X("FaxppDocumentCacheImpl::loadDocument"), buf.getRawBuffer());
    }

    const FAXPP_Event *event = FAXPP_get_current_event(wrapper_.parser);
    LOCATION(event);

    switch(event->type) {
    case START_DOCUMENT_EVENT: {
      // TBD Get encoding from parser if not specified in document - jpcs
      events_->setLocationInfo(&location_);

      // Encode space chars in the document URI as %20
      const XMLCh *uri = srcToUse.getSystemId();
      XMLBuffer encode(XMLString::stringLen(uri) + 1);
      if(uri != 0) {
        for(const XMLCh *uptr = uri; *uptr; ++uptr) {
          if(*uptr != ' ')
            encode.append(*uptr);
          else {
            encode.append('%');
            encode.append('2');
            encode.append('0');
          }
        }
        uri = encode.getRawBuffer();
      }

      events_->startDocumentEvent(uri, nullTerm(event->encoding, mm));
      break;
    }
    case END_DOCUMENT_EVENT:
      events_->endDocumentEvent();
      return;
    case START_ELEMENT_EVENT:
    case SELF_CLOSING_ELEMENT_EVENT:
      events_->startElementEvent(nullTerm(event->prefix, mm), nullTerm(event->uri, mm), nullTerm(event->name, mm));

      for(i = 0; i < event->attr_count; ++i) {
        attr = &event->attrs[i];
        LOCATION(attr);

        if(attr->xmlns_attr) {
          if(attr->prefix.ptr == 0)
            events_->namespaceEvent(0, nullTerm(attr->value.value, mm));
          else
            events_->namespaceEvent(nullTerm(attr->name, mm), nullTerm(attr->value.value, mm));
        }
        else {
          events_->attributeEvent(nullTerm(attr->prefix, mm), nullTerm(attr->uri, mm), nullTerm(attr->name, mm), nullTerm(attr->value.value, mm),
                                  SchemaSymbols::fgURI_SCHEMAFORSCHEMA, ATUntypedAtomic::fgDT_UNTYPEDATOMIC);
        }
      }

      if(event->type == START_ELEMENT_EVENT) break;
      // Fall through
    case END_ELEMENT_EVENT:
      events_->endElementEvent(nullTerm(event->prefix, mm), nullTerm(event->uri, mm), nullTerm(event->name, mm),
                               SchemaSymbols::fgURI_SCHEMAFORSCHEMA, DocumentCache::g_szUntyped);
      break;
    case IGNORABLE_WHITESPACE_EVENT:
      // Do nothing
      break;
    case ENTITY_REFERENCE_EVENT:
    case DEC_CHAR_REFERENCE_EVENT:
    case HEX_CHAR_REFERENCE_EVENT:
    case CHARACTERS_EVENT:
    case CDATA_EVENT:
      events_->textEvent((XMLCh*)event->value.ptr, event->value.len / sizeof(XMLCh));
      break;
    case COMMENT_EVENT:
      events_->commentEvent(nullTerm(event->value, mm));
      break;
    case PI_EVENT:
      events_->piEvent(nullTerm(event->name, mm), nullTerm(event->value, mm));
      break;
    case DOCTYPE_EVENT:
    case ENTITY_REFERENCE_START_EVENT:
    case ENTITY_REFERENCE_END_EVENT:
    case START_EXTERNAL_ENTITY_EVENT:
    case END_EXTERNAL_ENTITY_EVENT:
    case NO_EVENT: break;
    }
  }

  }
  catch(XQException& e) {
    if(e.getXQueryLine() == 0) {
      e.setXQueryPosition(&location_);
    }
    throw e;
  }
}