6 * $Date: 2012-07-07 17:14:54 +0200 (Sa, 07. Jul 2012) $
7 ***************************************************************/
10 * \brief Implementation of the class DinoXmlScanner serving the
16 * This file is part of the Open Graph Drawing Framework (OGDF).
20 * See README.txt in the root directory of the OGDF installation for details.
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License
25 * Version 2 or 3 as published by the Free Software Foundation;
26 * see the file LICENSE.txt included in the packaging of this file
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
36 * You should have received a copy of the GNU General Public
37 * License along with this program; if not, write to the Free
38 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
39 * Boston, MA 02110-1301, USA.
41 * \see http://www.gnu.org/copyleft/gpl.html
42 ***************************************************************/
45 #include <ogdf/fileformats/DinoXmlScanner.h>
55 // C o n s t r u c t o r
57 DinoXmlScanner::DinoXmlScanner(const char *fileName
)
60 m_pLineBuffer
= new DinoLineBuffer(fileName
);
62 // Create current token string
63 m_pCurrentTokenString
= new char[DinoLineBuffer::c_maxStringLength
];
64 if (m_pCurrentTokenString
== 0)
65 OGDF_THROW(InsufficientMemoryException
);
66 for (int i
= 0; i
< DinoLineBuffer::c_maxStringLength
; i
++){
67 m_pCurrentTokenString
[i
] = '0';
70 } // DinoXmlScanner::DinoXmlScanner
73 // D e s t r u c t o r
75 DinoXmlScanner::~DinoXmlScanner()
77 // Destroy current token string
78 delete [] m_pCurrentTokenString
;
80 // Destroy line buffer
83 } // DinoXmlScanner::~DinoXmlScanner
86 // g e t N e x t T o k e n
88 // Take a look at the state machine of getNextToken() to understand
89 // what is going on here.
91 // TODO: It seems to be useful that this function throws an exception
92 // if something goes wrong.
93 XmlToken
DinoXmlScanner::getNextToken(){
95 // First skip whitespaces
96 m_pLineBuffer
->skipWhitespace();
98 // Let's have a look at the current character
99 char currentCharacter
= m_pLineBuffer
->getCurrentCharacter();
101 // End of file reached
102 if (currentCharacter
== EOF
){
106 // First we handle single characters with a switch statement
107 switch (currentCharacter
){
112 m_pLineBuffer
->moveToNextCharacter();
113 return openingBracket
;
120 m_pLineBuffer
->moveToNextCharacter();
121 return closingBracket
;
128 m_pLineBuffer
->moveToNextCharacter();
136 m_pLineBuffer
->moveToNextCharacter();
137 return exclamationMark
;
144 m_pLineBuffer
->moveToNextCharacter();
152 m_pLineBuffer
->moveToNextCharacter();
160 m_pLineBuffer
->moveToNextCharacter();
167 // Now we handle more complex token
170 if (isalpha(currentCharacter
)){
172 // Put a pointer to the beginning of the identifier
173 DinoLineBufferPosition startPosition
= m_pLineBuffer
->getCurrentPosition();
175 currentCharacter
= m_pLineBuffer
->moveToNextCharacter();
177 // Read valid identifier characters
178 while ((isalnum(currentCharacter
)) || // a..z|A..Z|0..9
179 (currentCharacter
== '.') ||
180 (currentCharacter
== ':') ||
181 (currentCharacter
== '_'))
183 currentCharacter
= m_pLineBuffer
->moveToNextCharacter();
186 // Copy identifier to currentTokenString
187 m_pLineBuffer
->extractString(startPosition
,
188 m_pLineBuffer
->getCurrentPosition(),
189 m_pCurrentTokenString
);
191 // Return identifier token
194 } // end of identifier
196 // Quoted characters " ... " or ' ... '
197 if ((currentCharacter
== '\"') ||
198 (currentCharacter
== '\''))
200 // Distinguish what kind of quote sign we have
202 if (currentCharacter
== '\"')
208 currentCharacter
= m_pLineBuffer
->moveToNextCharacter();
210 // Read until the closing quotation sign is found
211 // String is copied to m_pCurrentTokenString by readStringUntil()
213 readStringUntil('\"', false);
216 readStringUntil('\'', false);
219 // Skip over the end quote character
220 m_pLineBuffer
->moveToNextCharacter();
222 // Return token for quoted value
225 } // end of quoted characters
227 // An atributeValue, i.e. a sequence of characters, digits, minus - or dot .
228 if ((isalnum(currentCharacter
)) ||
229 (currentCharacter
== '-') ||
230 (currentCharacter
== '.'))
232 // Put a pointer to the beginning of the quoted text
233 DinoLineBufferPosition startPosition
= m_pLineBuffer
->getCurrentPosition();;
235 // Read until until an invalid character occurs
236 currentCharacter
= m_pLineBuffer
->moveToNextCharacter();
237 while ((isalnum(currentCharacter
)) ||
238 (currentCharacter
== '-') ||
239 (currentCharacter
== '.'))
241 currentCharacter
= m_pLineBuffer
->moveToNextCharacter();
244 // Copy attributeValue to currentTokenString
245 m_pLineBuffer
->extractString(startPosition
,
246 m_pLineBuffer
->getCurrentPosition(),
247 m_pCurrentTokenString
);
249 // Return token for attribute value
250 return attributeValue
;
252 } // end of an attributeValue
255 m_pLineBuffer
->moveToNextCharacter();
261 // t e s t N e x t T o k e n
263 XmlToken
DinoXmlScanner::testNextToken(){
265 // Save pointer to the current position
266 DinoLineBufferPosition originalPosition
= m_pLineBuffer
->getCurrentPosition();
268 // Call getNextToken()
269 XmlToken returnToken
= getNextToken();
271 // Set pointer back to the original position
272 m_pLineBuffer
->setCurrentPosition(originalPosition
);
280 // t e s t N e x t N e x t T o k e n
282 XmlToken
DinoXmlScanner::testNextNextToken(){
284 // Save pointer to the current position
285 DinoLineBufferPosition originalPosition
= m_pLineBuffer
->getCurrentPosition();
287 // Call getNextToken()
290 // Again Call getNextToken()
291 XmlToken returnToken
= getNextToken();
293 // Set pointer back to the original position
294 m_pLineBuffer
->setCurrentPosition(originalPosition
);
299 } // testNextNextToken
304 bool DinoXmlScanner::skipUntil(char searchCharacter
, bool skipOverSearchCharacter
){
306 while (m_pLineBuffer
->getCurrentCharacter() != EOF
){
308 // Search character has been found!
309 if (m_pLineBuffer
->getCurrentCharacter() == searchCharacter
){
311 // Move to the position behind the search character if desired
312 if (skipOverSearchCharacter
){
313 m_pLineBuffer
->moveToNextCharacter();
318 } // Search character has been found!
320 // Move to next character and proceed
321 m_pLineBuffer
->moveToNextCharacter();
330 // 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
332 bool DinoXmlScanner::skipUntilMatchingClosingBracket(){
334 // We assume that the opening bracket has already been read
335 int bracketParity
= 1;
337 while ((m_pLineBuffer
->getCurrentCharacter() != EOF
) &&
338 (bracketParity
!= 0))
340 // Opening bracket has been found!
341 if (m_pLineBuffer
->getCurrentCharacter() == '<'){
346 // Closing bracket has been found!
347 if (m_pLineBuffer
->getCurrentCharacter() == '>'){
352 // Move to next character and proceed
353 m_pLineBuffer
->moveToNextCharacter();
357 if (bracketParity
!= 0 )
362 } // skipUntilMatchingClosingBracket
365 // r e a d S t r i n g U n t i l
367 bool DinoXmlScanner::readStringUntil(char searchCharacter
,
368 bool includeSearchCharacter
){
370 // Remember start position
371 DinoLineBufferPosition startPosition
= m_pLineBuffer
->getCurrentPosition();
374 if (skipUntil(searchCharacter
, includeSearchCharacter
)){
376 // Copy found string to m_pCurrentTokenString
377 m_pLineBuffer
->extractString(startPosition
,
378 m_pLineBuffer
->getCurrentPosition(),
379 m_pCurrentTokenString
);
394 void DinoXmlScanner::test(){
396 bool terminate
= false;
397 XmlToken currentToken
;
401 cout
<< "Line " << getInputFileLineCounter() << ": ";
402 currentToken
= getNextToken();
404 switch (currentToken
){
414 case exclamationMark
:
427 cout
<< "Identifier: " << m_pCurrentTokenString
<< endl
;
430 cout
<< "Attribute value: " << m_pCurrentTokenString
<< endl
;
433 cout
<< "Quoted value: \"" << m_pCurrentTokenString
<< "\"" << endl
;
436 cout
<< "EOF" << endl
;
440 cout
<< "Invalid token!" << endl
;