/* * $Revision: 2565 $ * * last checkin: * $Author: gutwenger $ * $Date: 2012-07-07 17:14:54 +0200 (Sa, 07. Jul 2012) $ ***************************************************************/ /** \file * \brief Implementation of the class DinoXmlScanner serving the * class DinoXmlParser * * \author Dino Ahr * * \par License: * This file is part of the Open Graph Drawing Framework (OGDF). * * \par * Copyright (C)
* See README.txt in the root directory of the OGDF installation for details. * * \par * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * Version 2 or 3 as published by the Free Software Foundation; * see the file LICENSE.txt included in the packaging of this file * for details. * * \par * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * \par * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * \see http://www.gnu.org/copyleft/gpl.html ***************************************************************/ #include "DinoXmlScanner.h" #include #include extern ofstream os; namespace ogdf { // // C o n s t r u c t o r // DinoXmlScanner::DinoXmlScanner(const char *fileName) { // Create line buffer m_pLineBuffer = new DinoLineBuffer(fileName); // Create current token string m_pCurrentTokenString = new char[DinoLineBuffer::c_maxStringLength]; if (m_pCurrentTokenString == 0) OGDF_THROW(InsufficientMemoryException); for (int i = 0; i < DinoLineBuffer::c_maxStringLength; i++){ m_pCurrentTokenString[i] = '0'; } } // DinoXmlScanner::DinoXmlScanner // // D e s t r u c t o r // DinoXmlScanner::~DinoXmlScanner() { // Destroy current token string delete [] m_pCurrentTokenString; // Destroy line buffer delete m_pLineBuffer; } // DinoXmlScanner::~DinoXmlScanner // // g e t N e x t T o k e n // // Take a look at the state machine of getNextToken() to understand // what is going on here. // // TODO: It seems to be useful that this function throws an exception // if something goes wrong. XmlToken DinoXmlScanner::getNextToken(){ // First skip whitespaces m_pLineBuffer->skipWhitespace(); // Let's have a look at the current character char currentCharacter = m_pLineBuffer->getCurrentCharacter(); // End of file reached if (currentCharacter == EOF){ return endOfFile; } // First we handle single characters with a switch statement switch (currentCharacter){ // Opening Bracket case '<': { m_pLineBuffer->moveToNextCharacter(); return openingBracket; } break; // Closing Bracket case '>': { m_pLineBuffer->moveToNextCharacter(); return closingBracket; } break; // Question Mark case '?': { m_pLineBuffer->moveToNextCharacter(); return questionMark; } break; // Exclamation Mark case '!': { m_pLineBuffer->moveToNextCharacter(); return exclamationMark; } break; // Minus case '-': { m_pLineBuffer->moveToNextCharacter(); return minus; } break; // Slash case '/': { m_pLineBuffer->moveToNextCharacter(); return slash; } break; // Equal Sign case '=': { m_pLineBuffer->moveToNextCharacter(); return equalSign; } break; } // end of switch // Now we handle more complex token // Identifier if (isalpha(currentCharacter)){ // Put a pointer to the beginning of the identifier DinoLineBufferPosition startPosition = m_pLineBuffer->getCurrentPosition(); currentCharacter = m_pLineBuffer->moveToNextCharacter(); // Read valid identifier characters while ((isalnum(currentCharacter)) || // a..z|A..Z|0..9 (currentCharacter == '.') || (currentCharacter == ':') || (currentCharacter == '_')) { currentCharacter = m_pLineBuffer->moveToNextCharacter(); } // Copy identifier to currentTokenString m_pLineBuffer->extractString(startPosition, m_pLineBuffer->getCurrentPosition(), m_pCurrentTokenString); // Return identifier token return identifier; } // end of identifier // Quoted characters " ... " or ' ... ' if ((currentCharacter == '\"') || (currentCharacter == '\'')) { // Distinguish what kind of quote sign we have bool doubleQuote; if (currentCharacter == '\"') doubleQuote = true; else doubleQuote = false; // Skip quote sign currentCharacter = m_pLineBuffer->moveToNextCharacter(); // Read until the closing quotation sign is found // String is copied to m_pCurrentTokenString by readStringUntil() if (doubleQuote){ readStringUntil('\"', false); } else{ readStringUntil('\'', false); } // Skip over the end quote character m_pLineBuffer->moveToNextCharacter(); // Return token for quoted value return quotedValue; } // end of quoted characters // An atributeValue, i.e. a sequence of characters, digits, minus - or dot . if ((isalnum(currentCharacter)) || (currentCharacter == '-') || (currentCharacter == '.')) { // Put a pointer to the beginning of the quoted text DinoLineBufferPosition startPosition = m_pLineBuffer->getCurrentPosition();; // Read until until an invalid character occurs currentCharacter = m_pLineBuffer->moveToNextCharacter(); while ((isalnum(currentCharacter)) || (currentCharacter == '-') || (currentCharacter == '.')) { currentCharacter = m_pLineBuffer->moveToNextCharacter(); } // Copy attributeValue to currentTokenString m_pLineBuffer->extractString(startPosition, m_pLineBuffer->getCurrentPosition(), m_pCurrentTokenString); // Return token for attribute value return attributeValue; } // end of an attributeValue // No valid token m_pLineBuffer->moveToNextCharacter(); return invalidToken; } // getNextToken // // t e s t N e x t T o k e n // XmlToken DinoXmlScanner::testNextToken(){ // Save pointer to the current position DinoLineBufferPosition originalPosition = m_pLineBuffer->getCurrentPosition(); // Call getNextToken() XmlToken returnToken = getNextToken(); // Set pointer back to the original position m_pLineBuffer->setCurrentPosition(originalPosition); // Return token return returnToken; } // testNextToken // // t e s t N e x t N e x t T o k e n // XmlToken DinoXmlScanner::testNextNextToken(){ // Save pointer to the current position DinoLineBufferPosition originalPosition = m_pLineBuffer->getCurrentPosition(); // Call getNextToken() getNextToken(); // Again Call getNextToken() XmlToken returnToken = getNextToken(); // Set pointer back to the original position m_pLineBuffer->setCurrentPosition(originalPosition); // Return token return returnToken; } // testNextNextToken // // s k i p U n t i l // bool DinoXmlScanner::skipUntil(char searchCharacter, bool skipOverSearchCharacter){ while (m_pLineBuffer->getCurrentCharacter() != EOF){ // Search character has been found! if (m_pLineBuffer->getCurrentCharacter() == searchCharacter){ // Move to the position behind the search character if desired if (skipOverSearchCharacter){ m_pLineBuffer->moveToNextCharacter(); } return true; } // Search character has been found! // Move to next character and proceed m_pLineBuffer->moveToNextCharacter(); } // while (!EOF) return false; } // skipUntil // // s k i p U n t i l M a t c h i n g C l o s i n g B r a c k e t // bool DinoXmlScanner::skipUntilMatchingClosingBracket(){ // We assume that the opening bracket has already been read int bracketParity = 1; while ((m_pLineBuffer->getCurrentCharacter() != EOF) && (bracketParity != 0)) { // Opening bracket has been found! if (m_pLineBuffer->getCurrentCharacter() == '<'){ ++bracketParity; } // Closing bracket has been found! if (m_pLineBuffer->getCurrentCharacter() == '>'){ --bracketParity; } // Move to next character and proceed m_pLineBuffer->moveToNextCharacter(); } // while if (bracketParity != 0 ) return false; else return true; } // skipUntilMatchingClosingBracket // // r e a d S t r i n g U n t i l // bool DinoXmlScanner::readStringUntil(char searchCharacter, bool includeSearchCharacter){ // Remember start position DinoLineBufferPosition startPosition = m_pLineBuffer->getCurrentPosition(); // Use skipUntil() if (skipUntil(searchCharacter, includeSearchCharacter)){ // Copy found string to m_pCurrentTokenString m_pLineBuffer->extractString(startPosition, m_pLineBuffer->getCurrentPosition(), m_pCurrentTokenString); return true; } // An error occurred else{ return false; } } // getStringUntil // // t e s t // void DinoXmlScanner::test(){ bool terminate = false; XmlToken currentToken; while (!terminate){ cout << "Line " << getInputFileLineCounter() << ": "; currentToken = getNextToken(); switch (currentToken){ case openingBracket: cout << "<" << endl; break; case closingBracket: cout << ">" << endl; break; case questionMark: cout << "?" << endl; break; case exclamationMark: cout << "!" << endl; break; case minus: cout << "-" << endl; break; case slash: cout << "/" << endl; break; case equalSign: cout << "<" << endl; break; case identifier: cout << "Identifier: " << m_pCurrentTokenString << endl; break; case attributeValue: cout << "Attribute value: " << m_pCurrentTokenString << endl; break; case quotedValue: cout << "Quoted value: \"" << m_pCurrentTokenString << "\"" << endl; break; case endOfFile: cout << "EOF" << endl; terminate = true; break; default: cout << "Invalid token!" << endl; } // switch } // while } // testScanner } // namespace ogdf