MOOS 0.2375
|
00001 00002 // 00003 // MOOS - Mission Oriented Operating Suite 00004 // 00005 // A suit of Applications and Libraries for Mobile Robotics Research 00006 // Copyright (C) 2001-2005 Massachusetts Institute of Technology and 00007 // Oxford University. 00008 // 00009 // This software was written by Paul Newman at MIT 2001-2002 and Oxford 00010 // University 2003-2005. email: pnewman@robots.ox.ac.uk. 00011 // 00012 // This file is part of a MOOS Core Component. 00013 // 00014 // This program is free software; you can redistribute it and/or 00015 // modify it under the terms of the GNU General Public License as 00016 // published by the Free Software Foundation; either version 2 of the 00017 // License, or (at your option) any later version. 00018 // 00019 // This program is distributed in the hope that it will be useful, 00020 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00022 // General Public License for more details. 00023 // 00024 // You should have received a copy of the GNU General Public License 00025 // along with this program; if not, write to the Free Software 00026 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00027 // 02111-1307, USA. 00028 // 00030 // MOOSFileReader.cpp: implementation of the CMOOSFileReader class. 00031 // 00033 #ifdef _WIN32 00034 #pragma warning(disable : 4786) 00035 #endif 00036 00037 #ifdef _WIN32 00038 #include <winsock2.h> 00039 #include "windows.h" 00040 #include "winbase.h" 00041 #include "winnt.h" 00042 #else 00043 #include <pthread.h> 00044 #endif 00045 00046 00047 #include "MOOSGenLibGlobalHelper.h" 00048 #include "MOOSFileReader.h" 00049 #include "assert.h" 00050 #include "MOOSLock.h" 00051 00052 #define MAXLINESIZE 2000 00053 using namespace std; 00054 00056 // Construction/Destruction 00058 00059 CMOOSFileReader::CMOOSFileReader() 00060 { 00061 //by default we want to use quotes to allow verbatim 00062 //strings 00063 EnableVerbatimQuoting(true); 00064 m_pLock = new CMOOSLock(); 00065 } 00066 00067 CMOOSFileReader::~CMOOSFileReader() 00068 { 00069 if(IsOpen()) 00070 { 00071 GetFile()->close(); 00072 } 00073 00074 delete m_pLock; 00075 m_pLock = NULL; 00076 00077 ClearFileMap(); 00078 } 00079 00080 bool CMOOSFileReader::SetFile(const std::string & sFile) 00081 { 00082 m_sFileName = sFile; 00083 00084 //quick check that we can open a file 00085 if(GetFile()==NULL) 00086 return false; 00087 00088 THREAD2FILE_MAP::iterator p; 00089 00090 for(p=m_FileMap.begin();p!=m_FileMap.end();p++) 00091 { 00092 std::ifstream * pFile = p->second; 00093 00094 if(pFile!=NULL) 00095 { 00096 if(pFile->is_open()) 00097 { 00098 pFile->close(); 00099 } 00100 delete pFile; 00101 p->second = NULL; 00102 } 00103 } 00104 00105 ClearFileMap(); 00106 00107 BuildLocalShellVars(); 00108 00109 return true; 00110 00111 } 00112 00113 00114 std::string CMOOSFileReader::GetNextValidLine(bool bDoSubstitution) 00115 { 00116 00117 00118 std::string sLine; 00119 00120 if(eof() || !IsOpen()) 00121 { 00122 return sLine; 00123 } 00124 00125 char Tmp[MAXLINESIZE]; 00126 00127 //skip white space 00128 (*GetFile())>>std::ws; 00129 00130 00131 GetFile()->getline(Tmp,sizeof(Tmp)); 00132 sLine = std::string(Tmp); 00133 00134 while(GetFile()&& sLine.length()!=0 && IsComment(sLine)) 00135 { 00136 (*GetFile())>>std::ws; 00137 GetFile()->getline(Tmp,sizeof(Tmp)); 00138 sLine = std::string(Tmp); 00139 } 00140 00141 // jckerken 8-12-2004 (MIT) 00142 // remove comments made in line not at beginning 00143 size_t nC = sLine.find("//"); 00144 00145 //better check its not inside a quoted section...(PMN oct 2009) 00146 size_t nS1 = sLine.find("\""); 00147 if(nS1!=std::string::npos && m_bEnableVerbatimQuoting) 00148 { 00149 size_t nS2 = sLine.find("\"",nS1+1); 00150 if(nS2!=std::string::npos) 00151 { 00152 00153 std::string sF = sLine.substr(nS1+1,nS2-nS1-1); 00154 00155 sLine.replace(nS1,nS2-nS1+1,sF); 00156 00157 if(nS1<nC && nC<<nS2) 00158 { 00159 //remove quotes 00160 nC = sLine.find("//",nS2-1); 00161 } 00162 } 00163 } 00164 00165 if (nC >= 0 && nC <= sLine.size() && nC!=std::string::npos) 00166 { 00167 if (nC > 0) 00168 { 00169 sLine = sLine.substr(0, nC); 00170 } 00171 else 00172 sLine = ""; 00173 } // end jckerken 00174 00175 00176 if(bDoSubstitution) 00177 DoVariableExpansion(sLine); 00178 00179 00180 00181 return sLine; 00182 } 00183 00184 bool CMOOSFileReader::IsComment(std::string &sLine) 00185 { 00186 MOOSTrimWhiteSpace(sLine); 00187 if(sLine.find("//")==0) 00188 { 00189 return true; 00190 } 00191 00192 return false; 00193 } 00194 00195 bool CMOOSFileReader::GetTokenValPair(std::string sLine, std::string &sTok, std::string &sVal,bool bPreserveWhiteSpace) 00196 { 00197 if(sLine.find("=")!=std::string::npos) 00198 { 00199 MOOSRemoveChars(sLine,"\r"); 00200 00201 if(!bPreserveWhiteSpace) 00202 { 00203 MOOSRemoveChars(sLine," \t"); 00204 } 00205 00206 sTok = MOOSChomp(sLine,"="); 00207 sVal = sLine; 00208 return true; 00209 } 00210 else 00211 { 00212 return false; 00213 } 00214 } 00215 00216 bool CMOOSFileReader::GetValue(std::string sName,double & dfResult) 00217 { 00218 std::string sTmp; 00219 00220 if(GetValue(sName,sTmp)) 00221 { 00222 if(!MOOSIsNumeric(sTmp)) 00223 return false; 00224 00225 dfResult = atof(sTmp.c_str()); 00226 return true; 00227 } 00228 00229 return false; 00230 } 00231 00232 00233 bool CMOOSFileReader::GetValue(std::string sName,int & nResult) 00234 { 00235 std::string sTmp; 00236 00237 if(GetValue(sName,sTmp)) 00238 { 00239 if(!MOOSIsNumeric(sTmp)) 00240 return false; 00241 00242 nResult = atoi(sTmp.c_str()); 00243 return true; 00244 } 00245 00246 return false; 00247 } 00248 00249 00250 bool CMOOSFileReader::GetValue(std::string sName,std::string & sResult) 00251 { 00252 00253 00254 if(IsOpen()) 00255 { 00256 Reset(); 00257 00258 GetFile()->seekg(std::ios::beg); 00259 00260 std::string sLine,sVal,sTok; 00261 while(!GetFile()->eof()) 00262 { 00263 sLine = GetNextValidLine(); 00264 00265 if(GetTokenValPair(sLine, sTok, sVal)) 00266 { 00267 if(MOOSStrCmp(sTok,sName)) 00268 { 00269 sResult = sVal; 00270 return true; 00271 } 00272 } 00273 } 00274 } 00275 00276 return false; 00277 } 00278 00279 00280 00281 bool CMOOSFileReader::GetValue(std::string sName,float & fResult) 00282 { 00283 double dfT; 00284 if(GetValue(sName,dfT)) 00285 { 00286 fResult = float(dfT); 00287 return true; 00288 } 00289 return false; 00290 00291 } 00292 bool CMOOSFileReader::GetValue(std::string sName,bool & bResult) 00293 { 00294 std::string sT; 00295 00296 if(GetValue(sName, sT)) 00297 { 00298 bResult = (MOOSStrCmp(sT, "TRUE") || 00299 (MOOSIsNumeric(sT) && atof(sT.c_str()) > 0)); 00300 00301 return true; 00302 } 00303 return false; 00304 00305 } 00306 bool CMOOSFileReader::GetValue(std::string sName,unsigned int & nResult) 00307 { 00308 int nT; 00309 if(GetValue(sName,nT)) 00310 { 00311 if(nT<0) 00312 nResult = 0; 00313 else 00314 nResult = (unsigned int)nT; 00315 00316 return true; 00317 } 00318 return false; 00319 } 00320 00321 00322 bool CMOOSFileReader::Reset() 00323 { 00324 bool bResult = true; 00325 // m_pLock->Lock(); 00326 00327 00328 if(IsOpen()) 00329 { 00330 if(GetFile()->eof()) 00331 { 00332 GetFile()->clear(); 00333 GetFile()->seekg(ios::beg); 00334 00335 } 00336 else 00337 { 00338 std::ifstream * pMyFile = GetFile(); 00339 pMyFile->seekg(ios::beg); 00340 } 00341 bResult = true; 00342 } 00343 else 00344 { 00345 bResult = false; 00346 } 00347 00348 // m_pLock->UnLock(); 00349 00350 return bResult; 00351 00352 } 00353 00354 bool CMOOSFileReader::eof() 00355 { 00356 return IsOpen() && GetFile()->eof(); 00357 } 00358 00359 bool CMOOSFileReader::GoTo(std::string sLine) 00360 { 00361 00362 if(IsOpen()) 00363 { 00364 MOOSRemoveChars(sLine," \t\r"); 00365 00366 std::string sTmp; 00367 while(!GetFile()->eof()) 00368 { 00369 sTmp = GetNextValidLine(); 00370 MOOSRemoveChars(sTmp," \t\r"); 00371 00372 if(MOOSStrCmp(sTmp,sLine)) 00373 { 00374 return true; 00375 } 00376 00377 } 00378 } 00379 else 00380 { 00381 //MOOSTrace("CMOOSFileReader::GoTo() file not open!\n"); 00382 } 00383 00384 return false; 00385 } 00386 00387 std::ifstream * CMOOSFileReader::GetFile() 00388 { 00389 m_pLock->Lock(); 00390 #ifdef _WIN32 00391 DWORD Me = GetCurrentThreadId(); 00392 #else 00393 pthread_t Me = pthread_self(); 00394 #endif 00395 00396 THREAD2FILE_MAP::iterator p = m_FileMap.find(Me); 00397 00398 if(p==m_FileMap.end()) 00399 { 00400 //MOOSTrace("\n::CMOOSFileReader Making mission file for thread[%d]\n",Me); 00401 std::ifstream * pNewStream = new ifstream; 00402 m_FileMap[Me] = pNewStream; 00403 p = m_FileMap.find(Me); 00404 } 00405 00406 std::ifstream * pAnswer = p->second; 00407 00408 if(pAnswer!=NULL) 00409 { 00410 //now open the file as required... 00411 if(!pAnswer->is_open() && !m_sFileName.empty()) 00412 { 00413 pAnswer->open(m_sFileName.c_str()); 00414 } 00415 00416 if(!pAnswer->is_open()) 00417 { 00418 delete pAnswer; 00419 pAnswer = NULL; 00420 m_FileMap.erase(Me); 00421 } 00422 } 00423 00424 m_pLock->UnLock(); 00425 00426 return pAnswer; 00427 00428 00429 } 00430 00431 bool CMOOSFileReader::IsOpen() 00432 { 00433 if(GetFile()==NULL) 00434 return false; 00435 00436 return GetFile()->is_open(); 00437 } 00438 00439 00440 00441 bool CMOOSFileReader::BuildLocalShellVars() 00442 { 00443 00444 if(IsOpen()) 00445 { 00446 Reset(); 00447 00448 GetFile()->seekg(std::ios::beg); 00449 00450 std::string sLine,sVal,sTok; 00451 while(!GetFile()->eof()) 00452 { 00453 sLine = GetNextValidLine(false); 00454 00455 MOOSChomp(sLine,"define:"); 00456 00457 if(!sLine.empty()) 00458 { 00459 std::string sVarName,sVarVal; 00460 if(GetTokenValPair(sLine,sVarName,sVarVal)) 00461 { 00462 m_LocalShellVariables[sVarName] = sVarVal; 00463 } 00464 } 00465 } 00466 00467 Reset(); 00468 00469 00470 return true; 00471 } 00472 00473 return false; 00474 00475 } 00476 00477 00478 bool CMOOSFileReader::DoVariableExpansion(std::string & sVal) 00479 { 00480 00481 std::string sBuilt,sExpand; 00482 do 00483 { 00484 sExpand.clear(); 00485 00486 sBuilt+= MOOSChomp(sVal,"${"); 00487 00488 sExpand = MOOSChomp(sVal,"}"); 00489 00490 if(!sExpand.empty()) 00491 { 00492 std::map<std::string,std::string>::iterator p; 00493 p = m_LocalShellVariables.find(sExpand); 00494 if(p == m_LocalShellVariables.end()) 00495 { 00496 //maybe its a system shell var? 00497 char * pShellVal = getenv(sExpand.c_str()); 00498 if(pShellVal!=NULL) 00499 { 00500 //MOOSTrace("using system variable expansion ${%s} -> %s\n",sExpand.c_str(),pShellVal); 00501 00502 //indeed it is! 00503 sExpand = std::string(pShellVal); 00504 00505 } 00506 else 00507 { 00508 MOOSTrace("Error in mission file\n\t no shell or mission file expansion fouind for ${%s}\n",sExpand.c_str()); 00509 } 00510 } 00511 else 00512 { 00513 //OK we have been told about this in file scope 00514 //MOOSTrace("using local variable expansion ${%s} -> %s\n",sExpand.c_str(),p->second.c_str()); 00515 00516 sExpand=p->second; 00517 } 00518 00519 sBuilt+=sExpand; 00520 //MOOSTrace("and sBuilt = %s\n",sBuilt.c_str()); 00521 } 00522 00523 }while(!sExpand.empty()); 00524 00525 00526 sVal = sBuilt; 00527 00528 00529 return true; 00530 00531 00532 } 00533 00534 bool CMOOSFileReader::MakeOverloadedCopy(const std::string & sCopyName,std::map<std::string, std::string> & OverLoads) 00535 { 00536 if(IsOpen()) 00537 { 00538 //open a file to copy to 00539 std::ofstream of(sCopyName.c_str()); 00540 00541 if(!of.is_open()) 00542 return false; 00543 00544 00545 Reset(); 00546 00547 GetFile()->seekg(std::ios::beg); 00548 00549 std::string sLine,sVal,sTok,sTmp; 00550 while(!GetFile()->eof()) 00551 { 00552 00553 00554 char Tmp[MAXLINESIZE]; 00555 00556 GetFile()->getline(Tmp,sizeof(Tmp)); 00557 sLine = std::string(Tmp); 00558 sTmp = sLine; 00559 00560 MOOSTrimWhiteSpace(sTmp); 00561 if(!sTmp.find("//")==0 && !sLine.empty()) 00562 { 00563 std::string sVarName,sVarVal; 00564 if(GetTokenValPair(sLine,sVarName,sVarVal)) 00565 { 00566 if(OverLoads.find(sVarName)!=OverLoads.end()) 00567 { 00568 of<<"//---- Next Line was commented and replaced with a command line overload ---- //"<<std::endl; 00569 of<<"//"+sLine+ " (default)"<<std::endl; 00570 of<<sVarName<<" = "<<OverLoads[sVarName]<<std::endl; 00571 continue; 00572 } 00573 } 00574 } 00575 00576 //nothing much to do just a simple copy 00577 of<<sLine<<std::endl; 00578 00579 00580 } 00581 00582 Reset(); 00583 00584 of.close(); 00585 return true; 00586 } 00587 00588 return false; 00589 00590 00591 } 00592