bool run()
    {
        DFG_ASSERT(m_graph, nullptr, m_graph.m_form == ThreadedCPS);
        
        ScoreBoard scoreBoard(m_graph.m_nextMachineLocal);
        scoreBoard.assertClear();
        for (size_t blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
            BasicBlock* block = m_graph.block(blockIndex);
            if (!block)
                continue;
            if (!block->isReachable)
                continue;
            if (!ASSERT_DISABLED) {
                // Force usage of highest-numbered virtual registers.
                scoreBoard.sortFree();
            }
            for (size_t indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
                Node* node = block->at(indexInBlock);
        
                if (!node->shouldGenerate())
                    continue;
                
                switch (node->op()) {
                case Phi:
                case Flush:
                case PhantomLocal:
                    continue;
                case GetLocal:
                    ASSERT(!node->child1()->hasResult());
                    break;
                default:
                    break;
                }
                
                // First, call use on all of the current node's children, then
                // allocate a VirtualRegister for this node. We do so in this
                // order so that if a child is on its last use, and a
                // VirtualRegister is freed, then it may be reused for node.
                if (node->flags() & NodeHasVarArgs) {
                    for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++)
                        scoreBoard.useIfHasResult(m_graph.m_varArgChildren[childIdx]);
                } else {
                    scoreBoard.useIfHasResult(node->child1());
                    scoreBoard.useIfHasResult(node->child2());
                    scoreBoard.useIfHasResult(node->child3());
                }

                if (!node->hasResult())
                    continue;

                VirtualRegister virtualRegister = scoreBoard.allocate();
                node->setVirtualRegister(virtualRegister);
                // 'mustGenerate' nodes have their useCount artificially elevated,
                // call use now to account for this.
                if (node->mustGenerate())
                    scoreBoard.use(node);
            }
            scoreBoard.assertClear();
        }
        
        // Record the number of virtual registers we're using. This is used by calls
        // to figure out where to put the parameters.
        m_graph.m_nextMachineLocal = scoreBoard.highWatermark();

        return true;
    }
Example #2
0
void MarkupAccumulator::serializeNodesWithNamespaces(Node& targetNode, EChildrenOnly childrenOnly, const Namespaces* namespaces, Vector<QualifiedName>* tagNamesToSkip)
{
    if (tagNamesToSkip) {
        for (size_t i = 0; i < tagNamesToSkip->size(); ++i) {
            if (targetNode.hasTagName(tagNamesToSkip->at(i)))
                return;
        }
    }

    Namespaces namespaceHash;
    if (namespaces)
        namespaceHash = *namespaces;

    if (!childrenOnly)
        appendStartTag(targetNode, &namespaceHash);

    if (!(serializeAsHTMLDocument(targetNode) && elementCannotHaveEndTag(targetNode))) {
        Node* current = isHTMLTemplateElement(targetNode) ? toHTMLTemplateElement(targetNode).content()->firstChild() : targetNode.firstChild();
        for ( ; current; current = current->nextSibling())
            serializeNodesWithNamespaces(*current, IncludeNode, &namespaceHash, tagNamesToSkip);
    }

    if (!childrenOnly)
        appendEndTag(targetNode);
}
Example #3
0
static void sortBlock(unsigned from, unsigned to, WillBeHeapVector<NodeSetVector>& parentMatrix, bool mayContainAttributeNodes)
{
    ASSERT(from + 1 < to); // Should not call this function with less that two nodes to sort.
    unsigned minDepth = UINT_MAX;
    for (unsigned i = from; i < to; ++i) {
        unsigned depth = parentMatrix[i].size() - 1;
        if (minDepth > depth)
            minDepth = depth;
    }

    // Find the common ancestor.
    unsigned commonAncestorDepth = minDepth;
    Node* commonAncestor;
    while (true) {
        commonAncestor = parentWithDepth(commonAncestorDepth, parentMatrix[from]);
        if (commonAncestorDepth == 0)
            break;

        bool allEqual = true;
        for (unsigned i = from + 1; i < to; ++i) {
            if (commonAncestor != parentWithDepth(commonAncestorDepth, parentMatrix[i])) {
                allEqual = false;
                break;
            }
        }
        if (allEqual)
            break;

        --commonAncestorDepth;
    }

    if (commonAncestorDepth == minDepth) {
        // One of the nodes is the common ancestor => it is the first in document order.
        // Find it and move it to the beginning.
        for (unsigned i = from; i < to; ++i)
            if (commonAncestor == parentMatrix[i][0]) {
                parentMatrix[i].swap(parentMatrix[from]);
                if (from + 2 < to)
                    sortBlock(from + 1, to, parentMatrix, mayContainAttributeNodes);
                return;
            }
    }

    if (mayContainAttributeNodes && commonAncestor->isElementNode()) {
        // The attribute nodes and namespace nodes of an element occur before the children of the element.
        // The namespace nodes are defined to occur before the attribute nodes.
        // The relative order of namespace nodes is implementation-dependent.
        // The relative order of attribute nodes is implementation-dependent.
        unsigned sortedEnd = from;
        // FIXME: namespace nodes are not implemented.
        for (unsigned i = sortedEnd; i < to; ++i) {
            Node* n = parentMatrix[i][0];
            if (n->isAttributeNode() && toAttr(n)->ownerElement() == commonAncestor)
                parentMatrix[i].swap(parentMatrix[sortedEnd++]);
        }
        if (sortedEnd != from) {
            if (to - sortedEnd > 1)
                sortBlock(sortedEnd, to, parentMatrix, mayContainAttributeNodes);
            return;
        }
    }

    // Children nodes of the common ancestor induce a subdivision of our node-set.
    // Sort it according to this subdivision, and recursively sort each group.
    WillBeHeapHashSet<RawPtrWillBeMember<Node> > parentNodes;
    for (unsigned i = from; i < to; ++i)
        parentNodes.add(parentWithDepth(commonAncestorDepth + 1, parentMatrix[i]));

    unsigned previousGroupEnd = from;
    unsigned groupEnd = from;
    for (Node* n = commonAncestor->firstChild(); n; n = n->nextSibling()) {
        // If parentNodes contains the node, perform a linear search to move its children in the node-set to the beginning.
        if (parentNodes.contains(n)) {
            for (unsigned i = groupEnd; i < to; ++i)
                if (parentWithDepth(commonAncestorDepth + 1, parentMatrix[i]) == n)
                    parentMatrix[i].swap(parentMatrix[groupEnd++]);

            if (groupEnd - previousGroupEnd > 1)
                sortBlock(previousGroupEnd, groupEnd, parentMatrix, mayContainAttributeNodes);

            ASSERT(previousGroupEnd != groupEnd);
            previousGroupEnd = groupEnd;
#ifndef NDEBUG
            parentNodes.remove(n);
#endif
        }
    }

    ASSERT(parentNodes.isEmpty());
}
    bool run()
    {
        ScoreBoard scoreBoard(m_graph.m_nextMachineLocal);
        scoreBoard.assertClear();
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
        bool needsNewLine = false;
#endif
        for (size_t blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
            BasicBlock* block = m_graph.block(blockIndex);
            if (!block)
                continue;
            if (!block->isReachable)
                continue;
            for (size_t indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
                Node* node = block->at(indexInBlock);
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
                if (needsNewLine)
                    dataLogF("\n");
                dataLogF("   @%u:", node->index());
                needsNewLine = true;
#endif
        
                if (!node->shouldGenerate())
                    continue;
                
                switch (node->op()) {
                case Phi:
                case Flush:
                case PhantomLocal:
                    continue;
                case GetLocal:
                    ASSERT(!node->child1()->hasResult());
                    break;
                default:
                    break;
                }
                
                // First, call use on all of the current node's children, then
                // allocate a VirtualRegister for this node. We do so in this
                // order so that if a child is on its last use, and a
                // VirtualRegister is freed, then it may be reused for node.
                if (node->flags() & NodeHasVarArgs) {
                    for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++)
                        scoreBoard.useIfHasResult(m_graph.m_varArgChildren[childIdx]);
                } else {
                    scoreBoard.useIfHasResult(node->child1());
                    scoreBoard.useIfHasResult(node->child2());
                    scoreBoard.useIfHasResult(node->child3());
                }

                if (!node->hasResult())
                    continue;

                VirtualRegister virtualRegister = scoreBoard.allocate();
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
                dataLogF(
                    " Assigning virtual register %u to node %u.",
                    virtualRegister, node->index());
#endif
                node->setVirtualRegister(virtualRegister);
                // 'mustGenerate' nodes have their useCount artificially elevated,
                // call use now to account for this.
                if (node->mustGenerate())
                    scoreBoard.use(node);
            }
            scoreBoard.assertClear();
        }
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
        if (needsNewLine)
            dataLogF("\n");
#endif
        
        // Record the number of virtual registers we're using. This is used by calls
        // to figure out where to put the parameters.
        m_graph.m_nextMachineLocal = scoreBoard.highWatermark();

        // 'm_numCalleeRegisters' is the number of locals and temporaries allocated
        // for the function (and checked for on entry). Since we perform a new and
        // different allocation of temporaries, more registers may now be required.
        // This also accounts for the number of temporaries that may be needed if we
        // OSR exit, due to inlining. Hence this computes the number of temporaries
        // that could be used by this code block even if it exits; it may be more
        // than what this code block needs if it never exits.
        unsigned calleeRegisters = scoreBoard.highWatermark() + m_graph.m_parameterSlots;
        for (InlineCallFrameSet::iterator iter = m_graph.m_inlineCallFrames->begin(); !!iter; ++iter) {
            InlineCallFrame* inlineCallFrame = *iter;
            CodeBlock* codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
            unsigned requiredCalleeRegisters = VirtualRegister(inlineCallFrame->stackOffset).toLocal() + 1 + codeBlock->m_numCalleeRegisters;
            if (requiredCalleeRegisters > calleeRegisters)
                calleeRegisters = requiredCalleeRegisters;
        }
        if ((unsigned)codeBlock()->m_numCalleeRegisters < calleeRegisters)
            codeBlock()->m_numCalleeRegisters = calleeRegisters;
#if DFG_ENABLE(DEBUG_VERBOSE)
        dataLogF("Num callee registers: %u\n", calleeRegisters);
#endif
        
        return true;
    }
Example #5
0
// Result nodes are ordered in axis order. Node test (including merged predicates) is applied.
void Step::nodesInAxis(Node* context, NodeSet& nodes) const
{
    ASSERT(nodes.isEmpty());
    switch (m_axis) {
        case ChildAxis:
            if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
                return;

            for (Node* n = context->firstChild(); n; n = n->nextSibling())
                if (nodeMatches(n, ChildAxis, m_nodeTest))
                    nodes.append(n);
            return;
        case DescendantAxis:
            if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
                return;

            for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context))
                if (nodeMatches(n, DescendantAxis, m_nodeTest))
                    nodes.append(n);
            return;
        case ParentAxis:
            if (context->isAttributeNode()) {
                Element* n = toAttr(context)->ownerElement();
                if (nodeMatches(n, ParentAxis, m_nodeTest))
                    nodes.append(n);
            } else {
                ContainerNode* n = context->parentNode();
                if (n && nodeMatches(n, ParentAxis, m_nodeTest))
                    nodes.append(n);
            }
            return;
        case AncestorAxis: {
            Node* n = context;
            if (context->isAttributeNode()) {
                n = toAttr(context)->ownerElement();
                if (nodeMatches(n, AncestorAxis, m_nodeTest))
                    nodes.append(n);
            }
            for (n = n->parentNode(); n; n = n->parentNode())
                if (nodeMatches(n, AncestorAxis, m_nodeTest))
                    nodes.append(n);
            nodes.markSorted(false);
            return;
        }
        case FollowingSiblingAxis:
            if (context->nodeType() == Node::ATTRIBUTE_NODE ||
                 context->nodeType() == Node::XPATH_NAMESPACE_NODE)
                return;

            for (Node* n = context->nextSibling(); n; n = n->nextSibling())
                if (nodeMatches(n, FollowingSiblingAxis, m_nodeTest))
                    nodes.append(n);
            return;
        case PrecedingSiblingAxis:
            if (context->nodeType() == Node::ATTRIBUTE_NODE ||
                 context->nodeType() == Node::XPATH_NAMESPACE_NODE)
                return;

            for (Node* n = context->previousSibling(); n; n = n->previousSibling())
                if (nodeMatches(n, PrecedingSiblingAxis, m_nodeTest))
                    nodes.append(n);

            nodes.markSorted(false);
            return;
        case FollowingAxis:
            if (context->isAttributeNode()) {
                Node* p = toAttr(context)->ownerElement();
                while ((p = NodeTraversal::next(*p))) {
                    if (nodeMatches(p, FollowingAxis, m_nodeTest))
                        nodes.append(p);
                }
            } else {
                for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
                    for (Node* n = p->nextSibling(); n; n = n->nextSibling()) {
                        if (nodeMatches(n, FollowingAxis, m_nodeTest))
                            nodes.append(n);
                        for (Node* c = n->firstChild(); c; c = NodeTraversal::next(*c, n))
                            if (nodeMatches(c, FollowingAxis, m_nodeTest))
                                nodes.append(c);
                    }
                }
            }
            return;
        case PrecedingAxis: {
            if (context->isAttributeNode())
                context = toAttr(context)->ownerElement();

            Node* n = context;
            while (ContainerNode* parent = n->parentNode()) {
                for (n = NodeTraversal::previous(*n); n != parent; n = NodeTraversal::previous(*n))
                    if (nodeMatches(n, PrecedingAxis, m_nodeTest))
                        nodes.append(n);
                n = parent;
            }
            nodes.markSorted(false);
            return;
        }
        case AttributeAxis: {
            if (!context->isElementNode())
                return;

            Element* contextElement = toElement(context);

            // Avoid lazily creating attribute nodes for attributes that we do not need anyway.
            if (m_nodeTest.kind() == NodeTest::NameTest && m_nodeTest.data() != starAtom) {
                RefPtr<Node> n = contextElement->getAttributeNodeNS(m_nodeTest.namespaceURI(), m_nodeTest.data());
                if (n && n->namespaceURI() != XMLNSNames::xmlnsNamespaceURI) { // In XPath land, namespace nodes are not accessible on the attribute axis.
                    if (nodeMatches(n.get(), AttributeAxis, m_nodeTest)) // Still need to check merged predicates.
                        nodes.append(n.release());
                }
                return;
            }

            if (!contextElement->hasAttributes())
                return;

            for (unsigned i = 0; i < contextElement->attributeCount(); ++i) {
                RefPtr<Attr> attr = contextElement->ensureAttr(contextElement->attributeItem(i)->name());
                if (nodeMatches(attr.get(), AttributeAxis, m_nodeTest))
                    nodes.append(attr.release());
            }
            return;
        }
        case NamespaceAxis:
            // XPath namespace nodes are not implemented yet.
            return;
        case SelfAxis:
            if (nodeMatches(context, SelfAxis, m_nodeTest))
                nodes.append(context);
            return;
        case DescendantOrSelfAxis:
            if (nodeMatches(context, DescendantOrSelfAxis, m_nodeTest))
                nodes.append(context);
            if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
                return;

            for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context))
            if (nodeMatches(n, DescendantOrSelfAxis, m_nodeTest))
                nodes.append(n);
            return;
        case AncestorOrSelfAxis: {
            if (nodeMatches(context, AncestorOrSelfAxis, m_nodeTest))
                nodes.append(context);
            Node* n = context;
            if (context->isAttributeNode()) {
                n = toAttr(context)->ownerElement();
                if (nodeMatches(n, AncestorOrSelfAxis, m_nodeTest))
                    nodes.append(n);
            }
            for (n = n->parentNode(); n; n = n->parentNode())
                if (nodeMatches(n, AncestorOrSelfAxis, m_nodeTest))
                    nodes.append(n);

            nodes.markSorted(false);
            return;
        }
    }
    ASSERT_NOT_REACHED();
}
SliderThumbElement* RenderSlider::shadowSliderThumb() const
{
    Node* shadow = static_cast<Element*>(node())->shadowRoot();
    return shadow ? toSliderThumbElement(shadow->firstChild()) : 0;
}
Example #7
0
JSValue* JSNode::getValueProperty(ExecState* exec, int token) const
{
    switch (token) {
    case NodeNameAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return jsStringOrNull(imp->nodeName());
    }
    case NodeValueAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return jsStringOrNull(imp->nodeValue());
    }
    case NodeTypeAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return jsNumber(imp->nodeType());
    }
    case ParentNodeAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return toJS(exec, WTF::getPtr(imp->parentNode()));
    }
    case ChildNodesAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return toJS(exec, WTF::getPtr(imp->childNodes()));
    }
    case FirstChildAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return toJS(exec, WTF::getPtr(imp->firstChild()));
    }
    case LastChildAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return toJS(exec, WTF::getPtr(imp->lastChild()));
    }
    case PreviousSiblingAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return toJS(exec, WTF::getPtr(imp->previousSibling()));
    }
    case NextSiblingAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return toJS(exec, WTF::getPtr(imp->nextSibling()));
    }
    case AttributesAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return toJS(exec, WTF::getPtr(imp->attributes()));
    }
    case OwnerDocumentAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return toJS(exec, WTF::getPtr(imp->ownerDocument()));
    }
    case NamespaceURIAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return jsStringOrNull(imp->namespaceURI());
    }
    case PrefixAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return jsStringOrNull(imp->prefix());
    }
    case LocalNameAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return jsStringOrNull(imp->localName());
    }
    case BaseURIAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return jsStringOrNull(imp->baseURI());
    }
    case TextContentAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return jsStringOrNull(imp->textContent());
    }
    case ParentElementAttrNum: {
        Node* imp = static_cast<Node*>(impl());

        return toJS(exec, WTF::getPtr(imp->parentElement()));
    }
    case ConstructorAttrNum:
        return getConstructor(exec);
    }
    return 0;
}
Example #8
0
int main()
{
	TEST_TAG(main);

	typedef gubg::tree::Node<Data> Node;
	Node n;
	TEST_FALSE(n);

	n = Node::create();
	TEST_TRUE(n);
	TEST_EQ(0, n.nrChilds());

	n.data().name = "Hello";
	n.data().i = 42;

	{
		const auto cn = n;
		TEST_EQ(42, cn.data().i);
	}

	{
		TEST_TAG(get);
		auto ch = n.firstChild();
		TEST_FALSE(ch);
	}

	{
		TEST_TAG(push);
		n.pushChild(Node::create());
		TEST_EQ(1, n.nrChilds());
		n.pushChild(Node::create());
		TEST_EQ(2, n.nrChilds());
	}

	{
		TEST_TAG(forward);
		auto ch = n.firstChild();
		TEST_TRUE(ch);
		TEST_FALSE(ch.prevSibling());
		ch = ch.nextSibling();
		TEST_TRUE(ch);
		TEST_TRUE(ch.prevSibling());
		TEST_EQ(n.lastChild(), ch);
		ch = ch.nextSibling();
		TEST_FALSE(ch);
	}
	{
		TEST_TAG(backward);
		auto ch = n.lastChild();
		TEST_TRUE(ch);
		TEST_FALSE(ch.nextSibling());
		ch = ch.prevSibling();
		TEST_TRUE(ch);
		TEST_TRUE(ch.nextSibling());
		TEST_EQ(n.firstChild(), ch);
		ch = ch.prevSibling();
		TEST_FALSE(ch);
	}

	{
		TEST_TAG(shift);
		auto ch = n.shiftChild();
		TEST_EQ(1, n.nrChilds());
		TEST_TRUE(ch);
		ch = n.shiftChild();
		TEST_EQ(0, n.nrChilds());
		TEST_TRUE(ch);
		ch = n.shiftChild();
		TEST_EQ(0, n.nrChilds());
		TEST_FALSE(ch);
	}

	{
		TEST_TAG(stress);
		for (int i = 0; i < 1000000; ++i)
			n.pushChild(Node::create());
        L("Node " << sizeof(Node));
        L("shared_ptr" << sizeof(std::shared_ptr<int>));
        L("Data " << sizeof(Data));
        L("string " << sizeof(std::string));
        L("tree::impl<Data> " << sizeof(gubg::tree::impl::Node<Data>));
        L("mutex " << sizeof(std::mutex));
	}
    //getc(stdin);

	return 0;
}
Example #9
0
// Result nodes are ordered in axis order. Node test (including merged
// predicates) is applied.
void Step::nodesInAxis(EvaluationContext& evaluationContext, Node* context, NodeSet& nodes) const
{
    ASSERT(nodes.isEmpty());
    switch (m_axis) {
    case ChildAxis:
        // In XPath model, attribute nodes do not have children.
        if (context->isAttributeNode())
            return;

        for (Node* n = context->firstChild(); n; n = n->nextSibling()) {
            if (nodeMatches(evaluationContext, n, ChildAxis, nodeTest()))
                nodes.append(n);
        }
        return;

    case DescendantAxis:
        // In XPath model, attribute nodes do not have children.
        if (context->isAttributeNode())
            return;

        for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context)) {
            if (nodeMatches(evaluationContext, n, DescendantAxis, nodeTest()))
                nodes.append(n);
        }
        return;

    case ParentAxis:
        if (context->isAttributeNode()) {
            Element* n = toAttr(context)->ownerElement();
            if (nodeMatches(evaluationContext, n, ParentAxis, nodeTest()))
                nodes.append(n);
        } else {
            ContainerNode* n = context->parentNode();
            if (n && nodeMatches(evaluationContext, n, ParentAxis, nodeTest()))
                nodes.append(n);
        }
        return;

    case AncestorAxis: {
        Node* n = context;
        if (context->isAttributeNode()) {
            n = toAttr(context)->ownerElement();
            if (nodeMatches(evaluationContext, n, AncestorAxis, nodeTest()))
                nodes.append(n);
        }
        for (n = n->parentNode(); n; n = n->parentNode()) {
            if (nodeMatches(evaluationContext, n, AncestorAxis, nodeTest()))
                nodes.append(n);
        }
        nodes.markSorted(false);
        return;
    }

    case FollowingSiblingAxis:
        if (context->nodeType() == Node::ATTRIBUTE_NODE)
            return;

        for (Node* n = context->nextSibling(); n; n = n->nextSibling()) {
            if (nodeMatches(evaluationContext, n, FollowingSiblingAxis, nodeTest()))
                nodes.append(n);
        }
        return;

    case PrecedingSiblingAxis:
        if (context->nodeType() == Node::ATTRIBUTE_NODE)
            return;

        for (Node* n = context->previousSibling(); n; n = n->previousSibling()) {
            if (nodeMatches(evaluationContext, n, PrecedingSiblingAxis, nodeTest()))
                nodes.append(n);
        }
        nodes.markSorted(false);
        return;

    case FollowingAxis:
        if (context->isAttributeNode()) {
            for (Node* p = NodeTraversal::next(*toAttr(context)->ownerElement()); p; p = NodeTraversal::next(*p)) {
                if (nodeMatches(evaluationContext, p, FollowingAxis, nodeTest()))
                    nodes.append(p);
            }
        } else {
            for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
                for (Node* n = p->nextSibling(); n; n = n->nextSibling()) {
                    if (nodeMatches(evaluationContext, n, FollowingAxis, nodeTest()))
                        nodes.append(n);
                    for (Node* c = n->firstChild(); c; c = NodeTraversal::next(*c, n)) {
                        if (nodeMatches(evaluationContext, c, FollowingAxis, nodeTest()))
                            nodes.append(c);
                    }
                }
            }
        }
        return;

    case PrecedingAxis: {
        if (context->isAttributeNode())
            context = toAttr(context)->ownerElement();

        Node* n = context;
        while (ContainerNode* parent = n->parentNode()) {
            for (n = NodeTraversal::previous(*n); n != parent; n = NodeTraversal::previous(*n)) {
                if (nodeMatches(evaluationContext, n, PrecedingAxis, nodeTest()))
                    nodes.append(n);
            }
            n = parent;
        }
        nodes.markSorted(false);
        return;
    }

    case AttributeAxis: {
        if (!context->isElementNode())
            return;

        Element* contextElement = toElement(context);
        // Avoid lazily creating attribute nodes for attributes that we do not
        // need anyway.
        if (nodeTest().kind() == NodeTest::NameTest && nodeTest().data() != starAtom) {
            RefPtrWillBeRawPtr<Node> n = contextElement->getAttributeNodeNS(nodeTest().namespaceURI(), nodeTest().data());
            // In XPath land, namespace nodes are not accessible on the attribute axis.
            if (n && n->namespaceURI() != XMLNSNames::xmlnsNamespaceURI) {
                // Still need to check merged predicates.
                if (nodeMatches(evaluationContext, n.get(), AttributeAxis, nodeTest()))
                    nodes.append(n.release());
            }
            return;
        }

        AttributeCollection attributes = contextElement->attributes();
        AttributeCollection::iterator end = attributes.end();
        for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
            RefPtrWillBeRawPtr<Attr> attr = contextElement->ensureAttr(it->name());
            if (nodeMatches(evaluationContext, attr.get(), AttributeAxis, nodeTest()))
                nodes.append(attr.release());
        }
        return;
    }

    case NamespaceAxis:
        // XPath namespace nodes are not implemented.
        return;

    case SelfAxis:
        if (nodeMatches(evaluationContext, context, SelfAxis, nodeTest()))
            nodes.append(context);
        return;

    case DescendantOrSelfAxis:
        if (nodeMatches(evaluationContext, context, DescendantOrSelfAxis, nodeTest()))
            nodes.append(context);
        // In XPath model, attribute nodes do not have children.
        if (context->isAttributeNode())
            return;

        for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context)) {
            if (nodeMatches(evaluationContext, n, DescendantOrSelfAxis, nodeTest()))
                nodes.append(n);
        }
        return;

    case AncestorOrSelfAxis: {
        if (nodeMatches(evaluationContext, context, AncestorOrSelfAxis, nodeTest()))
            nodes.append(context);
        Node* n = context;
        if (context->isAttributeNode()) {
            n = toAttr(context)->ownerElement();
            if (nodeMatches(evaluationContext, n, AncestorOrSelfAxis, nodeTest()))
                nodes.append(n);
        }
        for (n = n->parentNode(); n; n = n->parentNode()) {
            if (nodeMatches(evaluationContext, n, AncestorOrSelfAxis, nodeTest()))
                nodes.append(n);
        }
        nodes.markSorted(false);
        return;
    }
    }
    ASSERT_NOT_REACHED();
}
Example #10
0
void Step::nodesInAxis(Node* context, NodeSet& nodes) const
{
    ASSERT(nodes.isEmpty());
    switch (m_axis) {
        case ChildAxis:
            if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
                return;

            for (Node* n = context->firstChild(); n; n = n->nextSibling())
                if (nodeMatches(n))
                    nodes.append(n);
            return;
        case DescendantAxis:
            if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
                return;

            for (Node* n = context->firstChild(); n; n = n->traverseNextNode(context))
                if (nodeMatches(n))
                    nodes.append(n);
            return;
        case ParentAxis:
            if (context->isAttributeNode()) {
                Node* n = static_cast<Attr*>(context)->ownerElement();
                if (nodeMatches(n))
                    nodes.append(n);
            } else {
                Node* n = context->parentNode();
                if (n && nodeMatches(n))
                    nodes.append(n);
            }
            return;
        case AncestorAxis: {
            Node* n = context;
            if (context->isAttributeNode()) {
                n = static_cast<Attr*>(context)->ownerElement();
                if (nodeMatches(n))
                    nodes.append(n);
            }
            for (n = n->parentNode(); n; n = n->parentNode())
                if (nodeMatches(n))
                    nodes.append(n);
            nodes.reverse();
            return;
        }
        case FollowingSiblingAxis:
            if (context->nodeType() == Node::ATTRIBUTE_NODE ||
                 context->nodeType() == Node::XPATH_NAMESPACE_NODE) 
                return;
            
            for (Node* n = context->nextSibling(); n; n = n->nextSibling())
                if (nodeMatches(n))
                    nodes.append(n);
            return;
        case PrecedingSiblingAxis:
            if (context->nodeType() == Node::ATTRIBUTE_NODE ||
                 context->nodeType() == Node::XPATH_NAMESPACE_NODE)
                return;
            
            for (Node* n = context->previousSibling(); n; n = n->previousSibling())
                if (nodeMatches(n))
                    nodes.append(n);

            nodes.reverse();
            return;
        case FollowingAxis:
            if (context->isAttributeNode()) {
                Node* p = static_cast<Attr*>(context)->ownerElement();
                while ((p = p->traverseNextNode()))
                    if (nodeMatches(p))
                        nodes.append(p);
            } else {
                for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
                    for (Node* n = p->nextSibling(); n; n = n->nextSibling()) {
                        if (nodeMatches(n))
                            nodes.append(n);
                        for (Node* c = n->firstChild(); c; c = c->traverseNextNode(n))
                            if (nodeMatches(c))
                                nodes.append(c);
                    }
                }
            }
            return;
        case PrecedingAxis:
            if (context->isAttributeNode())
                context = static_cast<Attr*>(context)->ownerElement();

            for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
                for (Node* n = p->previousSibling(); n ; n = n->previousSibling()) {
                    if (nodeMatches(n))
                        nodes.append(n);
                    for (Node* c = n->firstChild(); c; c = c->traverseNextNode(n))
                        if (nodeMatches(c))
                            nodes.append(c);
                }
            }
            nodes.markSorted(false);
            return;
        case AttributeAxis: {
            if (context->nodeType() != Node::ELEMENT_NODE)
                return;

            // Avoid lazily creating attribute nodes for attributes that we do not need anyway.
            if (m_nodeTest.kind() == NodeTest::NameTest && m_nodeTest.data() != "*") {
                RefPtr<Node> n = static_cast<Element*>(context)->getAttributeNodeNS(m_nodeTest.namespaceURI(), m_nodeTest.data());
                if (n && n->namespaceURI() != "http://www.w3.org/2000/xmlns/") // In XPath land, namespace nodes are not accessible on the attribute axis.
                    nodes.append(n.release());
                return;
            }
            
            NamedAttrMap* attrs = context->attributes();
            if (!attrs)
                return;

            for (unsigned long i = 0; i < attrs->length(); ++i) {
                RefPtr<Node> n = attrs->item(i);
                if (nodeMatches(n.get()))
                    nodes.append(n.release());
            }
            return;
        }
        case NamespaceAxis:
            // XPath namespace nodes are not implemented yet.
            return;
        case SelfAxis:
            if (nodeMatches(context))
                nodes.append(context);
            return;
        case DescendantOrSelfAxis:
            if (nodeMatches(context))
                nodes.append(context);
            if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
                return;

            for (Node* n = context->firstChild(); n; n = n->traverseNextNode(context))
            if (nodeMatches(n))
                nodes.append(n);
            return;
        case AncestorOrSelfAxis: {
            if (nodeMatches(context))
                nodes.append(context);
            Node* n = context;
            if (context->isAttributeNode()) {
                n = static_cast<Attr*>(context)->ownerElement();
                if (nodeMatches(n))
                    nodes.append(n);
            }
            for (n = n->parentNode(); n; n = n->parentNode())
                if (nodeMatches(n))
                    nodes.append(n);

            nodes.reverse();
            return;
        }
    }
    ASSERT_NOT_REACHED();
}
Example #11
0
SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range *r)
{
    m_positionNode = 0;

    if (!r)
        return;

    int exception = 0;
    Node *startNode = r->startContainer(exception);
    if (exception)
        return;
    Node *endNode = r->endContainer(exception);
    if (exception)
        return;
    int startOffset = r->startOffset(exception);
    if (exception)
        return;
    int endOffset = r->endOffset(exception);
    if (exception)
        return;

    if (!startNode->offsetInCharacters()) {
        if (startOffset >= 0 && startOffset < static_cast<int>(startNode->childNodeCount())) {
            startNode = startNode->childNode(startOffset);
            startOffset = 0;
        }
    }
    if (!endNode->offsetInCharacters()) {
        if (endOffset > 0 && endOffset <= static_cast<int>(endNode->childNodeCount())) {
            endNode = endNode->childNode(endOffset - 1);
            endOffset = endNode->hasChildNodes() ? endNode->childNodeCount() : endNode->maxOffset();
        }
    }

    m_node = endNode;
    m_offset = endOffset;
    m_handledNode = false;
    m_handledChildren = endOffset == 0;

    m_startNode = startNode;
    m_startOffset = startOffset;
    m_endNode = endNode;
    m_endOffset = endOffset;
    
#ifndef NDEBUG
    // Need this just because of the assert.
    m_positionNode = endNode;
#endif

    m_lastTextNode = 0;
    m_lastCharacter = '\n';
    
    if (startOffset == 0 || !startNode->firstChild()) {
        m_pastStartNode = startNode->previousSibling();
        while (!m_pastStartNode && startNode->parentNode()) {
            startNode = startNode->parentNode();
            m_pastStartNode = startNode->previousSibling();
        }
    } else
        m_pastStartNode = startNode->childNode(startOffset - 1);

    advance();
}
Example #12
0
    void fixupBlock(BasicBlock* block)
    {
        if (!block)
            return;
        
        switch (m_graph.m_form) {
        case SSA:
            break;
            
        case ThreadedCPS: {
            // Clean up variable links for the block. We need to do this before the actual DCE
            // because we need to see GetLocals, so we can bypass them in situations where the
            // vars-at-tail point to a GetLocal, the GetLocal is dead, but the Phi it points
            // to is alive.
            
            for (unsigned phiIndex = 0; phiIndex < block->phis.size(); ++phiIndex) {
                if (!block->phis[phiIndex]->shouldGenerate()) {
                    // FIXME: We could actually free nodes here. Except that it probably
                    // doesn't matter, since we don't add any nodes after this phase.
                    // https://bugs.webkit.org/show_bug.cgi?id=126239
                    block->phis[phiIndex--] = block->phis.last();
                    block->phis.removeLast();
                }
            }
            
            cleanVariables(block->variablesAtHead);
            cleanVariables(block->variablesAtTail);
            break;
        }
            
        default:
            RELEASE_ASSERT_NOT_REACHED();
            return;
        }

        for (unsigned indexInBlock = block->size(); indexInBlock--;) {
            Node* node = block->at(indexInBlock);
            if (node->shouldGenerate())
                continue;
                
            switch (node->op()) {
            case MovHint: {
                ASSERT(node->child1().useKind() == UntypedUse);
                if (!node->child1()->shouldGenerate()) {
                    node->setOpAndDefaultFlags(ZombieHint);
                    node->child1() = Edge();
                    break;
                }
                node->setOpAndDefaultFlags(MovHint);
                break;
            }
                
            case ZombieHint: {
                // Currently we assume that DCE runs only once.
                RELEASE_ASSERT_NOT_REACHED();
                break;
            }
            
            default: {
                if (node->flags() & NodeHasVarArgs) {
                    for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++) {
                        Edge edge = m_graph.m_varArgChildren[childIdx];

                        if (!edge || edge.willNotHaveCheck())
                            continue;

                        m_insertionSet.insertNode(indexInBlock, SpecNone, Phantom, node->codeOrigin, edge);
                    }

                    node->convertToPhantomUnchecked();
                    node->children.reset();
                    node->setRefCount(1);
                    break;
                }

                node->convertToPhantom();
                eliminateIrrelevantPhantomChildren(node);
                node->setRefCount(1);
                break;
            } }
        }

        m_insertionSet.execute(block);
    }
Example #13
0
bool ofxXivelyOutput::parseResponseEeml(string _response) {
	if (bVerbose) printf("[Xively] start parsing eeml\n");
	try
	{
		pData.clear();
		DOMParser parser;
		AttrMap* pMap;
		AutoPtr<Document> pDoc = parser.parseMemory(_response.c_str(), _response.length());

		NodeIterator itElem(pDoc, NodeFilter::SHOW_ELEMENT);

		Node* pNode = itElem.nextNode();
		while (pNode)
		{
			if (pNode->nodeName() == XMLString("environment"))
			{
				pMap = (AttrMap*) pNode->attributes();
				sUpdated = pMap->getNamedItem("updated")->nodeValue();
			}

			if (pNode->nodeName() == XMLString("title"))
				sTitle = pNode->firstChild()->getNodeValue();
			if (pNode->nodeName() == XMLString("status"))
				sStatus = pNode->firstChild()->getNodeValue();
			if (pNode->nodeName() == XMLString("description"))
				sDescription = pNode->firstChild()->getNodeValue();
			if (pNode->nodeName() == XMLString("website"))
				sWebsite = pNode->firstChild()->getNodeValue();

			if (pNode->nodeName() == XMLString("location"))
			{
				//				pMap = (AttrMap*)pNode->attributes();
				//				location.sDomain = pMap->getNamedItem("domain")->nodeValue();
				//				location.sExposure = pMap->getNamedItem("exposure")->nodeValue();
				//				location.sDisposition = pMap->getNamedItem("disposition")->nodeValue();

				NodeIterator itChildren(pNode, NodeFilter::SHOW_ELEMENT);
				Node* pChild = itChildren.nextNode();
				while (pChild)
				{
					if (pChild->nodeName() == XMLString("name"))
						location.sName = pChild->firstChild()->nodeValue();
					if (pChild->nodeName() == XMLString("lat"))
						location.sLat = pChild->firstChild()->nodeValue();
					if (pChild->nodeName() == XMLString("lon"))
						location.sLon = pChild->firstChild()->nodeValue();

					pChild = itChildren.nextNode();
				}
			}

			if (pNode->nodeName() == XMLString("data"))
			{
				ofxXivelyData data;

				pMap = (AttrMap*) pNode->attributes();
				data.iId = atoi(pMap->getNamedItem("id")->nodeValue().c_str());

				NodeIterator itChildren(pNode, NodeFilter::SHOW_ELEMENT);
				Node* pChild = itChildren.nextNode();
				while (pChild)
				{
					if (pChild->nodeName() == XMLString("tag"))
						data.pTags.push_back(pChild->firstChild()->getNodeValue());

					if (pChild->nodeName() == XMLString("value"))
					{
						data.fValue = atof(pChild->firstChild()->getNodeValue().c_str());

						pMap = (AttrMap*) pChild->attributes();
						data.fValueMin = atof(pMap->getNamedItem("minValue")->nodeValue().c_str());
						data.fValueMax = atof(pMap->getNamedItem("maxValue")->nodeValue().c_str());
					}

					pChild = itChildren.nextNode();
				}

				pData.push_back(data);
			}

			pNode = itElem.nextNode();
		}
	}
	catch (Exception& exc)
	{
		printf("[Xively] Parse xml exception: %s\n", exc.displayText().c_str());
		return false;
	}
	if (bVerbose) printf("[Xively] finished parsing eeml\n");

	return true;
}
Example #14
0
int ConfigParser::parse(Poco::XML::Document* xmlDocument, NetworkLayout* networkLayout) {
	Node* configNode = xmlDocument->firstChild();
	if(!configNode || (configNode->nodeName()!=XMLConstants::CONFIG_TAG)){
		std::cout << "config.xml: No element with name " << XMLConstants::CONFIG_TAG << " at the appropiate place." << std::endl;
		exit(1);
	}
	Node* trafficNode = configNode->firstChild();
	if(!trafficNode || (trafficNode->nodeName()!=XMLConstants::TRAFFIC_TAG)){
		std::cout << "config.xml: No element with name " << XMLConstants::TRAFFIC_TAG << " at the appropiate place." << std::endl;
		exit(1);
	}

	int numTrafficNodes = 0;

	//For each traffic block
	while (trafficNode != 0) {
		ConfigContent* content = new ConfigContent();

		numTrafficNodes++;

		//initialize non-mandatory content
		content->tcp_flags = std::vector<Flags>();
		content->tcp_flags.push_back(SYN);
		content->icmp_type = 0;
		content->icmp_code = -1;
		content->dumpPath = std::pair<std::string, bool>("", false);
		content->destIP = IPAddress();
		content->sourceIP = IPAddress();
		content->inInterface = "";
		content->outInterface = "";
		content->numPackets = 1;

		Node* elementNode = trafficNode->firstChild();
		while (elementNode != 0){

			//elementNode must be an element node with name XMLConstants::SOURCEIPTAG or XMLConstants::SOURCEPORTTAG or ...
			if(		   (elementNode->nodeName()!=XMLConstants::SOURCE_IP_TAG)
					&& (elementNode->nodeName()!=XMLConstants::SOURCE_PORT_TAG)
					&& (elementNode->nodeName()!=XMLConstants::DESTINATION_IP_TAG)
					&& (elementNode->nodeName()!=XMLConstants::DESTINATION_PORT_TAG)
					&& (elementNode->nodeName()!=XMLConstants::PROTOCOL_TAG)
					&& (elementNode->nodeName()!=XMLConstants::TCP_FLAGS_TAG)
					&& (elementNode->nodeName()!=XMLConstants::ICMP_TYPE)
					&& (elementNode->nodeName()!=XMLConstants::ICMP_CODE)
					&& (elementNode->nodeName()!=XMLConstants::POLICY_TAG)
					&& (elementNode->nodeName()!=XMLConstants::IN_INTERFACE_TAG)
					&& (elementNode->nodeName()!=XMLConstants::OUT_INTERFACE_TAG)
					&& (elementNode->nodeName()!=XMLConstants::DUMP_TAG)
					&& (elementNode->nodeName()!=XMLConstants::ASCII_DUMP_TAG)
					&& (elementNode->nodeName()!=XMLConstants::NUM_PACKETS)){
				std::cout << "config.xml: XML element " << elementNode->nodeName() << " is not supported." << std::endl;
				exit(1);
			}

			Node* textNode = elementNode->firstChild();

			if(!textNode){
				std::cout << "config.xml: XML elements must contain something else than whitespace."<<std::endl;
				exit(1);
			}

			if (elementNode->nodeName() == XMLConstants::SOURCE_IP_TAG){
				std::string ip = textNode->nodeValue();
				removeWhitespace(ip);
				try {
					content->sourceIP = IPAddress(ip);
				} catch (Poco::Exception e) {
					std::cout << "config.xml: Parsed faulty source IP address" << ip << ": '" << e.message() << "'. Terminating." << std::endl;
					exit(1);
				}
			} else if (elementNode->nodeName() == XMLConstants::SOURCE_PORT_TAG) {
				if ((content->protocol != UDP) && (content->protocol != TCP)){
					std::cout << "config.xml: You can only specify a source port if you have already specified the protocol as tcp or udp." << std::endl;
					exit(1);
				}
				content->sourcePort = atoi(textNode->nodeValue().c_str());
			} else if (elementNode->nodeName() == XMLConstants::DESTINATION_IP_TAG) {
				std::string ip = textNode->nodeValue();
				removeWhitespace(ip);
				try {
					content->destIP = IPAddress(ip);
				} catch (Poco::Exception e) {
					std::cout << "config.xml: Parsed faulty destination IP address " << ip << ": '" << e.message() << "'. Terminating." << std::endl;
					exit(1);
				}
			} else if (elementNode->nodeName() == XMLConstants::DESTINATION_PORT_TAG) {
				if ((content->protocol != UDP) && (content->protocol != TCP)){
					std::cout << "config.xml: You can only specify a destination port if you have already specified the protocol as tcp or udp." << std::endl;
					exit(1);
				}
				content->destPort = atoi(textNode->nodeValue().c_str());
			} else if (elementNode->nodeName() == XMLConstants::PROTOCOL_TAG) {
				ProtocolFactory* factory = ProtocolFactory::getInstance();
				content->protocol = factory->parse(textNode->nodeValue());
			} else if (elementNode->nodeName() == XMLConstants::TCP_FLAGS_TAG) {
				if (content->protocol != TCP){
					std::cout << "config.xml: You can only specify tcp flags if you have already specified the protocol as tcp." << std::endl;
					exit(1);
				}

				Node* flagNode = elementNode->firstChild();
				while (flagNode != 0) {
					Node* textNode = flagNode->firstChild();

					if(!textNode){
						std::cout << "config.xml: XML elements must contain something else than whitespace."<<std::endl;
						exit(1);
					}

					std::string value = textNode->getNodeValue();
					removeWhitespace(value);
					if(value == "1") {
						if (flagNode->nodeName()==XMLConstants::URG_FLAG_TAG) {
							content->tcp_flags.push_back(URG);
						} else if (flagNode->nodeName()==XMLConstants::ACK_FLAG_TAG) {
							content->tcp_flags.push_back(ACK);
						} else if (flagNode->nodeName()==XMLConstants::PSH_FLAG_TAG) {
							content->tcp_flags.push_back(PSH);
						} else if (flagNode->nodeName()==XMLConstants::RST_FLAG_TAG) {
							content->tcp_flags.push_back(RST);
						} else if (flagNode->nodeName()==XMLConstants::SYN_FLAG_TAG) {
							content->tcp_flags.push_back(SYN);
						} else if (flagNode->nodeName()==XMLConstants::FIN_FLAG_TAG) {
							content->tcp_flags.push_back(FIN);
						} else {
							std::cout << "config.xml: XML element " << flagNode->nodeName() << " is not supported." << std::endl;
							exit(1);
						}
					} else if (value == "0") {
						if (flagNode->nodeName()==XMLConstants::SYN_FLAG_TAG) {
							for (std::vector<Flags>::iterator it = content->tcp_flags.begin(); it != content->tcp_flags.end(); it++) {
								if (*it == SYN) {
									content->tcp_flags.erase(it);
								}
							}

						}
					} else if ((flagNode->nodeName()!=XMLConstants::URG_FLAG_TAG)
								&& (flagNode->nodeName()!=XMLConstants::ACK_FLAG_TAG)
								&& (flagNode->nodeName()!=XMLConstants::PSH_FLAG_TAG)
								&& (flagNode->nodeName()!=XMLConstants::RST_FLAG_TAG)
								&& (flagNode->nodeName()!=XMLConstants::SYN_FLAG_TAG)
								&& (flagNode->nodeName()!=XMLConstants::FIN_FLAG_TAG)){
						std::cout << "config.xml: XML element " << flagNode->nodeName() << " is not supported as a tcp flag." << std::endl;
						exit(1);
					} else {
						std::cout << "config.xml: Content of XML element " << flagNode->nodeName() << " should be 0 or 1." << std::endl;
						exit(1);
					}

					flagNode = flagNode->nextSibling();
				}
			} else if (elementNode->nodeName() == XMLConstants::ICMP_TYPE) {
				if (content->protocol != ICMP){
					std::cout << "config.xml: You can only specify an icmp type if you have already specified the protocol as icmp." << std::endl;
					exit(1);
				}
				content->icmp_type = atoi(textNode->nodeValue().c_str());
			} else if (elementNode->nodeName() == XMLConstants::ICMP_CODE) {
				if (content->protocol != ICMP){
					std::cout << "config.xml: You can only specify an icmp code if you have already specified the protocol as icmp." << std::endl;
					exit(1);
				}
				content->icmp_code = atoi(textNode->nodeValue().c_str());
			} else if (elementNode->nodeName() == XMLConstants::POLICY_TAG) {
				PolicyFactory* factory = PolicyFactory::getInstance();
				content->policy = factory->parse(textNode->nodeValue());
			} else if (elementNode->nodeName() == XMLConstants::IN_INTERFACE_TAG) {
				std::string inIf = textNode->nodeValue();
				removeWhitespace(inIf);
				if(!networkLayout->hasInterface(inIf)){
					std::cout << "config.xml: You can only specify an in-interface that's specified in network_layout.xml" << std::endl;
					exit(1);
				}
				content->inInterface = inIf;
			} else if (elementNode->nodeName() == XMLConstants::OUT_INTERFACE_TAG) {
				std::string outIf = textNode->nodeValue();
				removeWhitespace(outIf);
				if(!networkLayout->hasInterface(outIf)){
					std::cout << "config.xml: You can only specify an out-interface that's specified in network_layout.xml" << std::endl;
					exit(1);
				}
				content->outInterface = outIf;
			} else if (elementNode->nodeName() == XMLConstants::DUMP_TAG) {
				std::string dumpFile = textNode->nodeValue();
				removeWhitespace(dumpFile);
				std::string path = _path + dumpFile;
				if(!fileExist(path)){
					std::cout << "config.xml: The specified dump file " << textNode->nodeValue() << " is not found in the config folder." << std::endl;
					exit(1);
				}
				content->dumpPath = std::pair<std::string, bool>(path, false);
			} else if (elementNode->nodeName() == XMLConstants::ASCII_DUMP_TAG) {
				std::string dumpFile = textNode->nodeValue();
				removeWhitespace(dumpFile);
				std::string path = _path + dumpFile;
				if(!fileExist(path)){
					std::cout << "config.xml: The specified ascii dump file " << textNode->nodeValue() << " is not found in the config folder." << std::endl;
					exit(1);
				}
				content->dumpPath = std::pair<std::string, bool>(path, true);
			} else if (elementNode->nodeName() ==  XMLConstants::NUM_PACKETS) {
				content->numPackets = atoi(textNode->nodeValue().c_str());
			}
			elementNode = elementNode->nextSibling();
		}

		if (content->dumpPath.first!="") {
			//traffic from dump file detected.
			if(content->inInterface == "" || content->outInterface == ""){
				std::cout << "config.xml: If you specify a " << (content->dumpPath.second?XMLConstants::ASCII_DUMP_TAG:XMLConstants::DUMP_TAG) << ", then you must also specify " << XMLConstants::IN_INTERFACE_TAG << "and " << XMLConstants::OUT_INTERFACE_TAG << "." << std::endl;
				exit(1);
			}
			//check existence of in- and out-interfaces.
			if (!networkLayout->hasInterface(content->inInterface) || !networkLayout->hasInterface(content->outInterface)){
				std::cout << "config.xml: The specified default in- and out-interfaces " << content->inInterface << " and " << content->outInterface << " do not exist within network_layout.xml." << std::endl;
				exit(1);
			}
			checkDump(content->dumpPath, content->inInterface, content->outInterface, networkLayout);
		} else {
			//src ip and dst ip must be set
			if ((content->sourceIP.toString() == "0.0.0.0") || (content->destIP.toString()=="0.0.0.0")){
				std::cout << "config.xml: No source or destination IP address specified. Otherwise you have to specify a dump file." << std::endl;
				exit(1);
			}
			//No dump file specified
			if (networkLayout->isInternal(content->sourceIP.toString(), content->destIP.toString())){
				//src and dst if must be set
				if((content->inInterface=="") || (content->outInterface=="")){
					std::cout << "config.xml: INTERN: Based on the specified ip addresses " << content->sourceIP.toString() << " and "<< content->destIP.toString() << ", the packet is classified as internal firewall traffic. You must specify the in- and out-interfaces properly." << std::endl;
					exit(1);
				}
				//check existence of in- and out-interfaces.
				if (!networkLayout->hasInterface(content->inInterface) || !networkLayout->hasInterface(content->outInterface)){
					std::cout << "config.xml: INTERN: The specified in- and out-interfaces " << content->inInterface << " and " << content->outInterface << " do not exist within network_layout.xml." << std::endl;
					exit(1);
				}
				//check source and destination
				if(content->sourceIP.toString() != networkLayout->getIpAddress(content->outInterface)) {
					std::cout << "config.xml: INTERN: Source ip address " << content->sourceIP.toString() << " does not correspond to the specified out-interface " << content->outInterface << " (" << networkLayout->getIpAddress(content->outInterface)<< ")" << std::endl;
					exit(1);
				}
				if (content->destIP.toString() != networkLayout->getIpAddress(content->inInterface)){
					std::cout << "config.xml: INTERN: Destination ip address " << content->destIP.toString() << " does not correspond to the specified in-interface " << content->inInterface << " (" << networkLayout->getIpAddress(content->inInterface)<< ")" << std::endl;
					exit(1);
				}
			} else if (networkLayout->isOutput(content->sourceIP.toString())){
				//src if must be set
				if(content->outInterface == ""){
					std::cout << "config.xml: OUTPUT: Based on the specified ip addresses " << content->sourceIP.toString() << " and "<< content->destIP.toString() << ", the packet is classified as firewall output traffic. You must specify the out-interface properly." << std::endl;
					exit(1);
				}
				//check existence of the out-interface.
				if (!networkLayout->hasInterface(content->outInterface)){
					std::cout << "config.xml: OUTPUT: The specified out-interface " << content->outInterface << " does not exist within network_layout.xml." << std::endl;
					exit(1);
				}
				//check source
				if(content->sourceIP.toString() != networkLayout->getIpAddress(content->outInterface)){
					std::cout << "config.xml: OUTPUT: Source ip address " << content->sourceIP.toString() << " does not correspond to the specified out-interface " << content->outInterface << " (" << networkLayout->getIpAddress(content->outInterface)<< ")" << std::endl;
					exit(1);
				}
			} else if (networkLayout->isInput(content->destIP.toString())) {
				//dst if must be set
				if(content->inInterface == ""){
					std::cout << "config.xml: INPUT: Based on the specified ip addresses " << content->sourceIP.toString() << " and "<< content->destIP.toString() << ", the packet is classified as firewall input traffic. You must specify the in-interface properly." << std::endl;
					exit(1);
				}
				//check existence of the in-interface.
				if (!networkLayout->hasInterface(content->inInterface)){
					std::cout << "config.xml: INPUT: The specified in-interface " << content->inInterface << " does not exist within network_layout.xml." << std::endl;
					exit(1);
				}
				//check destination
				if(content->destIP.toString() != networkLayout->getIpAddress(content->inInterface)){
					std::cout << "config.xml: INPUT: Destination ip address " << content->destIP.toString() << " does not correspond to the specified in-interface " << content->inInterface << " (" << networkLayout->getIpAddress(content->inInterface)<< ")" << std::endl;
					exit(1);
				}
			} else {
				//forward
				//src and dst if must be set
				if((content->inInterface == "") || (content->outInterface == "")){
					std::cout << "config.xml: FORWARD: Based on the specified ip addresses " << content->sourceIP.toString() << " and "<< content->destIP.toString() << ", the packet is classified as forward firewall traffic. You must specify the in- and out-interfaces properly." << std::endl;
					exit(1);
				}
				//check existence of in- and out-interfaces.
				if (!networkLayout->hasInterface(content->inInterface) || !networkLayout->hasInterface(content->outInterface)){
					std::cout << "config.xml: FORWARD: The specified in- and out-interfaces " << content->inInterface << " and " << content->outInterface << " do not exist within network_layout.xml." << std::endl;
					exit(1);
				}
			}
		}
		_content.push_back(content);

		trafficNode = trafficNode->nextSibling();
	}

	return numTrafficNodes;
}