1 // Copyright (C) 2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "SimanIO_Configuration.hxx"
24 // maximum length of the line in the parsed conf file
25 const int MAX_BUFFER_SIZE=10000;
29 SimanIO_Configuration::SimanIO_Configuration()
33 ///! Returns true is the given symbol is white space
34 static bool IsWhite(const char theSym) {
35 return theSym == ' ' || theSym == '\t';
38 ///! Returns true if theLine starts with theCommand, returns in theVal rest part of the line in this case
39 static bool IsCommand(const char* theCommand, char* theLine, char*& theVal) {
40 string aLine(theLine);
41 char* aComPtr = (char*)theCommand;
43 while(*aComPtr != 0 && *theVal != 0) {
44 if (IsWhite(*aComPtr)) { // skip white spaces in the command line
48 if (IsWhite(*theVal)) { // skip white spaces in the processed line
52 //cout<<"Compare symbols "<<tolower(*aComPtr)<<" and "<<tolower(*theVal)<<endl;
53 if (tolower(*aComPtr) != tolower(*theVal)) // symbols are not match (case is not significant)
58 if (*aComPtr == 0) { // command has been found
59 while(*theVal != 0 && IsWhite(*theVal)) { // skip white spaces in the processed line
67 ///! Returns true if theText1 fully equal to theText2
68 static bool IsValue(const char* theText1, const char* theText2) {
70 for(a = 0; theText1[a] != 0 && theText2[a] != 0; a++)
71 if (theText1[a] != theText2[a]) return false;
72 return theText1[a] == 0 && theText2[a] == 0;
75 ///! Converts string to the integer value, or returns the default vaule if failed
76 static int toInt(const char* theStr, int theDefault) {
79 aResult = atol(theStr);
86 // unification of the error handling in the Parse method
87 #define PARSE_ERROR(condition, message) if (condition) {cerr<<message<<endl; return false;}
89 bool SimanIO_Configuration::Parse(const char* theConfFileName)
91 ifstream f(theConfFileName);
93 PARSE_ERROR(!f.good(), "Can not read conf file "<<theConfFileName)
94 char aBuffer[MAX_BUFFER_SIZE];
95 myBuffer = aBuffer; // buffer for one line reading
96 myReuseLine = false; // to read current line from the file
97 char* aVal; // value in line, that is located after the identifier of the command
100 if (IsCommand("Study ID :", myBuffer, aVal)) {
101 // skip study ID: this info is known in Link
102 } else if (IsCommand("Scenario ID :", myBuffer, aVal)) {
103 // skip scenario ID: this info is known in Link
104 } else if (IsCommand("User ID :", myBuffer, aVal)) {
105 // skip user ID: this info is known in Link
106 } else if (IsCommand("Activity", myBuffer, aVal)) {
107 if (!ParseActivity(aVal)) return false;
109 PARSE_ERROR(true, "Invalid line of conf file: '"<<myBuffer<<"'");
115 bool SimanIO_Configuration::ParseActivity(char* aName)
117 SimanIO_Activity aNewActivity;
118 aNewActivity.SetName(aName);
119 int activityID = -1; // to be imported later
120 char* aVal; // value in line, that is located after the identifier of the command
123 if (IsCommand("Activity ID :", myBuffer, aVal)) {
124 PARSE_ERROR(activityID != -1, "Duplicated activity identifier '"<<myBuffer<<"'");
125 activityID = toInt(aVal, -1);
126 PARSE_ERROR(activityID < 1, "Invalid activity identifier '"<<aVal<<"'");
127 } else if (IsCommand("Module :", myBuffer, aVal) || IsCommand("SALOME Module :", myBuffer, aVal)) { // read only if module not yet imported before
129 PARSE_ERROR(aNewActivity.Module()[0] != 0, "Duplicated module name in '"<<myBuffer<<"'")
130 PARSE_ERROR(aVal[0] == 0, "Invalid module name in '"<<myBuffer<<"'")
131 aNewActivity.SetModule(aVal);
132 } else if (IsCommand("Document :", myBuffer, aVal)) {
133 if (!ParseDocument(aVal, aNewActivity)) return false;
134 } else { // unknown command will be processed in higher level method
139 PARSE_ERROR(activityID == -1, "Activity '"<<aNewActivity.Name()<<"' ID is not defined");
140 PARSE_ERROR(aNewActivity.Module()[0] == 0, "Module of the activity '"<<aNewActivity.Name()<<"' is not defined");
141 if (!IsValue("null", aNewActivity.Module())) // skip activities with module name "null"
142 AddActivity(aNewActivity, activityID);
146 bool SimanIO_Configuration::ParseDocument(char* aName, SimanIO_Activity& theActivity)
148 SimanIO_Document aNewDocument;
149 aNewDocument.SetName(aName);
150 int aDocID = -1; // to be imported later
151 char* aVal; // value in line, that is located after the identifier of the command
154 if (IsCommand("Document ID :", myBuffer, aVal)) {
155 PARSE_ERROR(aDocID != -1, "Duplicated document identifier '"<<myBuffer<<"'");
156 aDocID = toInt(aVal, -1);
157 PARSE_ERROR(aDocID < 1, "Invalid document identifier '"<<aVal<<"'");
158 } else if (IsCommand("Source file:", myBuffer, aVal) || IsCommand("Result file:", myBuffer, aVal)) {
159 if (!ParseFile(aNewDocument)) return false;
160 } else { // unknown command will be processed in higher level method
165 PARSE_ERROR(aDocID == -1, "Document '"<<aNewDocument.Name()<<"' ID is not defined");
166 theActivity.AddDocument(aDocID, aNewDocument);
170 bool SimanIO_Configuration::ParseFile(SimanIO_Document& theDocument)
172 SimanIO_File aNewFile;
174 int aDocID = -1; // to be imported later
175 char* aVal; // value in line, that is located after the identifier of the command
177 // current line contains one of the next two commands
178 if (IsCommand("Result file :", myBuffer, aVal)) {
179 aNewFile.result = true;
181 } else if (IsCommand("Source file :", myBuffer, aVal)) {
182 aNewFile.result = false;
185 PARSE_ERROR(aNewFile.url.empty(), "File '"<<myBuffer<<"' has invalid URL");
188 if (IsCommand("Automatic processing :", myBuffer, aVal)) {
190 if (IsCommand("file-download", aVal, aVal2)) aNewFile.proc = FILE_DOWNLOAD;
191 else if (IsCommand("file-import", aVal, aVal2)) aNewFile.proc = FILE_IMPORT;
192 else PARSE_ERROR(true, "Invalid automatic processing value '"<<aVal<<"'");
193 } else if (IsCommand("State :", myBuffer, aVal)) {
195 if (IsCommand("file-actual", aVal, aVal2)) aNewFile.state = FILE_ACTUAL;
196 else if (IsCommand("file-outdated", aVal, aVal2)) aNewFile.state = FILE_OUTDATED;
197 else PARSE_ERROR(true, "Invalid state value '"<<aVal<<"'");
198 } else if (IsCommand("File ID :", myBuffer, aVal)) {
199 PARSE_ERROR(aNewFile.id != -1, "Duplicated file identifier '"<<myBuffer<<"'");
200 aNewFile.id = toInt(aVal, -1);
201 PARSE_ERROR(aNewFile.id < 0, "Invalid file identifier '"<<aVal<<"'");
202 } else { // unknown command will be processed in higher level method
207 PARSE_ERROR(aNewFile.id < 0, "File '"<<aNewFile.url<<"' ID is not defined");
208 theDocument.AddFile(aNewFile);
212 int SimanIO_Configuration::AddActivity(const SimanIO_Activity& theActivity, const int theId)
215 if (theId < 0) { // generate the maximum unique Id
216 if (myActivities.empty()) anId = 1; // the first
218 anId = myActivities.rbegin()->first + 1; // take the maximum Id plus one (in map integers are ordered)
221 myActivities[anId] = theActivity;
224 SimanIO_Activity& SimanIO_Configuration::GetOrCreateActivity(const int theId)
226 if (myActivities.find(theId) == myActivities.end()) {
227 myActivities[theId] = SimanIO_Activity();
229 return myActivities[theId];
232 void SimanIO_Configuration::ReadLine() {
233 if (myReuseLine) { // reuse current line
238 myF->getline(myBuffer, MAX_BUFFER_SIZE - 1);
239 } while(!myF->eof() && myBuffer[0] == 0); // continue if there is empty line
242 /////////////////////////////////// iterator methods ///////////////////////////
244 SimanIO_Configuration::ActivitiesIterator::ActivitiesIterator(SimanIO_Configuration& theConf)
246 myIter = theConf.myActivities.begin();
247 myEnd = theConf.myActivities.end();
250 void SimanIO_Configuration::ActivitiesIterator::Next()
255 bool SimanIO_Configuration::ActivitiesIterator::More()
257 return myIter != myEnd;
260 const int SimanIO_Configuration::ActivitiesIterator::ActivityId()
262 return myIter->first;
265 SimanIO_Activity& SimanIO_Configuration::ActivitiesIterator::Activity()
267 return myIter->second;