MOOS 0.2375
/home/toby/moos-ivp/MOOS-2375-Oct0611/Core/MOOSGenLib/MOOSFileReader.cpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines