Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGPathHandler.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 
00042 #include "OSGConfig.h"
00043 
00044 #include "OSGPathHandler.h"
00045 
00046 #include "OSGFileSystem.h"
00047 
00048 #ifndef WIN32
00049 #include <pwd.h>
00050 #endif
00051 
00052 OSG_USING_NAMESPACE
00053 
00054 const Char8 PathHandler::_dirSepWin32  = '\\';
00055 const Char8 PathHandler::_pathSepWin32 = ';';
00056 
00057 const Char8 PathHandler::_dirSepUnix   = '/';
00058 const Char8 PathHandler::_pathSepUnix  = ':';
00059 
00060 #ifdef WIN32
00061 const Char8 PathHandler::_dirSep       = _dirSepWin32;
00062 const Char8 PathHandler::_pathSep      = _pathSepWin32;
00063 const Char8 PathHandler::_dirSepOther  = _dirSepUnix;
00064 const Char8 PathHandler::_pathSepOther = _pathSepUnix;
00065 #else
00066 const Char8 PathHandler::_dirSep       = _dirSepUnix;
00067 const Char8 PathHandler::_pathSep      = _pathSepUnix;
00068 const Char8 PathHandler::_dirSepOther  = _dirSepWin32;
00069 const Char8 PathHandler::_pathSepOther = _pathSepWin32;
00070 #endif
00071 
00072 /*--------------------------- Constructors --------------------------------*/
00073 
00074 PathHandler::PathHandler(void) :
00075     _pathList    (),
00076     _baseFilePath()
00077 {
00078 }
00079 
00080 PathHandler::PathHandler(const Char8 *initialPathList)
00081 {
00082     push_backUnixPath(initialPathList);
00083 }
00084 
00085 /*---------------------------- Destructor ---------------------------------*/
00086 
00087 PathHandler::~PathHandler(void)
00088 {
00089 }
00090 
00091 /*------------------------------- Get -------------------------------------*/
00092 
00093 std::string PathHandler::findFile(const Char8 *fileName)
00094 {
00095     std::string returnValue;
00096     bool        bFound      = false;
00097 
00098     PathList     tmpList;
00099 
00100     PathListIter iter    = _pathList.begin();
00101     PathListIter listEnd = _pathList.end();
00102 
00103     PathType     pType   = analysePath(fileName);
00104 
00105     parsePathList(fileName, tmpList);
00106 
00107     if(tmpList.size() != 0)
00108     {
00109         if((pType & TypeMask) == AbsPath)
00110         {
00111             SINFO << "Check abs : " << tmpList.front() << std::endl;
00112 
00113             if(File::tstAttr(tmpList.front().c_str(),
00114                              AccessFlags::IsReadable))
00115             {
00116                 returnValue.assign(fileName);
00117             }
00118         }
00119         else
00120         {
00121             if(_baseFilePath.empty() == false)
00122             {
00123                 returnValue.assign(_baseFilePath);
00124 
00125                 returnValue.append(tmpList.front());
00126 
00127                 SINFO << "Check base : " << returnValue << std::endl;
00128 
00129                 if(File::tstAttr(returnValue.c_str(),
00130                                  AccessFlags::IsReadable) == false)
00131                 {
00132                     returnValue.erase();
00133                 }
00134                 else
00135                 {
00136                     bFound = true;
00137                 }
00138             }
00139 
00140             if(bFound == false)
00141             {
00142                 while(iter != listEnd)
00143                 {
00144                     returnValue.assign(*iter);
00145                     returnValue.append(tmpList.front());
00146 
00147                     SINFO << "Check from pl : " << returnValue << std::endl;
00148 
00149                     if(File::tstAttr(returnValue.c_str(),
00150                                      AccessFlags::IsReadable) == true)
00151                     {
00152                         break;
00153                     }
00154 
00155                     ++iter;
00156                 }
00157 
00158                 if(iter == listEnd)
00159                 {
00160                     returnValue.erase();
00161                 }
00162             }
00163         }
00164     }
00165 
00166     return returnValue;
00167 }
00168 
00169 const std::string &PathHandler::getBaseFile (void) const
00170 {
00171   return _baseFilePath;
00172 }
00173 
00174 /*------------------------------- Set -------------------------------------*/
00175 
00176 void PathHandler::push_backPath(const Char8 *pathList)
00177 {
00178     PathList tmpList;
00179 
00180     parsePathList(pathList, tmpList);
00181 
00182     push_backPathList(tmpList);
00183 }
00184 
00185 void PathHandler::push_backCurrentDir(void)
00186 {
00187     Char8       *pCurrentDir = Directory::getCurrent();
00188     std::string  tmpString   = pCurrentDir;
00189 
00190     _pathList.push_back(tmpString);
00191 
00192     validateList(_pathList);
00193 
00194     delete [] pCurrentDir;
00195 }
00196 
00197 void PathHandler::push_backUnixPath(const Char8 *pathList)
00198 {
00199     PathList tmpList;
00200 
00201     parseUnixPathList(pathList, tmpList);
00202 
00203     push_backPathList(tmpList);
00204 }
00205 
00206 void PathHandler::push_backWin32Path(const Char8 *pathList)
00207 {
00208     PathList tmpList;
00209 
00210     parseWin32PathList(pathList, tmpList);
00211 
00212     push_backPathList(tmpList);
00213 }
00214 
00215 
00216 void PathHandler::push_frontPath(const Char8 *pathList)
00217 {
00218     PathList tmpList;
00219 
00220     parsePathList(pathList, tmpList);
00221 
00222     push_frontPathList(tmpList);
00223 }
00224 
00225 void PathHandler::push_frontCurrentDir(void)
00226 {
00227     Char8       *pCurrentDir = Directory::getCurrent();
00228     std::string  tmpString   = pCurrentDir;
00229 
00230     _pathList.push_front(tmpString);
00231 
00232     validateList(_pathList);
00233 
00234     delete [] pCurrentDir;
00235 }
00236 
00237 void PathHandler::push_frontUnixPath(const Char8 *pathList)
00238 {
00239     PathList tmpList;
00240 
00241     parseUnixPathList(pathList, tmpList);
00242 
00243     push_frontPathList(tmpList);
00244 }
00245 
00246 void PathHandler::push_frontWin32Path(const Char8 *pathList)
00247 {
00248     PathList tmpList;
00249 
00250     parseWin32PathList(pathList, tmpList);
00251 
00252     push_frontPathList(tmpList);
00253 }
00254 
00255 void PathHandler::subPath(const Char8 *pathList)
00256 {
00257     PathList tmpList;
00258 
00259     parsePathList(pathList, tmpList);
00260     validateList(tmpList);
00261     subPathList(tmpList);
00262 }
00263 
00264 void PathHandler::subUnixPath(const Char8 *pathList)
00265 {
00266     PathList tmpList;
00267 
00268     parseUnixPathList(pathList, tmpList);
00269     validateList(tmpList);
00270     subPathList(tmpList);
00271 }
00272 
00273 void PathHandler::subWin32Path(const Char8 *pathList)
00274 {
00275     PathList tmpList;
00276 
00277     parseWin32PathList(pathList, tmpList);
00278     validateList(tmpList);
00279     subPathList(tmpList);
00280 }
00281 
00282 void PathHandler::clearPathList(void)
00283 {
00284     _pathList.clear();
00285 }
00286 
00287 
00288 void PathHandler::setBaseFile(const Char8 *fileName)
00289 {
00290     if(fileName != NULL)
00291     {
00292         _baseFilePath = extractPath(fileName);
00293     }
00294 }
00295 
00296 void PathHandler::clearBaseFile(void)
00297 {
00298     _baseFilePath.erase();
00299 }
00300 
00301 /*------------------------------- Dump ------------------------------------*/
00302 
00303 void PathHandler::dump(void)
00304 {
00305     PathListIter iter = _pathList.begin();
00306 
00307     if(_baseFilePath.size() != 0)
00308     {
00309         SLOG << "Base file path : " << _baseFilePath << std::endl;
00310     }
00311     else
00312     {
00313         SLOG << "Base file path : empty" << std::endl;
00314     }
00315 
00316     for( ; iter != _pathList.end(); ++iter )
00317     {
00318         SLOG << "\"" << *iter << "\"" << std::endl;
00319     }
00320 }
00321 
00322 /*------------------------------ Helper -----------------------------------*/
00323 
00324 void PathHandler::validateList(PathList &pathList)
00325 {
00326     PathListIter iter    = pathList.begin();
00327     PathListIter listEnd = pathList.end();
00328 
00329     while(iter != listEnd)
00330     {
00331         if(iter->empty() == true)
00332         {
00333             (*iter) += '.';
00334             (*iter) += _dirSep;
00335         }
00336         else
00337         {
00338             if((*iter)[iter->length() - 1] != _dirSep)
00339             {
00340                 (*iter) += _dirSep;
00341             }
00342         }
00343 
00344         ++iter;
00345     }
00346 }
00347 
00348 std::string PathHandler::extractPath(const Char8 *szFilename)
00349 {
00350     std::string            returnValue(szFilename);
00351 
00352     std::string::size_type pos = returnValue.find_last_of("\\/");
00353 
00354     if(pos != std::string::npos)
00355     {
00356         if(pos != returnValue.length() - 1)
00357         {
00358             returnValue.erase(pos + 1);
00359         }
00360     }
00361     else
00362     {
00363         returnValue.assign(".");
00364     }
00365 
00366     PathType pType = analysePathList(returnValue.c_str());
00367 
00368     if((pType & PlatformMask) == Win32Path)
00369     {
00370 #ifndef WIN32
00371         convertPath(returnValue);
00372 #endif
00373     }
00374     else
00375     {
00376 #ifdef WIN32
00377         convertPath(returnValue);
00378 #endif
00379     }
00380 
00381     if(returnValue[returnValue.length() - 1] != _dirSep)
00382     {
00383         returnValue += _dirSep;
00384     }
00385 
00386     return returnValue;
00387 }
00388 
00389 PathHandler::PathType PathHandler::analysePathList(const Char8 *pathList)
00390 {
00391           PathType  returnValue = UnixPath;
00392     const Char8    *pCurr       = pathList;
00393 
00394     if(pathList == NULL)
00395         return returnValue;
00396 
00397     while(*pCurr != '\0')
00398     {
00399         if(*pCurr == '\\')
00400         {
00401             returnValue = Win32Path;
00402             break;
00403         }
00404         else if(*pCurr == ';')
00405         {
00406             returnValue = Win32Path;
00407             break;
00408         }
00409         else if(*pCurr == '%')
00410         {
00411             returnValue = Win32Path;
00412             break;
00413         }
00414         else if(*pCurr == '/')
00415         {
00416             returnValue = UnixPath;
00417             break;
00418         }
00419         else if(*pCurr == '$')
00420         {
00421             returnValue = UnixPath;
00422             break;
00423         }
00424         else if(*pCurr == ':')
00425         {
00426             if(*(pCurr + 1) == '\\')
00427             {
00428                 returnValue = Win32Path;
00429                 break;
00430             }
00431         }
00432 
00433         pCurr++;
00434     }
00435 
00436 #ifdef WIN32
00437     // HACK but d:/data/tie.wrl is also a valid windows path.
00438     if(returnValue == UnixPath)
00439     {
00440         // ok first look for a ";" in the path list.
00441         UInt32 uiSize = 0;
00442         pCurr = pathList;
00443         while(*pCurr != '\0')
00444         {
00445             if(*pCurr == ';')
00446             {
00447                 returnValue = Win32Path;
00448                 break;
00449             }
00450             pCurr++;
00451             uiSize++;
00452         }
00453 
00454         // ok we found no ";" in the list look for a absolute windows path.
00455         if(returnValue == UnixPath)
00456         {
00457             if(uiSize >= 3)
00458             {
00459                 if(pathList[1] == ':' &&
00460                    (pathList[2] == '/' || pathList[2] == '\\'))
00461                 {
00462                     returnValue = Win32Path;
00463                 }
00464             }
00465         }
00466     }
00467 #endif
00468 
00469     return returnValue;
00470 }
00471 
00472 PathHandler::PathType PathHandler::analysePath(const Char8 *path)
00473 {
00474           PathType  returnValue = UnixPath;
00475           UInt32    uiSize      = 0;
00476     const Char8    *pCurr       = path;
00477 
00478     if(path == NULL)
00479         return returnValue;
00480 
00481     while(*pCurr != '\0')
00482     {
00483         if(*pCurr == '\\')
00484         {
00485             returnValue = Win32Path;
00486             break;
00487         }
00488         else if(*pCurr == ';')
00489         {
00490             returnValue = Win32Path;
00491             break;
00492         }
00493         else if(*pCurr == '%')
00494         {
00495             returnValue = Win32Path;
00496             break;
00497         }
00498         else if(*pCurr == '/')
00499         {
00500             returnValue = UnixPath;
00501             break;
00502         }
00503         else if(*pCurr == '$')
00504         {
00505             returnValue = UnixPath;
00506             break;
00507         }
00508         else if(*pCurr == ':')
00509         {
00510             if(*(pCurr + 1) == '\\')
00511             {
00512                 returnValue = Win32Path;
00513                 uiSize++;
00514                 break;
00515             }
00516         }
00517 
00518         pCurr++;
00519         uiSize++;
00520     }
00521 
00522 #ifdef WIN32
00523     if(returnValue == UnixPath)
00524     {
00525         // d:/data/tie.wrl is also a windows path!
00526         if(uiSize >= 2)
00527         {
00528             if(path[1] == ':')
00529                 returnValue = Win32Path;
00530         }
00531     }
00532 #endif
00533 
00534     if(returnValue == Win32Path)
00535     {
00536         if(uiSize >= 2)
00537         {
00538             if(path[1] == ':')
00539                 returnValue = (PathType) (returnValue | AbsPath);
00540         }
00541         else
00542         {
00543             // windows network path.
00544             if(path[0] == '\\' && path[1] == '\\')
00545                 returnValue = (PathType) (returnValue | AbsPath);
00546         }
00547     }
00548     else
00549     {
00550         if(path[0] == '/')
00551             returnValue = (PathType) (returnValue | AbsPath);
00552     }
00553 
00554     return returnValue;
00555 }
00556 
00557 void PathHandler::expandWin32Path(std::string &path)
00558 {
00559     std::string            envVar;
00560 
00561     std::string::size_type currPos  = 0;
00562     std::string::size_type startPos = 0;
00563 
00564     while(currPos < path.size())
00565     {
00566         if(path[currPos] == '%')
00567         {
00568             envVar.erase();
00569             startPos = currPos++;
00570 
00571             while(path[currPos] != '%' &&
00572                   currPos < path.size())
00573             {
00574                 envVar += path[currPos++];
00575             }
00576 
00577             if(currPos < path.size())
00578             {
00579                 currPos++;
00580             }
00581 
00582             Char8 *szEnvVal = getenv(envVar.c_str());
00583 
00584             if(szEnvVal == NULL)
00585             {
00586                 FWARNING(("Could not find env var %s\n", envVar.c_str()));
00587             }
00588             else
00589             {
00590                 path.replace(startPos, currPos - startPos, szEnvVal);
00591             }
00592         }
00593         else
00594         {
00595             currPos++;
00596         }
00597     }
00598 }
00599 
00600 void PathHandler::expandUnixPath(std::string &path)
00601 {
00602     std::string  envVar;
00603     std::string  userName;
00604     std::string  userHome;
00605 #ifndef WIN32
00606     bool         stop;
00607     passwd      *userInfo;
00608 #endif
00609 
00610     std::string::size_type currPos  = 0;
00611     std::string::size_type startPos = 0;
00612 
00613     while(currPos < path.size())
00614     {
00615         if(path[currPos] == '$')
00616         {
00617             envVar.erase();
00618             startPos = currPos++;
00619 
00620             while(path[currPos] != ':' &&
00621                   path[currPos] != '/' &&
00622                   path[currPos] != '$' &&
00623                   currPos < path.size())
00624             {
00625                 envVar += path[currPos++];
00626             }
00627 
00628             Char8 *szEnvVal = getenv(envVar.c_str());
00629 
00630             if(szEnvVal == NULL)
00631             {
00632                 FWARNING(("Could not find env var %s\n", envVar.c_str()));
00633             }
00634             else
00635             {
00636                 path.replace(startPos, currPos - startPos, szEnvVal);
00637             }
00638         }
00639 #ifndef WIN32
00640         else if(path[currPos] == '~')
00641         {
00642             userName.erase();
00643             startPos = currPos++;
00644 
00645             while(path[currPos] != ':' &&
00646                   path[currPos] != '/' &&
00647                   path[currPos] != '$' &&
00648                   currPos < path.size())
00649             {
00650                 userName += path[currPos++];
00651             }
00652             
00653             if(!userName.empty())
00654             {
00655                 setpwent();     //prepare access to user db
00656                 stop = false;
00657 
00658                 while(stop == false)
00659                 {
00660                     if((userInfo=getpwent()) != NULL )
00661                     {
00662                         if(strcmp(userName.c_str(), userInfo->pw_name) == 0)
00663                         {
00664                             stop = true;
00665                             userHome = userInfo->pw_dir;
00666                         }
00667                     }
00668                     else
00669                     {
00670                         stop = true;
00671                     }
00672                 }
00673                 endpwent();
00674             }
00675             else
00676             {
00677                 if((userInfo=getpwuid(getuid())) != NULL)
00678                 {
00679                     userHome = userInfo->pw_dir;
00680                 }
00681             }
00682 
00683             if(userHome.empty() == false)
00684             {
00685                 path.replace(startPos, currPos - startPos, userHome);
00686             }
00687             else
00688             {
00689                 FWARNING(("Could not find user home %s\n", userHome.c_str()));
00690             }
00691         }
00692 #endif
00693         else
00694         {
00695             currPos++;
00696         }
00697     }
00698 }
00699 
00700 void PathHandler::push_backPathList(PathList &pathList)
00701 {
00702     _pathList.splice(_pathList.end(), pathList);
00703 
00704     validateList(_pathList);
00705 }
00706 
00707 void PathHandler::push_frontPathList(PathList &pathList)
00708 {
00709     _pathList.splice(_pathList.begin(), pathList);
00710 
00711     validateList(_pathList);
00712 }
00713 
00714 void PathHandler::subPathList(const PathList &pathList)
00715 {
00716     for(PathList::const_iterator i = pathList.begin();i != pathList.end();++i)
00717     {
00718         for(PathList::iterator j = _pathList.begin();j != _pathList.end();++j)
00719         {
00720             if(*j == *i)
00721             {
00722                 _pathList.erase(j);
00723                 break;
00724             }
00725         }
00726     }
00727 }
00728 
00729 void PathHandler::convertPath(std::string &path)
00730 {
00731     std::string::iterator stringIt  = path.begin();
00732     std::string::iterator stringEnd = path.end  ();
00733 
00734     while(stringIt != stringEnd)
00735     {
00736         if(*stringIt == _dirSepOther)
00737         {
00738             *stringIt = _dirSep;
00739         }
00740 
00741         stringIt++;
00742     };
00743 }
00744 
00745 void PathHandler::convertWin32PathList(PathList &result)
00746 {
00747     PathListIter iter    = result.begin();
00748     PathListIter endList = result.end();
00749 
00750     while(iter != endList)
00751     {
00752         expandWin32Path(*iter);
00753 
00754 #ifndef WIN32
00755         convertPath    (*iter);
00756 #endif
00757 
00758         iter++;
00759     };
00760 }
00761 
00762 void PathHandler::convertUnixPathList(PathList &result)
00763 {
00764     PathListIter iter    = result.begin();
00765     PathListIter endList = result.end();
00766 
00767     while(iter != endList)
00768     {
00769         expandUnixPath(*iter);
00770 
00771 #ifdef WIN32
00772         convertPath   (*iter);
00773 #endif
00774 
00775         iter++;
00776     };
00777 }
00778 
00779 void PathHandler::splitPathList(const Char8    *pathList,
00780                                 const Char8     pathSep,
00781                                       PathList &result)
00782 {
00783     std::string::size_type currPos    = 0;
00784     std::string::size_type startPos   = 0;
00785     std::string            workString(pathList);
00786 
00787     currPos = workString.find(pathSep);
00788 
00789     if(currPos == std::string::npos)
00790     {
00791         result.push_back(workString);
00792     }
00793     else
00794     {
00795         while(currPos != std::string::npos)
00796         {
00797             result.push_back(workString.substr(startPos,
00798                                                currPos - startPos));
00799 
00800             startPos = currPos + 1;
00801 
00802             currPos = workString.find(pathSep, startPos);
00803         }
00804 
00805         if(startPos != 0)
00806         {
00807             result.push_back(workString.substr(startPos));
00808         }
00809     }
00810 }
00811 
00812 void PathHandler::parsePathList(const Char8 *pathList, PathList &result)
00813 {
00814     PathType pType = analysePathList(pathList);
00815 
00816     if((pType & PlatformMask) == Win32Path)
00817     {
00818         parseWin32PathList(pathList, result);
00819     }
00820     else
00821     {
00822         parseUnixPathList (pathList, result);
00823     }
00824 }
00825 
00826 void PathHandler::parseUnixPathList(const Char8 *pathList, PathList &result)
00827 {
00828     if(pathList == NULL)
00829         return;
00830 
00831     splitPathList      (pathList, _pathSepUnix, result);
00832 
00833     convertUnixPathList(result);
00834 }
00835 
00836 void PathHandler::parseWin32PathList(const Char8 *pathList, PathList &result)
00837 {
00838     if(pathList == NULL)
00839         return;
00840 
00841     splitPathList     (pathList, _pathSepWin32, result);
00842 
00843     convertWin32PathList(result);
00844 }
00845 
00846 
00847 /*-------------------------------------------------------------------------*/
00848 /*                              cvs id's                                   */
00849 
00850 #ifdef __sgi
00851 #pragma set woff 1174
00852 #endif
00853 
00854 #ifdef OSG_LINUX_ICC
00855 #pragma warning( disable : 177 )
00856 #endif
00857 
00858 namespace
00859 {
00860     static Char8 cvsid_cpp[] = "@(#)$Id: $";
00861     static Char8 cvsid_hpp[] = OSGPATHHANDLER_HEADER_CVSID;
00862 }
00863 
00864 
00865 
00866 
00867 
00868 

Generated on Thu Aug 25 04:08:17 2005 for OpenSG by  doxygen 1.4.3