diff -r 000000000000 -r 2e3d3ce01487 tzpcside/tzcompiler/Source/TZScanner.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tzpcside/tzcompiler/Source/TZScanner.cpp Tue Feb 02 10:12:00 2010 +0200 @@ -0,0 +1,225 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// DST TZ Database Compiler +// +// + +#include "TzGlobals.h" +#include +#include +#include "TZDocument.h" +#include "TZScanner.h" +#include "TZNode.h" + +#include + +using namespace std; +//============================================================================ +// CTzCpScanner::CTzCpScanner +// Parser construction +//============================================================================ +CTzCpScanner::CTzCpScanner() + { + //Add valid characters + iValidChars = "+-_<>=:/%"; + } +//============================================================================ +// CTzCpScanner::~CTzCpScanner +// Parser destructor +//============================================================================ +CTzCpScanner::~CTzCpScanner() + { + } +//============================================================================ +// CTzCpScanner::Scan +// From MScanner +// Returns KErrNone if succesful or any other TzErrorCode +//============================================================================ +int CTzCpScanner::Scan(const char* aFileName) + { + iFileName = aFileName; + dbFile.open(aFileName); + + if (dbFile.is_open()) + { + dbFile.clear(); //This resets the eof flag and character position + scanState = EWaitFirstChar; + iLineNo = 0; + iColumnNo = 0; + ControlScanning(); + dbFile.close(); + return TzGlobals::ETzNone; + } + else + //File was not opened + { + cout << "Cannot open " << aFileName << endl; + throw TzGlobals::ETzAbortScannerFileIOError; + } + } +//============================================================================ +// CTzCpScanner::ControlScanning +// Reads the data file line by line. Each line is converted to a number of +// CTzNodes and ownership of the node is passed to the document. +// The general structure of a node is split into elements and attributes +// An 'element' node encapsulates the entire line as read from the data file +// by owning 'attribute' nodes, the actual fields on the line. +// The decisions made here are purely based on the first character of each +// line in the file to be parsed. The parser is unaware of the content or +// meaning of the file being parsed. +// Current rules used are: +// 1: We are only interested in lines that start with 'R','Z','L' or '\t' +// 2: The end of a token is a newline, tab, space or '#' +// 3: If a line starts with a tab the element is created as a child of the +// previous node +// 4: All other elements are created as chilren of the document root node +// 5: There is no limit on the number of attributes owned by an element +//============================================================================ +void CTzCpScanner::ControlScanning() + + { + char tmpChar; + char firstChar; + string tmpString; + + do + { + if (dbFile.eof()) + tmpChar = EOF; // define something out of the range of normal characters + else + { + dbFile.get(tmpChar); // get next char + ++iColumnNo; + } + + switch (scanState) + { + case EWaitFirstChar: + { + ++iLineNo; // we have a new line + iColumnNo = 0; // reset the column count + firstChar = tmpChar; + tmpString.erase(); // is this the right call to empty the string ? + if ((tmpChar == 'R') || (tmpChar == 'Z') || (tmpChar == 'L')) + { + tmpString += tmpChar; + iDocument->CreateRootChildElement(); + scanState = EWaitTokenEnd; + } + else if (tmpChar == '\t') + { + iDocument->CreateChildElement(); + tmpString += tmpChar; + // this creates an element whose name is '/t' + // We add two '/t' to achieve the same number of fields in the Stdtimealignment and Zone lines + iDocument->AddAttribute(tmpString.c_str()); + iDocument->AddAttribute(tmpString.c_str()); + tmpString.erase(); // clear the string for the next state + scanState = EWaitTokenStart; + } + else if (tmpChar == '\n') + { + // do nothing + } + else if ((tmpChar == KCharOlsonStartOfComment) || isspace(tmpChar)) + { + // ignore the whole line + scanState = EWaitLineFeed; + } + else if (tmpChar != EOF) + { + iDocument->HandleScanError(iFileName.c_str(),iLineNo,iColumnNo,tmpChar); + } + } + break; + + case EWaitTokenEnd: + { + // can we assume that there will always be a whitespace before a comment ('#')? + // how about 'CR'; the model assumes there will be a 'CRLF', perhaps that's not right + if ((tmpChar == ' ') || (tmpChar == '\t') || (tmpChar == '\n') || (tmpChar == EOF)) + { + iDocument->AddAttribute(tmpString.c_str()); + tmpString.erase(); // clear the string for the next state + if (tmpChar == '\n') + { + scanState = EWaitFirstChar; + if (firstChar != 'Z') + { + iDocument->CloseElement(); + } + } + else + { + scanState = EWaitTokenStart; + } + } + else + { + std::string strValidChars = iValidChars; + int pos = strValidChars.find(tmpChar); + if ((!isalpha(tmpChar)) && (!isdigit(tmpChar)) && (pos == string::npos)) + { + iDocument->HandleScanError(iFileName.c_str(),iLineNo,iColumnNo,tmpChar); + } + + tmpString += tmpChar; + } + } + break; + + case EWaitTokenStart: + { + if (tmpChar == '#') + { + // ignore the whole line + scanState = EWaitLineFeed; + //If a comment appears on a zone line we don't want to close the element + if (firstChar != 'Z') + { + iDocument->CloseElement(); + } + } + else if ((tmpChar != ' ') && (tmpChar != '\t') && (tmpChar != '\n')) // valid char + { + tmpString += tmpChar; + scanState = EWaitTokenEnd; + } + } + break; + + case EWaitLineFeed: + { + // ignore every thing till the end of line + if (tmpChar == '\n') + { + scanState = EWaitFirstChar; + } + } + break; + + default: + { + cout << "State Error!" << endl; + } + break; + } + } + while (tmpChar != EOF); + iDocument->CloseElement(); + } + +//============================================================================ +// End of file +//============================================================================