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; }
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); }
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; }
// 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; }
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; }
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; }
// 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(); }
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(); }
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(); }
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); }
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; }
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; }