Exemple #1
0
bool GraphMLParser::readData(
	GraphAttributes &GA,
	const node &v, const XmlTagObject &nodeData)
{
	XmlAttributeObject *keyId;
	nodeData.findXmlAttributeObjectByName("key", keyId);

	if(keyId == NULL) {
		cerr << "ERROR: Node data does not have a key.\n";
		return false;
	}

	const long attrs = GA.attributes();
	std::stringstream value(nodeData.getValue());

	switch (graphml::toAttribute(m_attrName[keyId->getValue()])) {
	case graphml::a_nodeLabel:
		if(attrs & GraphAttributes::nodeLabel) {
			value >> GA.label(v);
		}
		break;
	case graphml::a_x:
		if(attrs & GraphAttributes::nodeGraphics) {
			value >> GA.x(v);
		}
Exemple #2
0
static inline bool readColor(Color &color, const XmlTagObject &tag)
{
	XmlAttributeObject *redAttr, *greenAttr, *blueAttr, *alphaAttr;
	tag.findXmlAttributeObjectByName("red", redAttr);
	tag.findXmlAttributeObjectByName("green", greenAttr);
	tag.findXmlAttributeObjectByName("blue", blueAttr);
	tag.findXmlAttributeObjectByName("alpha", alphaAttr);

	if(!redAttr || !greenAttr || !blueAttr) {
		OGDF_ERROR("Missing compound attrribute on color tag " << "(line " << tag.getLine() << ").");
		return false;
	}

	int compound;

	std::istringstream is;

	is.clear();
	is.str(redAttr->getValue());
	is >> compound;
	color.red(static_cast<uint8_t>(compound));

	is.clear();
	is.str(greenAttr->getValue());
	is >> compound;
	color.green(static_cast<uint8_t>(compound));

	is.clear();
	is.str(blueAttr->getValue());
	is >> compound;
	color.blue(static_cast<uint8_t>(compound));

	if(alphaAttr) {
		is.clear();
		is.str(alphaAttr->getValue());
		is >> compound;
		color.alpha(static_cast<uint8_t>(compound));
	}

	return true;
}
Exemple #3
0
static inline bool readVizAttribute(
	GraphAttributes &GA, node v,
	const XmlTagObject &tag)
{
	const long attrs = GA.attributes();

	if(tag.getName() == "viz:position") {
		if(attrs & GraphAttributes::nodeGraphics) {
			XmlAttributeObject *xAttr, *yAttr, *zAttr;
			tag.findXmlAttributeObjectByName("x", xAttr);
			tag.findXmlAttributeObjectByName("y", yAttr);
			tag.findXmlAttributeObjectByName("z", zAttr);

			if(!xAttr || !yAttr) {
				OGDF_ERROR("Missing \"x\" or \"y\" on position tag "
				          << "(line " << tag.getLine() << ").");
				return false;
			}

			std::istringstream is;

			is.clear();
			is.str(xAttr->getValue());
			is >> GA.x(v);

			is.clear();
			is.str(yAttr->getValue());
			is >> GA.y(v);

			// z attribute is optional and avaliable only in \a threeD mode.
			if(zAttr && (attrs & GraphAttributes::threeD)) {
				is.clear();
				is.str(zAttr->getValue());
				is >> GA.z(v);
			}
		}
Exemple #4
0
bool Parser::readCluster(
	Graph &G, ClusterGraph &C, ClusterGraphAttributes *CA, cluster rootCluster,
	const XmlTagObject &rootTag)
{
	List<XmlTagObject *> nodeTags;
	rootTag.findSonXmlTagObjectByName("node", nodeTags);

	for(XmlTagObject *obj : nodeTags) {
		const XmlTagObject &nodeTag = *obj;

		XmlAttributeObject *idAttr;
		nodeTag.findXmlAttributeObjectByName("id", idAttr);
		if(!idAttr) {
			OGDF_ERROR("node is missing an attribute "
			          << "(line " << nodeTag.getLine() << ").");
		}

		// Node is a cluster iff it contains other nodes.
		XmlTagObject *nodesTag;
		nodeTag.findSonXmlTagObjectByName("nodes", nodesTag);
		if(nodesTag) {
			// Node tag found, therefore it is a cluster.
			const cluster c = C.newCluster(rootCluster);
			m_clusterId[idAttr->getValue()] = c;

			if(!readCluster(G, C, CA, c, *nodesTag)) {
				return false;
			}
		} else {
			// Node tag not found, therefore it is "normal" node.
			const node v = G.newNode();
			C.reassignNode(v, rootCluster);
			m_nodeId[idAttr->getValue()] = v;

			if(CA) {
				readAttributes(*CA, v, nodeTag);
			}
		}
	}

	return true;
}
Exemple #5
0
//
// p a r s e
//
// Take a look at the state machine of parse() to understand
// what is going on here.
//
// TODO: It seems to be useful that this function throws an exception
//       if something goes wrong.
XmlTagObject *XmlParser::parse()
{
    // Increment recursion depth
    ++m_recursionDepth;

    // currentTagObject is the tag object we want to create
    // in this invocation of parse()
    XmlTagObject *currentTagObject = 0;

    // Now we are in the start state of the state machine
    for( ; ; )
    {
        XmlToken token = m_pScanner->getNextToken();

        // Expect "<", otherwise failure
        if (token != openingBracket) {
            reportError("XmlParser::parse",
                        __LINE__,
                        "Opening Bracket expected!",
                        getInputFileLineCounter());
        }

        // Let's look what comes after "<"
        token = m_pScanner->getNextToken();

        // Read "?", i.e. we have the XML header line <? ... ?>
        if (token == questionMark) {

            // Skip until we reach the matching question mark
            if (!m_pScanner->skipUntil('?')) {
                reportError("XmlParser::parse",
                            __LINE__,
                            "Could not found the matching '?'",
                            getInputFileLineCounter());
            }

            // Consume ">", otherwise failure
            token = m_pScanner->getNextToken();
            if (token != closingBracket) {
                reportError("XmlParser::parse",
                            __LINE__,
                            "Closing Bracket expected!",
                            getInputFileLineCounter());
            }

            // Go to start state of the state machine
            continue;

        } // end of Read "?"

        // Read "!", i.e. we have a XML comment <!-- bla -->
        if (token == exclamationMark) {

            // A preambel comment <!lala > which could be also nested
            if ((m_pScanner->getNextToken() != minus) ||
                    (m_pScanner->getNextToken() != minus))
            {
                if (!m_pScanner->skipUntilMatchingClosingBracket()) {

                    reportError("XmlParser::parse",
                                __LINE__,
                                "Could not find closing comment bracket!",
                                getInputFileLineCounter());
                }

                continue;
            }

            // Find end of comment
            bool endOfCommentFound = false;
            while (!endOfCommentFound) {

                // Skip until we find a - (and skip over it)
                if (!m_pScanner->skipUntil('-', true)) {
                    reportError("XmlParser::parse",
                                __LINE__,
                                "Closing --> of comment not found!",
                                getInputFileLineCounter());
                }

                // The next characters must be -> (note that one minus is already consumed)
                if ((m_pScanner->getNextToken() == minus) &&
                        (m_pScanner->getNextToken() == closingBracket))
                {
                    endOfCommentFound = true;
                }

            } // while

            // Go to start state of the state machine
            continue;

        } // end of Read "!"

        // We have found an identifier, i.e. a tag name
        if (token == identifier) {

            // Get hash element of token string
            HashedString *tagName =
                hashString(m_pScanner->getCurrentTokenString());

            // Create new tag object
            currentTagObject = new XmlTagObject(tagName);
            if (currentTagObject == 0) {
                OGDF_THROW(InsufficientMemoryException);
            }
            //push (opening) tagName to stack
            m_tagObserver.push(tagName->key());
            // set depth of current tag object
            currentTagObject->setDepth(m_recursionDepth);

            // set line of the tag object in the parsed xml document
            currentTagObject->setLine(getInputFileLineCounter());

            // Next token
            token = m_pScanner->getNextToken();

            // Again we found an identifier, so it must be an attribute
            if (token == identifier) {

                // Read list of attributes
                do {
                    // Save the attribute name
                    HashedString *attributeName =
                        hashString(m_pScanner->getCurrentTokenString());

                    // Consume "=", otherwise failure
                    token = m_pScanner->getNextToken();
                    if (token != equalSign)
                    {
                        reportError("XmlParser::parse",
                                    __LINE__,
                                    "Equal Sign expected!",
                                    getInputFileLineCounter());
                    }

                    // Read value
                    token = m_pScanner->getNextToken();
                    if ((token != quotedValue) &&
                            (token != identifier) &&
                            (token != attributeValue))
                    {
                        reportError("XmlParser::parse",
                                    __LINE__,
                                    "No valid attribute value!",
                                    getInputFileLineCounter());
                    }

                    // Create a new XmlAttributeObject
                    XmlAttributeObject *currentAttributeObject =
                        new XmlAttributeObject(attributeName, hashString(m_pScanner->getCurrentTokenString()));
                    if (currentAttributeObject == 0) {
                        OGDF_THROW(InsufficientMemoryException);
                    }

                    // Append attribute to attribute list of the current tag object
                    appendAttributeObject(currentTagObject, currentAttributeObject);

                    // Get next token
                    token = m_pScanner->getNextToken();

                }
                while (token == identifier);

            } // Found an identifier of an attribute

            // Read "/", i.e. the tag is ended immeadiately, e.g.
            // <A ... /> without a closing tag </A>
            if (token == slash) {

                // Consume ">", otherwise failure
                token = m_pScanner->getNextToken();
                if (token != closingBracket)
                {
                    reportError("XmlParser::parse",
                                __LINE__,
                                "Closing Bracket expected!",
                                getInputFileLineCounter());
                }

                // The tag is closed and ended so we return
                string s = m_tagObserver.pop();
                --m_recursionDepth;
                return currentTagObject;

            } // end of Read "/"

            // Read ">", i.e. the tag is closed and we
            // expect some content
            if (token == closingBracket) {

                // We read something different from "<", so we have to
                // deal with a tag value now, i.e. a string inbetween the
                // opening and the closing tag, e.g. <A ...> lalala </A>
                if (m_pScanner->testNextToken() != openingBracket) {

                    // Read the characters until "<" is reached and put them into
                    // currentTagObject
                    m_pScanner->readStringUntil('<');
                    currentTagObject->m_pTagValue = hashString(m_pScanner->getCurrentTokenString());

                    // We expect a closing tag now, i.e. </id>
                    token = m_pScanner->getNextToken();
                    if (token != openingBracket)
                    {
                        reportError("XmlParser::parse",
                                    __LINE__,
                                    "Opening Bracket expected!",
                                    getInputFileLineCounter());
                    }

                    token = m_pScanner->getNextToken();
                    if (token != slash)
                    {
                        reportError("XmlParser::parse",
                                    __LINE__,
                                    "Slash expected!",
                                    getInputFileLineCounter());
                    }

                    token = m_pScanner->getNextToken();
                    if (token != identifier)
                    {
                        reportError("XmlParser::parse",
                                    __LINE__,
                                    "Identifier expected!",
                                    getInputFileLineCounter());
                    }

                    // next token is the closing tag
                    string nextTag(m_pScanner->getCurrentTokenString());
                    // pop corresponding tag from stack
                    string s = m_tagObserver.pop();
                    // compare the two tags
                    if (s != nextTag)
                    {
                        // the closing tag doesn't correspond to the opening tag:
                        reportError("XmlParser::parse",
                                    __LINE__,
                                    "wrong closing tag!",
                                    getInputFileLineCounter());
                    }

                    token = m_pScanner->getNextToken();
                    if (token != closingBracket)
                    {
                        reportError("XmlParser::parse",
                                    __LINE__,
                                    "Closing Bracket expected!",
                                    getInputFileLineCounter());
                    }

                    // The tag is closed so we return
                    --m_recursionDepth;
                    return currentTagObject;

                } // end of read something different from "<"

                // Found "<", so a (series of) new tag begins and we have to perform
                // recursive invocation of parse()
                //
                // There are two exceptions:
                // - a slash follows afer <, i.e. we have a closing tag
                // - an exclamation mark follows after <, i.e. we have a comment
                while (m_pScanner->testNextToken() == openingBracket) {

                    // Leave the while loop if a closing tag occurs
                    if (m_pScanner->testNextNextToken() == slash) {
                        break;
                    }

                    // Ignore comments
                    if (m_pScanner->testNextNextToken() == exclamationMark) {

                        // Comment must start with <!--
                        if ((m_pScanner->getNextToken() != openingBracket) ||
                                (m_pScanner->getNextToken() != exclamationMark) ||
                                (m_pScanner->getNextToken() != minus) ||
                                (m_pScanner->getNextToken() != minus))
                        {
                            reportError("XmlParser::parse",
                                        __LINE__,
                                        "Comment must start with <!--",
                                        getInputFileLineCounter());
                        }

                        // Find end of comment
                        bool endOfCommentFound = false;
                        while (!endOfCommentFound) {

                            // Skip until we find a - (and skip over it)
                            if (!m_pScanner->skipUntil('-', true)) {
                                reportError("XmlParser::parse",
                                            __LINE__,
                                            "Closing --> of comment not found!",
                                            getInputFileLineCounter());
                            }

                            // The next characters must be -> (note that one minus is already consumed)
                            if ((m_pScanner->getNextToken() == minus) &&
                                    (m_pScanner->getNextToken() == closingBracket))
                            {
                                endOfCommentFound = true;
                            }

                        } // while

                        // Proceed with outer while loop
                        continue;

                    } // Ignore comments

                    // The new tag object is a son of the current tag object
                    XmlTagObject *sonTagObject = parse();
                    appendSonTagObject(currentTagObject, sonTagObject);

                } // while

                // Now we have found all tags.
                // We expect a closing tag now, i.e. </id>
                token = m_pScanner->getNextToken();
                if (token != openingBracket)
                {
                    reportError("XmlParser::parse",
                                __LINE__,
                                "Opening Bracket expected!",
                                getInputFileLineCounter());
                }

                token = m_pScanner->getNextToken();
                if (token != slash)
                {
                    reportError("XmlParser::parse",
                                __LINE__,
                                "Slash expected!",
                                getInputFileLineCounter());
                }

                token = m_pScanner->getNextToken();
                if (token != identifier)
                {
                    reportError("XmlParser::parse",
                                __LINE__,
                                "Identifier expected!",
                                getInputFileLineCounter());
                }

                // next token is the closing tag
                string nextTag(m_pScanner->getCurrentTokenString());
                // pop corresponding tag from stack
                string s = m_tagObserver.pop();
                // compare the two tags
                if (s != nextTag)
                {
                    // the closing tag doesn't correspond to the opening tag:
                    reportError("XmlParser::parse",
                                __LINE__,
                                "wrong closing tag!",
                                getInputFileLineCounter());
                }

                token = m_pScanner->getNextToken();
                if (token != closingBracket)
                {
                    reportError("XmlParser::parse",
                                __LINE__,
                                "Closing Bracket expected!",
                                getInputFileLineCounter());
                }

                --m_recursionDepth;

                // check if Document contains code after the last closing bracket
                if (m_recursionDepth == 0) {
                    token = m_pScanner->getNextToken();
                    if (token != endOfFile) {
                        reportError("XmlParser::parse",
                                    __LINE__,
                                    "Document contains code after the last closing bracket!",
                                    getInputFileLineCounter());
                    }
                }

                return currentTagObject;

            } // end of Read ">"

            OGDF_ASSERT(false)
            //continue;

        } // end of found identifier

        OGDF_ASSERT(false)

    } // end of while (true)