1 #include <SimanIO_Configuration.hxx>
5 // maximum length of the line in the parsed conf file
6 const int MAX_BUFFER_SIZE=10000;
10 SimanIO_Configuration::SimanIO_Configuration()
14 ///! Returns true is the given symbol is white space
15 static bool IsWhite(const char theSym) {
16 return theSym == ' ' || theSym == '\t';
19 ///! Returns true if theLine starts with theCommand, returns in theVal rest part of the line in this case
20 static bool IsCommand(const char* theCommand, char* theLine, char*& theVal) {
21 string aLine(theLine);
22 char* aComPtr = (char*)theCommand;
24 while(*aComPtr != 0 && *theVal != 0) {
25 if (IsWhite(*aComPtr)) { // skip white spaces in the command line
29 if (IsWhite(*theVal)) { // skip white spaces in the processed line
33 //cout<<"Compare symbols "<<tolower(*aComPtr)<<" and "<<tolower(*theVal)<<endl;
34 if (tolower(*aComPtr) != tolower(*theVal)) // symbols are not match (case is not significant)
39 if (*aComPtr == 0) { // command has been found
40 while(*theVal != 0 && IsWhite(*theVal)) { // skip white spaces in the processed line
48 ///! Returns true if theText1 fully equal to theText2
49 static bool IsValue(const char* theText1, const char* theText2) {
51 for(a = 0; theText1[a] != 0 && theText2[a] != 0; a++)
52 if (theText1[a] != theText2[a]) return false;
53 return theText1[a] == 0 && theText2[a] == 0;
56 ///! Converts string to the integer value, or returns the default vaule if failed
57 static int toInt(const char* theStr, int theDefault) {
60 aResult = atol(theStr);
67 // unification of the error handling in the Parse method
68 #define PARSE_ERROR(condition, message) if (condition) {cerr<<message<<endl; return false;}
70 bool SimanIO_Configuration::Parse(const char* theConfFileName)
72 ifstream f(theConfFileName);
74 PARSE_ERROR(!f.good(), "Can not read conf file "<<theConfFileName)
75 char aBuffer[MAX_BUFFER_SIZE];
76 myBuffer = aBuffer; // buffer for one line reading
77 myReuseLine = false; // to read current line from the file
78 char* aVal; // value in line, that is located after the identifier of the command
81 if (IsCommand("Study ID :", myBuffer, aVal)) {
82 // skip study ID: this info is known in Link
83 } else if (IsCommand("Scenario ID :", myBuffer, aVal)) {
84 // skip scenario ID: this info is known in Link
85 } else if (IsCommand("User ID :", myBuffer, aVal)) {
86 // skip user ID: this info is known in Link
87 } else if (IsCommand("Activity", myBuffer, aVal)) {
88 if (!ParseActivity(aVal)) return false;
90 PARSE_ERROR(true, "Invalid line of conf file: '"<<myBuffer<<"'");
96 bool SimanIO_Configuration::ParseActivity(char* aName)
98 SimanIO_Activity aNewActivity;
99 aNewActivity.SetName(aName);
100 int activityID = -1; // to be imported later
101 char* aVal; // value in line, that is located after the identifier of the command
104 if (IsCommand("Activity ID :", myBuffer, aVal)) {
105 PARSE_ERROR(activityID != -1, "Duplicated activity identifier '"<<myBuffer<<"'");
106 activityID = toInt(aVal, -1);
107 PARSE_ERROR(activityID < 1, "Invalid activity identifier '"<<aVal<<"'");
108 } else if (IsCommand("Module :", myBuffer, aVal) || IsCommand("SALOME Module :", myBuffer, aVal)) { // read only if module not yet imported before
110 PARSE_ERROR(aNewActivity.Module()[0] != 0, "Duplicated module name in '"<<myBuffer<<"'")
111 PARSE_ERROR(aVal[0] == 0, "Invalid module name in '"<<myBuffer<<"'")
112 aNewActivity.SetModule(aVal);
113 } else if (IsCommand("Document :", myBuffer, aVal)) {
114 if (!ParseDocument(aVal, aNewActivity)) return false;
115 } else { // unknown command will be processed in higher level method
120 PARSE_ERROR(activityID == -1, "Activity '"<<aNewActivity.Name()<<"' ID is not defined");
121 PARSE_ERROR(aNewActivity.Module()[0] == 0, "Module of the activity '"<<aNewActivity.Name()<<"' is not defined");
122 if (!IsValue("null", aNewActivity.Module())) // skip activities with module name "null"
123 AddActivity(aNewActivity, activityID);
127 bool SimanIO_Configuration::ParseDocument(char* aName, SimanIO_Activity& theActivity)
129 SimanIO_Document aNewDocument;
130 aNewDocument.SetName(aName);
131 int aDocID = -1; // to be imported later
132 char* aVal; // value in line, that is located after the identifier of the command
135 if (IsCommand("Document ID :", myBuffer, aVal)) {
136 PARSE_ERROR(aDocID != -1, "Duplicated document identifier '"<<myBuffer<<"'");
137 aDocID = toInt(aVal, -1);
138 PARSE_ERROR(aDocID < 1, "Invalid document identifier '"<<aVal<<"'");
139 } else if (IsCommand("Source file:", myBuffer, aVal) || IsCommand("Result file:", myBuffer, aVal)) {
140 if (!ParseFile(aNewDocument)) return false;
141 } else { // unknown command will be processed in higher level method
146 PARSE_ERROR(aDocID == -1, "Document '"<<aNewDocument.Name()<<"' ID is not defined");
147 theActivity.AddDocument(aDocID, aNewDocument);
151 bool SimanIO_Configuration::ParseFile(SimanIO_Document& theDocument)
153 SimanIO_File aNewFile;
155 int aDocID = -1; // to be imported later
156 char* aVal; // value in line, that is located after the identifier of the command
158 // current line contains one of the next two commands
159 if (IsCommand("Result file :", myBuffer, aVal)) {
160 aNewFile.result = true;
162 } else if (IsCommand("Source file :", myBuffer, aVal)) {
163 aNewFile.result = false;
166 PARSE_ERROR(aNewFile.url.empty(), "File '"<<myBuffer<<"' has invalid URL");
169 if (IsCommand("Automatic processing :", myBuffer, aVal)) {
171 if (IsCommand("file-download", aVal, aVal2)) aNewFile.proc = FILE_DOWNLOAD;
172 else if (IsCommand("file-import", aVal, aVal2)) aNewFile.proc = FILE_IMPORT;
173 else PARSE_ERROR(true, "Invalid automatic processing value '"<<aVal<<"'");
174 } else if (IsCommand("State :", myBuffer, aVal)) {
176 if (IsCommand("file-actual", aVal, aVal2)) aNewFile.state = FILE_ACTUAL;
177 else if (IsCommand("file-outdated", aVal, aVal2)) aNewFile.state = FILE_OUTDATED;
178 else PARSE_ERROR(true, "Invalid state value '"<<aVal<<"'");
179 } else if (IsCommand("File ID :", myBuffer, aVal)) {
180 PARSE_ERROR(aNewFile.id != -1, "Duplicated file identifier '"<<myBuffer<<"'");
181 aNewFile.id = toInt(aVal, -1);
182 PARSE_ERROR(aNewFile.id < 0, "Invalid file identifier '"<<aVal<<"'");
183 } else { // unknown command will be processed in higher level method
188 PARSE_ERROR(aNewFile.id < 0, "File '"<<aNewFile.url<<"' ID is not defined");
189 theDocument.AddFile(aNewFile);
193 int SimanIO_Configuration::AddActivity(const SimanIO_Activity& theActivity, const int theId)
196 if (theId < 0) { // generate the maximum unique Id
197 if (myActivities.empty()) anId = 1; // the first
199 anId = myActivities.rbegin()->first + 1; // take the maximum Id plus one (in map integers are ordered)
202 myActivities[anId] = theActivity;
205 SimanIO_Activity& SimanIO_Configuration::GetOrCreateActivity(const int theId)
207 if (myActivities.find(theId) == myActivities.end()) {
208 myActivities[theId] = SimanIO_Activity();
210 return myActivities[theId];
213 void SimanIO_Configuration::ReadLine() {
214 if (myReuseLine) { // reuse current line
219 myF->getline(myBuffer, MAX_BUFFER_SIZE - 1);
220 } while(!myF->eof() && myBuffer[0] == 0); // continue if there is empty line
223 /////////////////////////////////// iterator methods ///////////////////////////
225 SimanIO_Configuration::ActivitiesIterator::ActivitiesIterator(SimanIO_Configuration& theConf)
227 myIter = theConf.myActivities.begin();
228 myEnd = theConf.myActivities.end();
231 void SimanIO_Configuration::ActivitiesIterator::Next()
236 bool SimanIO_Configuration::ActivitiesIterator::More()
238 return myIter != myEnd;
241 const int SimanIO_Configuration::ActivitiesIterator::ActivityId()
243 return myIter->first;
246 SimanIO_Activity& SimanIO_Configuration::ActivitiesIterator::Activity()
248 return myIter->second;