Beispiel #1
0
void AccelTreeBuilder<FromDocument>::startElement(const QXmlName &name, qint64 line, qint64 column)
{
    startStructure();

    AccelTree::BasicNodeData data(currentDepth(), currentParent(), QXmlNodeModelIndex::Element, -1, name);
    m_document->basicData.append(data);
    if (m_features & SourceLocationsFeature)
        m_document->sourcePositions.insert(m_document->maximumPreNumber(), qMakePair(line, column));

    ++m_preNumber;
    m_ancestors.push(m_preNumber);

    ++m_size.top();
    m_size.push(0);

    /* With node constructors, we can receive names for which we have no namespace
     * constructors, such as in the query '<xs:space/>'. Since the 'xs' prefix has no
     * NamespaceConstructor in this case, we synthesize the namespace.
     *
     * In case we're constructing from an XML document we avoid the call because
     * although it's redundant, it's on extra virtual call for each element. */
    if(!FromDocument)
        namespaceBinding(QXmlName(name.namespaceURI(), 0, name.prefix()));

    m_isPreviousAtomic = false;
}
Beispiel #2
0
void AccelTreeBuilder<FromDocument>::comment(const QString &content)
{
    startStructure();
    m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(), currentParent(), QXmlNodeModelIndex::Comment, 0));
    ++m_preNumber;
    m_document->data.insert(m_preNumber, content);
    ++m_size.top();
}
Beispiel #3
0
void AccelTreeBuilder<FromDocument>::processingInstruction(const QXmlName &target,
                                                           const QString &data)
{
    startStructure();
    ++m_preNumber;
    m_document->data.insert(m_preNumber, data);

    m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(),
                                                          currentParent(),
                                                          QXmlNodeModelIndex::ProcessingInstruction,
                                                          0,
                                                          target));
    ++m_size.top();
    m_isPreviousAtomic = false;
}
Beispiel #4
0
std::vector<ModelObject> getRecursiveChildren(const ParentObject& object, bool includeLifeCycleCosts) {
  std::set<Handle> resultSet;
  std::pair<HandleSet::const_iterator,bool> insertResult;
  std::vector<ModelObject> result;
  resultSet.insert(object.handle());
  result.push_back(object);

  if (includeLifeCycleCosts){
    for (const LifeCycleCost& lifeCycleCost : object.lifeCycleCosts()){
      result.push_back(lifeCycleCost);
    }
  }

  std::deque<ParentObject> parents;
  parents.push_back(object);

  while (parents.size() > 0) {
    ParentObject currentParent(parents[0]);
    parents.pop_front();

    // parent's costs have already been added
    
    for (const ModelObject& child : currentParent.children()) {
      insertResult = resultSet.insert(child.handle());
      if (insertResult.second) {
        result.push_back(child);

        if (includeLifeCycleCosts){
          for (const LifeCycleCost& lifeCycleCost : child.lifeCycleCosts()){
            result.push_back(lifeCycleCost);
          }
        }

        OptionalParentObject opo = child.optionalCast<ParentObject>();
        if (opo) { 
          parents.push_back(*opo); 
        }
      }
    }
  }

  return result;
}
Beispiel #5
0
std::vector<ModelObject> getRecursiveChildrenAndResources(const ModelObject& object) {
  std::set<Handle> resultSet;
  std::pair<HandleSet::const_iterator,bool> insertResult;
  std::vector<ModelObject> result;
  resultSet.insert(object.handle());
  result.push_back(object);

  std::deque<ModelObject> objectQueue;
  objectQueue.push_back(object);

  while (objectQueue.size() > 0) {
    ModelObject currentObject(objectQueue[0]);
    objectQueue.pop_front();
    // resources
    for (const ResourceObject& resource : currentObject.resources()) {
      insertResult = resultSet.insert(resource.handle());
      if (insertResult.second) {
        // new object
        ModelObject mo = resource.cast<ModelObject>();
        result.push_back(mo);
        objectQueue.push_back(mo);
      }
    }
    // children
    OptionalParentObject opo = currentObject.optionalCast<ParentObject>();
    if (opo) {
      ParentObject currentParent(*opo);
      for (const ModelObject& child : currentParent.children()) {
        insertResult = resultSet.insert(child.handle());
        if (insertResult.second) {
          // new object
          result.push_back(child);
          objectQueue.push_back(child);
        }
      }
    }
  }

  return result;
}
Beispiel #6
0
void AccelTreeBuilder<FromDocument>::startStructure()
{
    if(m_hasCharacters)
    {
        /* We create a node even if m_characters is empty.
         * Remember that `text {""}' creates one text node
         * with string value "". */

        ++m_preNumber;
        m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(),
                                                              currentParent(),
                                                              QXmlNodeModelIndex::Text,
                                                              m_isCharactersCompressed ? AccelTree::IsCompressed : 0));
        m_document->data.insert(m_preNumber, m_characters);
        ++m_size.top();

        m_characters.clear(); /* We don't want it added twice. */
        m_hasCharacters = false;

        if(m_isCharactersCompressed)
            m_isCharactersCompressed = false;
    }
}
Beispiel #7
0
void AccelTreeBuilder<FromDocument>::attribute(const QXmlName &name, const QStringRef &value)
{
    /* Attributes adds a namespace binding, so lets synthesize one.
     *
     * We optimize by checking whether we have a namespace for which a binding would
     * be generated. Happens relatively rarely. */
    if(name.hasPrefix())
        namespaceBinding(QXmlName(name.namespaceURI(), 0, name.prefix()));

    m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(), currentParent(), QXmlNodeModelIndex::Attribute, 0, name));
    ++m_preNumber;
    ++m_size.top();

    m_isPreviousAtomic = false;

    if(name.namespaceURI() == StandardNamespaces::xml && name.localName() == StandardLocalNames::id)
    {
        const QString normalized(value.toString().simplified());

        if(QXmlUtils::isNCName(normalized))
        {
            const QXmlName::LocalNameCode id = m_namePool->allocateLocalName(normalized);

            const int oldSize = m_document->m_IDs.count();
            m_document->m_IDs.insert(id, currentParent());
            /* We don't run the value through m_attributeCompress here, because
             * the likelyhood of it deing identical to another attribute is
             * very small. */
            m_document->data.insert(m_preNumber, normalized);

            /**
             * In the case that we're called for doc-available(), m_context is
             * null, and we need to flag somehow that we failed to load this
             * document.
             */
            if(oldSize == m_document->m_IDs.count() && m_context) // TODO
            {
                Q_ASSERT(m_context);
                m_context->error(QtXmlPatterns::tr("An %1-attribute with value %2 has already been declared.")
                                                   .arg(formatKeyword("xml:id"),
                                                        formatData(normalized)),
                                 FromDocument ? ReportContext::FODC0002 : ReportContext::XQDY0091,
                                 this);
            }
        }
        else if(m_context) // TODO
        {
            Q_ASSERT(m_context);

            /* If we're building from an XML Document(e.g, we're fed from QXmlStreamReader, we raise FODC0002,
             * otherwise XQDY0091. */
            m_context->error(QtXmlPatterns::tr("An %1-attribute must have a "
                                               "valid %2 as value, which %3 isn't.").arg(formatKeyword("xml:id"),
                                                                                         formatType(m_namePool, BuiltinTypes::xsNCName),
                                                                                         formatData(value.toString())),
                             FromDocument ? ReportContext::FODC0002 : ReportContext::XQDY0091,
                             this);
        }
    }
    else
        m_document->data.insert(m_preNumber, *m_attributeCompress.insert(value.toString()));
}