Example #1
0
void VTTCue::determineTextDirection()
{
    DEFINE_STATIC_LOCAL(const String, rtTag, (ASCIILiteral("rt")));
    createWebVTTNodeTree();
    if (!m_webVTTNodeTree)
        return;

    // Apply the Unicode Bidirectional Algorithm's Paragraph Level steps to the
    // concatenation of the values of each WebVTT Text Object in nodes, in a
    // pre-order, depth-first traversal, excluding WebVTT Ruby Text Objects and
    // their descendants.
    StringBuilder paragraphBuilder;
    for (Node* node = m_webVTTNodeTree->firstChild(); node; node = NodeTraversal::next(node, m_webVTTNodeTree.get())) {
        // FIXME: The code does not match the comment above. This does not actually exclude Ruby Text Object descendant.
        if (!node->isTextNode() || node->localName() == rtTag)
            continue;

        paragraphBuilder.append(node->nodeValue());
    }

    String paragraph = paragraphBuilder.toString();
    if (!paragraph.length())
        return;

    for (size_t i = 0; i < paragraph.length(); ++i) {
        UChar current = paragraph[i];
        if (!current || isCueParagraphSeparator(current))
            return;

        if (UChar current = paragraph[i]) {
            UCharDirection charDirection = u_charDirection(current);
            if (charDirection == U_LEFT_TO_RIGHT) {
                m_displayDirection = CSSValueLtr;
                return;
            }
            if (charDirection == U_RIGHT_TO_LEFT || charDirection == U_RIGHT_TO_LEFT_ARABIC) {
                m_displayDirection = CSSValueRtl;
                return;
            }
        }
    }
}
Example #2
0
/**
 * Takes a pointer to an XML node that is assumed to point at a "material"
 * tag.
 * It reads the definition and produces a new Material object.
 * @param element A pointer to an Element node that is a "material" tag
 * @return A new Material object
 */
Material MaterialXMLParser::parse(Poco::XML::Element *element) const {
  using namespace Poco::XML;
  typedef AutoPtr<NamedNodeMap> NamedNodeMapPtr;
  NamedNodeMapPtr attrs = element->attributes();
  const auto id = attrs->getNamedItem(ID_ATT);
  if (!id || id->nodeValue().empty()) {
    throw std::invalid_argument("MaterialXMLReader::read() - No 'id' tag found "
                                "or emptry string provided.");
  }
  attrs->removeNamedItem(ID_ATT);

  MaterialBuilder builder;
  builder.setName(id->nodeValue());
  const auto nattrs = attrs->length();
  for (unsigned long i = 0; i < nattrs; ++i) {
    Node *node = attrs->item(i);
    addToBuilder(&builder, node->nodeName(), node->nodeValue());
  }
  return builder.build();
}
Example #3
0
static CSSValueID determineTextDirection(DocumentFragment* vttRoot)
{
    DEFINE_STATIC_LOCAL(const String, rtTag, ("rt"));
    ASSERT(vttRoot);

    // Apply the Unicode Bidirectional Algorithm's Paragraph Level steps to the
    // concatenation of the values of each WebVTT Text Object in nodes, in a
    // pre-order, depth-first traversal, excluding WebVTT Ruby Text Objects and
    // their descendants.
    TextDirection textDirection = LTR;
    for (Node* node = vttRoot->firstChild(); node; node = NodeTraversal::next(*node, vttRoot)) {
        if (!node->isTextNode() || node->localName() == rtTag)
            continue;

        bool hasStrongDirectionality;
        textDirection = determineDirectionality(node->nodeValue(), hasStrongDirectionality);
        if (hasStrongDirectionality)
            break;
    }
    return isLeftToRightDirection(textDirection) ? CSSValueLtr : CSSValueRtl;
}
Example #4
0
void TextTrackCue::determineTextDirection()
{
    DEFINE_STATIC_LOCAL(const String, rtTag, (ASCIILiteral("rt")));
    createWebVTTNodeTree();

    // Apply the Unicode Bidirectional Algorithm's Paragraph Level steps to the
    // concatenation of the values of each WebVTT Text Object in nodes, in a
    // pre-order, depth-first traversal, excluding WebVTT Ruby Text Objects and
    // their descendants.
    StringBuilder paragraphBuilder;
    for (Node* node = m_webVTTNodeTree->firstChild(); node; node = NodeTraversal::next(node, m_webVTTNodeTree.get())) {
        if (!node->isTextNode() || node->localName() == rtTag)
            continue;

        paragraphBuilder.append(node->nodeValue());
    }

    String paragraph = paragraphBuilder.toString();
    if (!paragraph.length())
        return;

    for (size_t i = 0; i < paragraph.length(); ++i) {
        UChar current = paragraph[i];
        if (!current || isCueParagraphSeparator(current))
            return;

        if (UChar current = paragraph[i]) {
            WTF::Unicode::Direction charDirection = WTF::Unicode::direction(current);
            if (charDirection == WTF::Unicode::LeftToRight) {
                m_displayDirection = CSSValueLtr;
                return;
            }
            if (charDirection == WTF::Unicode::RightToLeft
                || charDirection == WTF::Unicode::RightToLeftArabic) {
                m_displayDirection = CSSValueRtl;
                return;
            }
        }
    }
}
Example #5
0
File: Element.cpp Project: 119/vdc
void Element::normalize()
{
	Node* pCur = firstChild();
	while (pCur)
	{
		if (pCur->nodeType() == Node::ELEMENT_NODE)
		{
			pCur->normalize();
		}
		else if (pCur->nodeType() == Node::TEXT_NODE)
		{
			Node* pNext = pCur->nextSibling();
			while (pNext && pNext->nodeType() == Node::TEXT_NODE)
			{
				static_cast<Text*>(pCur)->appendData(pNext->nodeValue());
				removeChild(pNext);
				pNext = pCur->nextSibling();
			}
		}
		pCur = pCur->nextSibling();
	}
}
Example #6
0
String SmartClip::extractTextFromNode(Node* node)
{
    // Science has proven that no text nodes are ever positioned at y == -99999.
    int prevYPos = -99999;

    StringBuilder result;
    for (Node* currentNode = node; currentNode; currentNode = NodeTraversal::next(*currentNode, node)) {
        RenderStyle* style = currentNode->computedStyle();
        if (style && style->userSelect() == SELECT_NONE)
            continue;

        if (Node* nodeFromFrame = nodeInsideFrame(currentNode))
            result.append(extractTextFromNode(nodeFromFrame));

        IntRect nodeRect = currentNode->pixelSnappedBoundingBox();
        if (currentNode->renderer() && !nodeRect.isEmpty()) {
            if (currentNode->isTextNode()) {
                String nodeValue = currentNode->nodeValue();

                // It's unclear why we blacklist solitary "\n" node values.
                // Maybe we're trying to ignore <br> tags somehow?
                if (nodeValue == "\n")
                    nodeValue = "";

                if (nodeRect.y() != prevYPos) {
                    prevYPos = nodeRect.y();
                    result.append('\n');
                }

                result.append(nodeValue);
            }
        }
    }

    return result.toString();
}
float Tree::value() {
  return nodePtr->nodeValue();
}
Example #8
0
JSValue* JSNode::getValueProperty(ExecState* exec, int token) const
{
    switch (token) {
    case NodeNameAttrNum: {
        Node* imp = static_cast<Node*>(impl());
        return jsStringOrNull(exec, imp->nodeName());
    }
    case NodeValueAttrNum: {
        Node* imp = static_cast<Node*>(impl());
        return jsStringOrNull(exec, imp->nodeValue());
    }
    case NodeTypeAttrNum: {
        Node* imp = static_cast<Node*>(impl());
        return jsNumber(exec, 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(exec, imp->namespaceURI());
    }
    case PrefixAttrNum: {
        Node* imp = static_cast<Node*>(impl());
        return jsStringOrNull(exec, imp->prefix());
    }
    case LocalNameAttrNum: {
        Node* imp = static_cast<Node*>(impl());
        return jsStringOrNull(exec, imp->localName());
    }
    case BaseURIAttrNum: {
        Node* imp = static_cast<Node*>(impl());
        return jsStringOrNull(exec, imp->baseURI());
    }
    case TextContentAttrNum: {
        Node* imp = static_cast<Node*>(impl());
        return jsStringOrNull(exec, 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 #9
0
String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element* element, size_t* resultDistance, bool* resultIsInCellAbove)
{
    OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels));
    // We stop searching after we've seen this many chars
    const unsigned int charsSearchedThreshold = 500;
    // This is the absolute max we search.  We allow a little more slop than
    // charsSearchedThreshold, to make it more likely that we'll search whole nodes.
    const unsigned int maxCharsSearched = 600;
    // If the starting element is within a table, the cell that contains it
    HTMLTableCellElement* startingTableCell = 0;
    bool searchedCellAbove = false;

    if (resultDistance)
        *resultDistance = notFound;
    if (resultIsInCellAbove)
        *resultIsInCellAbove = false;
    
    // walk backwards in the node tree, until another element, or form, or end of tree
    int unsigned lengthSearched = 0;
    Node* n;
    for (n = element->traversePreviousNode();
         n && lengthSearched < charsSearchedThreshold;
         n = n->traversePreviousNode())
    {
        if (n->hasTagName(formTag)
            || (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement()))
        {
            // We hit another form element or the start of the form - bail out
            break;
        } else if (n->hasTagName(tdTag) && !startingTableCell) {
            startingTableCell = static_cast<HTMLTableCellElement*>(n);
        } else if (n->hasTagName(trTag) && startingTableCell) {
            String result = searchForLabelsAboveCell(regExp.get(), startingTableCell, resultDistance);
            if (!result.isEmpty()) {
                if (resultIsInCellAbove)
                    *resultIsInCellAbove = true;
                return result;
            }
            searchedCellAbove = true;
        } else if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) {
            // For each text chunk, run the regexp
            String nodeString = n->nodeValue();
            // add 100 for slop, to make it more likely that we'll search whole nodes
            if (lengthSearched + nodeString.length() > maxCharsSearched)
                nodeString = nodeString.right(charsSearchedThreshold - lengthSearched);
            int pos = regExp->searchRev(nodeString);
            if (pos >= 0) {
                if (resultDistance)
                    *resultDistance = lengthSearched;
                return nodeString.substring(pos, regExp->matchedLength());
            }
            lengthSearched += nodeString.length();
        }
    }

    // If we started in a cell, but bailed because we found the start of the form or the
    // previous element, we still might need to search the row above us for a label.
    if (startingTableCell && !searchedCellAbove) {
         String result = searchForLabelsAboveCell(regExp.get(), startingTableCell, resultDistance);
        if (!result.isEmpty()) {
            if (resultIsInCellAbove)
                *resultIsInCellAbove = true;
            return result;
        }
    }
    return String();
}
Example #10
0
static v8::Handle<v8::Value> nodeValueAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
    INC_STATS("DOM.Node.nodeValue._get");
    Node* imp = V8Node::toNative(info.Holder());
    return v8StringOrNull(imp->nodeValue());
}
JSValue JSNamedNodeMap::setNamedItemNS(ExecState* exec, const ArgList& args)
{
    NamedNodeMap* imp = static_cast<NamedNodeMap*>(impl());
    ExceptionCode ec = 0;
    Node* newNode = toNode(args.at(0));

    if (newNode && newNode->nodeType() == Node::ATTRIBUTE_NODE && imp->element()) {
        if (!allowSettingSrcToJavascriptURL(exec, imp->element(), newNode->nodeName(), newNode->nodeValue()))
            return jsNull();
    }

    JSValue result = toJS(exec, globalObject(), WTF::getPtr(imp->setNamedItemNS(newNode, ec)));
    setDOMException(exec, ec);
    return result;
}
void ElementTest::testNodeByPathNS()
{
	/*
	<ns1:root xmlns:ns1="urn:ns1">
		<ns1:elem1>
			<ns2:elemA xmlns:ns2="urn:ns2"/>
			<ns3:elemA xmlns:ns3="urn:ns2"/>
		</ns1:elem1>
		<ns1:elem2>
			<ns2:elemB ns2:attr1="value1" xmlns:ns2="urn:ns2"/>
			<ns2:elemB ns2:attr1="value2" xmlns:ns2="urn:ns2"/>
			<ns2:elemB ns2:attr1="value3" xmlns:ns2="urn:ns2"/>
			<ns2:elemC ns2:attr1="value1" xmlns:ns2="urn:ns2">
				<ns2:elemC1 ns2:attr1="value1"/>
				<ns2:elemC2/>
			</ns2:elemC>
			<ns2:elemC ns2:attr1="value2" xmlns:ns2="urn:ns2"/>
		</ns1:elem2>
	</ns1:root>	
	*/
	AutoPtr<Document> pDoc   = new Document;
	
	AutoPtr<Element> pRoot   = pDoc->createElementNS("urn:ns1", "ns1:root");
	AutoPtr<Element> pElem1  = pDoc->createElementNS("urn:ns1", "ns1:elem1");
	AutoPtr<Element> pElem11 = pDoc->createElementNS("urn:ns2", "ns2:elemA");
	AutoPtr<Element> pElem12 = pDoc->createElementNS("urn:ns2", "ns2:elemA");
	AutoPtr<Element> pElem2  = pDoc->createElementNS("urn:ns1", "ns1:elem2");
	AutoPtr<Element> pElem21 = pDoc->createElementNS("urn:ns2", "ns2:elemB");
	AutoPtr<Element> pElem22 = pDoc->createElementNS("urn:ns2", "ns2:elemB");
	AutoPtr<Element> pElem23 = pDoc->createElementNS("urn:ns2", "ns2:elemB");
	AutoPtr<Element> pElem24 = pDoc->createElementNS("urn:ns2", "ns2:elemC");
	AutoPtr<Element> pElem25 = pDoc->createElementNS("urn:ns2", "ns2:elemC");
	
	pElem21->setAttributeNS("urn:ns2", "ns2:attr1", "value1");
	pElem22->setAttributeNS("urn:ns2", "ns2:attr1", "value2");
	pElem23->setAttributeNS("urn:ns2", "ns2:attr1", "value3");
	
	pElem24->setAttributeNS("urn:ns2", "ns2:attr1", "value1");
	pElem25->setAttributeNS("urn:ns2", "ns2:attr1", "value2");
	
	AutoPtr<Element> pElem241 = pDoc->createElementNS("urn:ns2", "elemC1");
	AutoPtr<Element> pElem242 = pDoc->createElementNS("urn:ns2", "elemC2");
	pElem241->setAttributeNS("urn:ns2", "ns2:attr1", "value1");
	pElem24->appendChild(pElem241);
	pElem24->appendChild(pElem242);
	
	pElem1->appendChild(pElem11);
	pElem1->appendChild(pElem12);
	pElem2->appendChild(pElem21);
	pElem2->appendChild(pElem22);
	pElem2->appendChild(pElem23);
	pElem2->appendChild(pElem24);
	pElem2->appendChild(pElem25);

	pRoot->appendChild(pElem1);
	pRoot->appendChild(pElem2);	

	pDoc->appendChild(pRoot);
	
	Element::NSMap nsMap;
	nsMap.declarePrefix("ns1", "urn:ns1");
	nsMap.declarePrefix("NS2", "urn:ns2");
	
	Node* pNode = pRoot->getNodeByPathNS("/", nsMap);
	assert (pNode == pRoot);
	
	pNode = pRoot->getNodeByPathNS("/ns1:elem1", nsMap);
	assert (pNode == pElem1);

	pNode = pDoc->getNodeByPathNS("/ns1:root/ns1:elem1", nsMap);
	assert (pNode == pElem1);

	pNode = pRoot->getNodeByPathNS("/ns1:elem2", nsMap);
	assert (pNode == pElem2);
	
	pNode = pRoot->getNodeByPathNS("/ns1:elem1/NS2:elemA", nsMap);
	assert (pNode == pElem11);
	
	pNode = pRoot->getNodeByPathNS("/ns1:elem1/NS2:elemA[0]", nsMap);
	assert (pNode == pElem11);

	pNode = pRoot->getNodeByPathNS("/ns1:elem1/NS2:elemA[1]", nsMap);
	assert (pNode == pElem12);
	
	pNode = pRoot->getNodeByPathNS("/ns1:elem1/NS2:elemA[2]", nsMap);
	assert (pNode == 0);
	
	pNode = pRoot->getNodeByPathNS("/ns1:elem2/NS2:elemB", nsMap);
	assert (pNode == pElem21);
	
	pNode = pRoot->getNodeByPathNS("/ns1:elem2/NS2:elemB[0]", nsMap);
	assert (pNode == pElem21);

	pNode = pRoot->getNodeByPathNS("/ns1:elem2/NS2:elemB[1]", nsMap);
	assert (pNode == pElem22);

	pNode = pRoot->getNodeByPathNS("/ns1:elem2/NS2:elemB[2]", nsMap);
	assert (pNode == pElem23);

	pNode = pRoot->getNodeByPathNS("/ns1:elem2/NS2:elemB[3]", nsMap);
	assert (pNode == 0);
	
	pNode = pRoot->getNodeByPathNS("/ns1:elem2/NS2:elemB[@NS2:attr1]", nsMap);
	assert (pNode && pNode->nodeValue() == "value1");

	pNode = pRoot->getNodeByPathNS("/ns1:elem2/NS2:elemB[@NS2:attr2]", nsMap);
	assert (pNode == 0);

	pNode = pRoot->getNodeByPathNS("/ns1:elem2/NS2:elemB[@NS2:attr1='value2']", nsMap);
	assert (pNode == pElem22);

	pNode = pRoot->getNodeByPathNS("/ns1:elem2/NS2:elemC[@NS2:attr1='value1']/NS2:elemC1", nsMap);
	assert (pNode == pElem241);

	pNode = pRoot->getNodeByPathNS("/ns1:elem2/NS2:elemC[@NS2:attr1='value1']/NS2:elemC1[@NS2:attr1]", nsMap);
	assert (pNode && pNode->nodeValue() == "value1");

	pNode = pRoot->getNodeByPathNS("/NS2:elem1", nsMap);
	assert (pNode == 0);

	pNode = pDoc->getNodeByPathNS("//NS2:elemB[@NS2:attr1='value1']", nsMap);
	assert (pNode == pElem21);
	
	pNode = pDoc->getNodeByPathNS("//NS2:elemB[@NS2:attr1='value2']", nsMap);
	assert (pNode == pElem22);

	pNode = pDoc->getNodeByPathNS("//NS2:elemB[@NS2:attr1='value3']", nsMap);
	assert (pNode == pElem23);

	pNode = pDoc->getNodeByPathNS("//NS2:elemB[@NS2:attr1='value4']", nsMap);
	assert (pNode == 0);

	pNode = pDoc->getNodeByPathNS("//[@NS2:attr1='value1']", nsMap);
	assert (pNode == pElem21);
	
	pNode = pDoc->getNodeByPathNS("//[@NS2:attr1='value2']", nsMap);
	assert (pNode == pElem22);
}
void ElementTest::testNodeByPath()
{
	/*
	<root>
		<elem1>
			<elemA/>
			<elemA/>
		</elem1>
		<elem2>
			<elemB attr1="value1"/>
			<elemB attr1="value2"/>
			<elemB attr1="value3"/>
			<elemC attr1="value1">
				<elemC1 attr1="value1"/>
				<elemC2/>
			</elemC>
			<elemC attr1="value2"/>
		</elem2>
	</root>
	*/

	AutoPtr<Document> pDoc   = new Document;
	
	AutoPtr<Element> pRoot   = pDoc->createElement("root");
	AutoPtr<Element> pElem1  = pDoc->createElement("elem1");
	AutoPtr<Element> pElem11 = pDoc->createElement("elemA");
	AutoPtr<Element> pElem12 = pDoc->createElement("elemA");
	AutoPtr<Element> pElem2  = pDoc->createElement("elem2");
	AutoPtr<Element> pElem21 = pDoc->createElement("elemB");
	AutoPtr<Element> pElem22 = pDoc->createElement("elemB");
	AutoPtr<Element> pElem23 = pDoc->createElement("elemB");
	AutoPtr<Element> pElem24 = pDoc->createElement("elemC");
	AutoPtr<Element> pElem25 = pDoc->createElement("elemC");
	
	pElem21->setAttribute("attr1", "value1");
	pElem22->setAttribute("attr1", "value2");
	pElem23->setAttribute("attr1", "value3");
	
	pElem24->setAttribute("attr1", "value1");
	pElem25->setAttribute("attr1", "value2");
	
	AutoPtr<Element> pElem241 = pDoc->createElement("elemC1");
	AutoPtr<Element> pElem242 = pDoc->createElement("elemC2");
	pElem241->setAttribute("attr1", "value1");
	pElem24->appendChild(pElem241);
	pElem24->appendChild(pElem242);
	
	pElem1->appendChild(pElem11);
	pElem1->appendChild(pElem12);
	pElem2->appendChild(pElem21);
	pElem2->appendChild(pElem22);
	pElem2->appendChild(pElem23);
	pElem2->appendChild(pElem24);
	pElem2->appendChild(pElem25);

	pRoot->appendChild(pElem1);
	pRoot->appendChild(pElem2);	
	
	pDoc->appendChild(pRoot);
	
	Node* pNode = pRoot->getNodeByPath("/");
	assert (pNode == pRoot);
	
	pNode = pRoot->getNodeByPath("/elem1");
	assert (pNode == pElem1);
	
	pNode = pDoc->getNodeByPath("/root/elem1");
	assert (pNode == pElem1);
	
	pNode = pRoot->getNodeByPath("/elem2");
	assert (pNode == pElem2);
	
	pNode = pRoot->getNodeByPath("/elem1/elemA");
	assert (pNode == pElem11);
	
	pNode = pRoot->getNodeByPath("/elem1/elemA[0]");
	assert (pNode == pElem11);

	pNode = pRoot->getNodeByPath("/elem1/elemA[1]");
	assert (pNode == pElem12);
	
	pNode = pRoot->getNodeByPath("/elem1/elemA[2]");
	assert (pNode == 0);
	
	pNode = pRoot->getNodeByPath("/elem2/elemB");
	assert (pNode == pElem21);
	
	pNode = pRoot->getNodeByPath("/elem2/elemB[0]");
	assert (pNode == pElem21);

	pNode = pRoot->getNodeByPath("/elem2/elemB[1]");
	assert (pNode == pElem22);

	pNode = pRoot->getNodeByPath("/elem2/elemB[2]");
	assert (pNode == pElem23);

	pNode = pRoot->getNodeByPath("/elem2/elemB[3]");
	assert (pNode == 0);
	
	pNode = pRoot->getNodeByPath("/elem2/elemB[@attr1]");
	assert (pNode && pNode->nodeValue() == "value1");

	pNode = pRoot->getNodeByPath("/elem2/elemB[@attr2]");
	assert (pNode == 0);

	pNode = pRoot->getNodeByPath("/elem2/elemB[@attr1='value2']");
	assert (pNode == pElem22);

	pNode = pRoot->getNodeByPath("/elem2/elemC[@attr1='value1']/elemC1");
	assert (pNode == pElem241);

	pNode = pRoot->getNodeByPath("/elem2/elemC[@attr1='value1']/elemC1[@attr1]");
	assert (pNode && pNode->nodeValue() == "value1");

	pNode = pDoc->getNodeByPath("//elemB[@attr1='value1']");
	assert (pNode == pElem21);
	
	pNode = pDoc->getNodeByPath("//elemB[@attr1='value2']");
	assert (pNode == pElem22);

	pNode = pDoc->getNodeByPath("//elemB[@attr1='value3']");
	assert (pNode == pElem23);

	pNode = pDoc->getNodeByPath("//elemB[@attr1='value4']");
	assert (pNode == 0);

	pNode = pDoc->getNodeByPath("//[@attr1='value1']");
	assert (pNode == pElem21);

	pNode = pDoc->getNodeByPath("//[@attr1='value2']");
	assert (pNode == pElem22);
}
Example #14
0
/**
 * Parse incomming message (from server).
 * @param str Incomming server message
 * @return Message in Command structure
 */
Command XMLTool::parseXML(string str) {
	Command cmd;

	try  {
		DOMParser parser = DOMParser(0);
		AutoPtr<Document> pDoc = parser.parseString(str);
		NodeIterator it(pDoc, NodeFilter::SHOW_ELEMENT);
		Node* pNode = it.nextNode();
		NamedNodeMap* attributes = NULL;
		Node* attribute = NULL;

		while (pNode)  {
			if (pNode->nodeName().compare("server_adapter") == 0) {
				if (pNode->hasAttributes()) {
					attributes = pNode->attributes();
					for(unsigned int i = 0; i < attributes->length(); i++) {
						attribute = attributes->item(i);
						if (attribute->nodeName().compare("protocol_version") == 0) {
							cmd.protocol_version = attribute->nodeValue();
						}

						else if (attribute->nodeName().compare("state") == 0) {
							cmd.state = attribute->nodeValue();
						}
						// FIXME - id attribute is here only for backward compatibility, it should be removed in Q1/2016
						else if (attribute->nodeName().compare("euid") == 0 || attribute->nodeName().compare("id") == 0) {
							cmd.euid = stoull(attribute->nodeValue(), nullptr, 0);
						}

						else if (attribute->nodeName().compare("device_id") == 0) {
							cmd.device_id = atoll(attribute->nodeValue().c_str());
						}

						else if (attribute->nodeName().compare("time") == 0) {
							cmd.time = atoll(attribute->nodeValue().c_str());
						}

						else {
							log.error("Unknow attribute for SERVER_ADAPTER : " + fromXMLString(attribute->nodeName()));
						}
					}
					attributes->release();
				}
			}

			else if (pNode->nodeName().compare("value") == 0) {
				if(cmd.state == "getparameters" || cmd.state == "parameters"){
					string inner = pNode->innerText();
					string device_id = "";

					if (pNode->hasAttributes()) {
						attributes = pNode->attributes();
						string device_id = "";
						for(unsigned int i = 0; i < attributes->length(); i++) {
							attribute = attributes->item(i);
							if (attribute->nodeName().compare("device_id") == 0) {
								device_id = toNumFromString(attribute->nodeValue());
							}
						}
						attributes->release();
					}
					cmd.params.value.push_back({inner, device_id});
				}
				else {
					float val = atof(pNode->innerText().c_str());

					if (pNode->hasAttributes()) {
						int module_id = 0;
						attributes = pNode->attributes();
						for(unsigned int i = 0; i < attributes->length(); i++) {
							attribute = attributes->item(i);
							if (attribute->nodeName().compare("module_id") == 0) {
								module_id = toNumFromString(attribute->nodeValue());
							}
						}
						cmd.values.push_back({module_id, val});  //TODO Hex number is processed wrongly
						attributes->release();
					}
				}
			}
			else if (pNode->nodeName().compare("parameter") == 0) {
				if (pNode->hasAttributes()) {
					attributes = pNode->attributes();
					for(unsigned int i = 0; i < attributes->length(); i++) {
						attribute = attributes->item(i);
						if (attribute->nodeName().compare("param_id") == 0 || attribute->nodeName().compare("id") == 0) {
							cmd.params.param_id = toNumFromString(attribute->nodeValue());
						}
						else if (attribute->nodeName().compare("euid") == 0) {
							cmd.params.euid = toNumFromString(attribute->nodeValue());
						}
					}
					attributes->release();
				}
			}
			pNode = it.nextNode();
		}
	}
	catch (Poco::Exception& e) {
		log.error("Invalid format of incoming message!" + e.displayText());
		cmd.state = "error";
	}
	return cmd;
}
Example #15
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;
}