/* * $Revision: 2565 $ * * last checkin: * $Author: gutwenger $ * $Date: 2012-07-07 17:14:54 +0200 (Sa, 07. Jul 2012) $ ***************************************************************/ /** \file * \brief Implementation of a line buffer serving the class DinoXmlScanner * * \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 "DinoLineBuffer.h" #include "../basic/String.h" #include "DinoTools.h" #include #include extern ofstream os; namespace ogdf { // Initialize static variables const int DinoLineBuffer::c_maxStringLength = OGDF_STRING_BUFFER_SIZE; const int DinoLineBuffer::c_maxLineLength = 200; const int DinoLineBuffer::c_maxNoOfLines = 20; // // ---------- D i n o L i n e B u f f e r P o s i t i o n ---------- // // // C o n s t r u c t o r // DinoLineBufferPosition::DinoLineBufferPosition( int lineNumber, int lineUpdateCount, int linePosition) { set(lineNumber, lineUpdateCount, linePosition); } // // C o p y C o n s t r u c t o r // DinoLineBufferPosition::DinoLineBufferPosition(const DinoLineBufferPosition &position) { m_lineNumber = position.m_lineNumber; m_lineUpdateCount = position.m_lineUpdateCount; m_linePosition = position.m_linePosition; } // // s e t // void DinoLineBufferPosition::set(int lineNumber, int lineUpdateCount, int linePosition) { OGDF_ASSERT((lineNumber >= 0) && (lineNumber < DinoLineBuffer::c_maxNoOfLines)) OGDF_ASSERT(lineUpdateCount >= 0) OGDF_ASSERT((linePosition >= 0) && (linePosition < DinoLineBuffer::c_maxLineLength)) m_lineNumber = lineNumber; m_lineUpdateCount = lineUpdateCount; m_linePosition = linePosition; } // set // // i n c r e m e n t P o s i t i o n // void DinoLineBufferPosition::incrementPosition() { ++m_linePosition; OGDF_ASSERT((m_linePosition >= 0) && (m_linePosition < DinoLineBuffer::c_maxLineLength)) } // increasePosition // // o p e r a t o r ! = // bool DinoLineBufferPosition::operator!=(const DinoLineBufferPosition &position) const { if ((m_lineNumber != position.m_lineNumber) || (m_lineUpdateCount != position.m_lineUpdateCount) || (m_linePosition != position.m_linePosition)) { return true; } return false; } // operator!= // // o p e r a t o r = // const DinoLineBufferPosition & DinoLineBufferPosition::operator=(const DinoLineBufferPosition &position) { if (&position != this){ m_lineNumber = position.getLineNumber(); m_lineUpdateCount = position.getLineUpdateCount(); m_linePosition = position.getLinePosition(); } return *this; } // operator= // // ---------- D i n o L i n e B u f f e r ---------- // // // C o n s t r u c t o r // DinoLineBuffer::DinoLineBuffer(const char *fileName) : m_pIs(0), m_pLinBuf(0), m_numberOfMostRecentlyReadLine(0), m_inputFileLineCounter(0) { // Open file m_pIs = new ifstream(fileName, ios::in); if (!(*m_pIs)) { DinoTools::reportError("DinoLineBuffer::DinoLineBuffer", __LINE__, "Error opening file!"); } // Create and initialize lineUpdateCountArray m_lineUpdateCountArray = new int[DinoLineBuffer::c_maxNoOfLines]; int i; for (i = 0; i < DinoLineBuffer::c_maxNoOfLines; i++){ m_lineUpdateCountArray[i] = 0; } // Create and initialize line buffer m_pLinBuf = new char[(DinoLineBuffer::c_maxNoOfLines * DinoLineBuffer::c_maxLineLength)]; if (m_pLinBuf == 0) OGDF_THROW(InsufficientMemoryException); for (i = 0; i < DinoLineBuffer::c_maxNoOfLines * DinoLineBuffer::c_maxLineLength; i++){ m_pLinBuf[i] = '0'; } // Read first line if (!m_pIs->eof()){ // Read first line m_pIs->getline(m_pLinBuf, DinoLineBuffer::c_maxLineLength); // Increase inputFileLineCounter ++m_inputFileLineCounter; // Increase updateCount ++(m_lineUpdateCountArray[0]); } // End of file is reached immeadiately else{ // Set eof marker *m_pLinBuf = EOF; } // Set position m_currentPosition.set(0, m_lineUpdateCountArray[0], 0); } // DinoLineBuffer::DinoLineBuffer // // D e s t r u c t o r // DinoLineBuffer::~DinoLineBuffer() { // destroy line buffer delete [] m_pLinBuf; // destroy lineUpdateCountArray delete [] m_lineUpdateCountArray; // Close file delete m_pIs; } // DinoLineBuffer::~DinoLineBuffer // // m o v e T o N e x t C h a r a c t e r // char DinoLineBuffer::moveToNextCharacter(){ // Return if end of file is reached if (getCurrentCharacter() == EOF){ return EOF; } // Increment position m_currentPosition.incrementPosition(); // End of line is reached, there can be some consecutive lines // with only \0 in it; hence we use a while loop while (getCurrentCharacter() == '\0'){ // Current line is equal to most recently read line, // i.e. we have to read a new line from the file if (m_currentPosition.getLineNumber() == m_numberOfMostRecentlyReadLine){ // Increment line pointer (modulo c_maxNoOfLines - 1) if (m_numberOfMostRecentlyReadLine == (DinoLineBuffer::c_maxNoOfLines - 1)){ m_numberOfMostRecentlyReadLine = 0; } else { ++m_numberOfMostRecentlyReadLine; } // Increment update count ++(m_lineUpdateCountArray[m_numberOfMostRecentlyReadLine]); // Increment inputFileLineCounter ++m_inputFileLineCounter; // Set current position m_currentPosition.set( m_numberOfMostRecentlyReadLine, m_lineUpdateCountArray[m_numberOfMostRecentlyReadLine], 0); // End of file is reached if (m_pIs->eof()){ // Set eof marker setCurrentCharacter(EOF); } // Read next line and put it to the new position else{ m_pIs->getline(getCurrentCharacterPointer(), DinoLineBuffer::c_maxLineLength); } } // Current line is equal to most recently read line // Current line is NOT equal to most recently read line, i.e. // it is not necessary to read a new line from the file but to // set the currentPosition to the next line which is already in // the line buffer. else{ int newLine; // Increment current line pointer (modulo c_maxNoOfLines - 1) if (m_currentPosition.getLineNumber() == (DinoLineBuffer::c_maxNoOfLines - 1)){ newLine = 0; } else { newLine = m_currentPosition.getLineNumber() + 1; } // Set current position m_currentPosition.set(newLine, m_lineUpdateCountArray[newLine], 0); } // Current line is NOT equal to most recently read line } // End of line is reached return getCurrentCharacter(); } // moveToNextCharacter // // s e t C u r r e n t P o s i t i o n // bool DinoLineBuffer::setCurrentPosition(const DinoLineBufferPosition &newPosition){ // Given positon is not valid if (!isValidPosition(newPosition)) { return false; } m_currentPosition = newPosition; return true; } // setCurrentPosition // // s k i p W h i t e s p a c e // void DinoLineBuffer::skipWhitespace() { if (getCurrentCharacter() == EOF) { return; } while ((isspace(getCurrentCharacter())) && (!(getCurrentCharacter() == EOF))) { moveToNextCharacter(); } } // skipWhitespace // // e x t r a c t S t r i n g // bool DinoLineBuffer::extractString( const DinoLineBufferPosition &startPosition, const DinoLineBufferPosition &endPosition, char *targetString) { // StartPosition invalid, probably because the line of the startPosition // has already been overwritten, i.e. the string is too long if (!isValidPosition(startPosition)) { ogdf::strcpy(targetString, DinoLineBuffer::c_maxStringLength, "String too long!"); return false; } // EndPosition must be valid OGDF_ASSERT(isValidPosition(endPosition)) // Remember original currentPosition DinoLineBufferPosition originalCurrentPosition = getCurrentPosition(); // Begin at startPosition setCurrentPosition(startPosition); // Copy characters to tempString int targetStringIndex = 0; while (getCurrentPosition() != endPosition) { // Check if eof OGDF_ASSERT(getCurrentCharacter() != EOF) // Put character into targetString targetString[targetStringIndex] = getCurrentCharacter(); ++targetStringIndex; // String too long if (targetStringIndex >= DinoLineBuffer::c_maxStringLength - 1){ ogdf::strcpy(targetString, DinoLineBuffer::c_maxStringLength, "String too long!"); // Set back the original current position setCurrentPosition(originalCurrentPosition); return false; } // Move to next character moveToNextCharacter(); } // Copy characters to tempString // Set back the original current position setCurrentPosition(originalCurrentPosition); // Terminate string targetString[targetStringIndex] = '\0'; return true; } // extractString // // i s V a l i d P o s i t i o n // bool DinoLineBuffer::isValidPosition(const DinoLineBufferPosition &position) const { // We can assume that the position is valid according to // array ranges since these things are checked in constructor and set of // class DinoLineBufferPosition // The line of the given position has already been overwritten if (position.getLineUpdateCount() != m_lineUpdateCountArray[position.getLineNumber()]) { return false; } return true; } // isValidPosition } // namespace ogdf