# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

new_path.cpp

Go to the documentation of this file.
00001 #if 0
00002 
00008 /* Copyright, 2000, 2001 Nevrax Ltd.
00009  *
00010  * This file is part of NEVRAX NEL.
00011  * NEVRAX NEL is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2, or (at your option)
00014  * any later version.
00015 
00016  * NEVRAX NEL is distributed in the hope that it will be useful, but
00017  * WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00019  * General Public License for more details.
00020 
00021  * You should have received a copy of the GNU General Public License
00022  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00023  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00024  * MA 02111-1307, USA.
00025  */
00026 
00027 #include <fstream>
00028 
00029 #include "nel/misc/debug.h"
00030 
00031 #include "nel/misc/new_path.h"
00032 
00033 #ifdef NL_OS_WINDOWS
00034 #       include <windows.h>
00035 #else
00036 #   include <sys/types.h>
00037 #   include <sys/stat.h>
00038 #       include <dirent.h>
00039 #   include <unistd.h>
00040 #endif // NL_OS_WINDOWS
00041 
00042 using namespace std;
00043 
00044 namespace NLMISC {
00045 
00046 //
00047 // Macros
00048 //
00049 
00050 // Use this define if you want to display info about the CPath.
00051 #define NL_DEBUG_PATH
00052 
00053 #ifdef  NL_DEBUG_PATH
00054 #define NL_DISPLAY_PATH nlinfo
00055 #else 
00056 #define NL_DISPLAY_PATH if(false)
00057 #endif
00058 
00059 
00060 //
00061 // Variables
00062 //
00063 
00064 CNewPath *CNewPath::_Instance = NULL;
00065 
00066 
00067 //
00068 // Functions
00069 //
00070 
00071 CNewPath *CNewPath::getInstance ()
00072 {
00073         if (_Instance == NULL)
00074         {
00075                 _Instance = new CNewPath;
00076         }
00077         return _Instance;
00078 }
00079 
00080 void CNewPath::clearMap ()
00081 {
00082         CNewPath *inst = CNewPath::getInstance();
00083         inst->_Files.clear ();
00084         NL_DISPLAY_PATH("CNewPath::clearMap(): map directory cleared");
00085 }
00086 
00087 sint CNewPath::findExtension (const string &ext1, const string &ext2)
00088 {
00089         CNewPath *inst = CNewPath::getInstance();
00090         for (uint i = 0; i < inst->_Extensions.size (); i++)
00091         {
00092                 if (inst->_Extensions[i].first == ext1 && inst->_Extensions[i].second == ext2)
00093                 {
00094                         return i;
00095                 }
00096         }
00097         return -1;
00098 }
00099 
00100 void CNewPath::remapExtension (const string &ext1, const string &ext2, bool substitute)
00101 {
00102         CNewPath *inst = CNewPath::getInstance();
00103 
00104         if (ext1.empty() || ext2.empty())
00105         {
00106                 nlwarning ("CNewPath::remapExtension(%s, %s, %d): can't remap empty extension", ext1.c_str(), ext2.c_str(), substitute);
00107         }
00108 
00109         if (!substitute)
00110         {
00111                 // remove the mapping from the mapping list
00112                 sint n = inst->findExtension (ext1, ext2);
00113                 nlassert (n != -1);
00114                 inst->_Extensions.erase (inst->_Extensions.begin() + n);
00115 
00116                 // remove mapping in the map
00117                 map<string, CNewFileEntry>::iterator it = inst->_Files.begin();
00118                 map<string, CNewFileEntry>::iterator nit = it;
00119                 while (it != inst->_Files.end ())
00120                 {
00121                         nit++;
00122                         if ((*it).second.Remapped && (*it).second.Extension == ext2)
00123                         {
00124                                 inst->_Files.erase (it);
00125                         }
00126                         it = nit;
00127                 }
00128                 NL_DISPLAY_PATH("CNewPath::remapExtension(%s, %s, %d): extension removed", ext1.c_str(), ext2.c_str(), substitute);
00129         }
00130         else
00131         {
00132                 sint n = inst->findExtension (ext1, ext2);
00133                 if (n != -1)
00134                 {
00135                         nlwarning ("CNewPath::remapExtension(%s, %s, %d): remapping already set", ext1.c_str(), ext2.c_str(), substitute);
00136                         return;
00137                 }
00138 
00139                 // adding mapping into the mapping list
00140                 inst->_Extensions.push_back (make_pair (ext1, ext2));
00141 
00142                 // adding mapping into the map
00143                 vector<string> newFiles;
00144                 map<string, CNewFileEntry>::iterator it = inst->_Files.begin();
00145                 while (it != inst->_Files.end ())
00146                 {
00147                         if (!(*it).second.Remapped && (*it).second.Extension == ext1)
00148                         {
00149                                 // find if already exist
00150                                 sint pos = (*it).first.find_last_of (".");
00151                                 if (pos != string::npos)
00152                                 {
00153                                         string file = (*it).first.substr (0, pos + 1);
00154                                         file += ext2;
00155 
00156                                         map<string, CNewFileEntry>::iterator nit = inst->_Files.find (file);
00157                                         if (nit != inst->_Files.end())
00158                                         {
00159                                                 nlwarning ("CNewPath::remapExtension(%s, %s): The file '%s' is in conflict with the remapping file '%s', skip it", ext1.c_str(), ext2.c_str(), file.c_str(), (*it).first.c_str());
00160                                         }
00161                                         else
00162                                         {
00163 // TODO perhaps a problem because I insert in the current map that i parcours
00164                                                 insertFileInMap (file, (*it).second.Path, true, ext2);
00165                                         }
00166                                 }
00167                         }
00168                         it++;
00169                 }
00170                 NL_DISPLAY_PATH("CNewPath::remapExtension(%s, %s, %d): extension added", ext1.c_str(), ext2.c_str(), substitute);
00171         }
00172 }
00173 
00174 string CNewPath::lookup (const string &filename)
00175 {
00176         // Try to find in the map directories
00177         CNewPath *inst = CNewPath::getInstance();
00178         map<string, CNewFileEntry>::iterator it = inst->_Files.find (filename);
00179         // If found in the map, returns it
00180         if (it != inst->_Files.end())
00181         {
00182                 NL_DISPLAY_PATH("CNewPath::lookup(%s): found in the map directory: '%s'", filename.c_str(), (*it).second.Path.c_str());
00183                 return (*it).second.Path;
00184         }
00185         
00186         // Try to find in the alternative directories
00187         for (uint i = 0; i < inst->_AlternativePaths.size(); i++)
00188         {
00189                 string s = inst->_AlternativePaths[i] + filename;
00190                 if ( CNewFile::fileExists(s) )
00191                 {
00192                         NL_DISPLAY_PATH("CNewPath::lookup(%s): found in the alternative directory: '%s'", filename.c_str(), s.c_str());
00193                         return s;
00194                 }
00195                 
00196                 // try with the remapping
00197                 for (uint j = 0; j < inst->_Extensions.size(); j++)
00198                 {
00199                         string rs = inst->_AlternativePaths[i] + CNewFile::getFilenameWithoutExtension (filename) + "." + inst->_Extensions[j].first;
00200                         if ( CNewFile::fileExists(rs) )
00201                         {
00202                                 NL_DISPLAY_PATH("CNewPath::lookup(%s): found in the alternative directory: '%s'", filename.c_str(), rs.c_str());
00203                                 return rs;
00204                         }
00205                 }
00206         }
00207 
00208         // Not found
00209         NL_DISPLAY_PATH("CNewPath::lookup(%s): file not found", filename.c_str());
00210         return "";
00211 }
00212 
00213 string CNewPath::standardizePath (const string &path, bool addFinalSlash)
00214 {
00215         string newPath;
00216 
00217         // check empty path
00218         if (path.empty()) return "";
00219 
00220         // don't transform the first \\ for windows network path
00221 /*      if (path.size() >= 2 && path[0] == '\\' && path[1] == '\\')
00222         {
00223                 newPath += "\\\\";
00224                 i = 2;
00225         }
00226 */      
00227         for (uint i = 0; i < path.size(); i++)
00228         {
00229                 // don't transform the first \\ for windows network path
00230                 if (path[i] == '\\')
00231                         newPath += '/';
00232                 else
00233                         newPath += path[i];
00234         }
00235 
00236         // add terminal slash
00237         if (addFinalSlash && newPath[path.size()-1] != '/')
00238                 newPath += '/';
00239 
00240         return newPath;
00241 }
00242 
00243 #ifdef NL_OS_WINDOWS
00244 #       define dirent   WIN32_FIND_DATA
00245 #       define DIR              void
00246 
00247 static string sDir;
00248 static char sDirBackup[512];
00249 static WIN32_FIND_DATA findData;
00250 static HANDLE hFind;
00251 
00252 DIR *opendir (const char *path)
00253 {
00254         nlassert (path != NULL);
00255         nlassert (path[0] != '\0');
00256 
00257         nlassert (sDirBackup[0] == '\0');
00258         if (GetCurrentDirectory (512, sDirBackup) == 0)
00259         {
00260                 // failed
00261                 return NULL;
00262         }
00263 
00264         if (!CNewFile::isDirectory(path))
00265         {
00266                 // failed
00267                 return NULL;
00268         }
00269         
00270         sDir = path;
00271 
00272         hFind = NULL;
00273         
00274         return (void *)1;
00275 }
00276 
00277 int closedir (DIR *dir)
00278 {
00279         nlassert (sDirBackup[0] != '\0');
00280         sDirBackup[0] = '\0';
00281         return 0;
00282 }
00283 
00284 dirent *readdir (DIR *dir)
00285 {
00286         // set the current path
00287         nlassert (!sDir.empty());
00288         if (SetCurrentDirectory (sDir.c_str()) == 0)
00289         {
00290                 // failed
00291                 return NULL;
00292         }
00293 
00294         if (hFind == NULL)
00295         {
00296                 hFind = FindFirstFile ("*", &findData);
00297         }
00298         else
00299         {
00300                 if (!FindNextFile (hFind, &findData))
00301                 {
00302                         nlassert (sDirBackup[0] != '\0');
00303                         SetCurrentDirectory (sDirBackup);
00304                         return NULL;
00305                 }
00306         }
00307 
00308         // restore the current path
00309         nlassert (sDirBackup[0] != '\0');
00310         SetCurrentDirectory (sDirBackup);
00311 
00312         return &findData;
00313 }
00314 
00315 #endif // NL_OS_WINDOWS
00316 
00317 bool isdirectory (dirent *de)
00318 {
00319         nlassert (de != NULL);
00320 #ifdef NL_OS_WINDOWS
00321         return (de->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
00322 #else
00323         return (de->d_type & DT_DIR) != 0;
00324 #endif // NL_OS_WINDOWS
00325 }
00326 
00327 bool isfile (dirent *de)
00328 {
00329         nlassert (de != NULL);
00330 #ifdef NL_OS_WINDOWS
00331         return (de->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0;
00332 #else
00333         return (de->d_type & DT_DIR) == 0;
00334 #endif // NL_OS_WINDOWS
00335 }
00336 
00337 string getname (dirent *de)
00338 {
00339         nlassert (de != NULL);
00340 #ifdef NL_OS_WINDOWS
00341         return de->cFileName;
00342 #else
00343         return de->d_name;
00344 #endif // NL_OS_WINDOWS
00345 }
00346 
00347 void CNewPath::getPathContent (const string &path, bool recurse, bool wantDir, bool wantFile, vector<string> &result)
00348 {
00349         DIR *dir = opendir (path.c_str());
00350         if (dir == NULL)
00351         {
00352                 NL_DISPLAY_PATH("CNewPath::getPathContent(%s, %d, %d, %d): could not open the directory", path.c_str(), recurse, wantDir, wantFile);
00353                 return;
00354         }
00355 
00356         // contains path that we have to recurs into
00357         vector<string> recursPath;
00358 
00359         while (true)
00360         {
00361                 dirent *de = readdir(dir);
00362                 if (de == NULL)
00363                 {
00364                         NL_DISPLAY_PATH("CNewPath::getPathContent(%s, %d, %d, %d): end of directory", path.c_str(), recurse, wantDir, wantFile);
00365                         break;
00366                 }
00367 
00368                 // skip . and ..
00369                 if (getname (de) == "." || getname (de) == "..")
00370                         continue;
00371 
00372                 if (isdirectory(de))
00373                 {
00374                         string stdName = standardizePath(path + getname(de));
00375                         if (recurse)
00376                         {
00377                                 NL_DISPLAY_PATH("CNewPath::getPathContent(%s, %d, %d, %d): need to recurse into '%s'", path.c_str(), recurse, wantDir, wantFile, stdName.c_str());
00378                                 recursPath.push_back (stdName);
00379                         }
00380 
00381                         if (wantDir)
00382                         {
00383                                 NL_DISPLAY_PATH("CNewPath::getPathContent(%s, %d, %d, %d): adding path '%s'", path.c_str(), recurse, wantDir, wantFile, stdName.c_str());
00384                                 result.push_back (stdName);
00385                         }
00386                 }
00387                 if (wantFile && isfile(de))
00388                 {
00389                         string stdName = path + getname(de);
00390                         NL_DISPLAY_PATH("CNewPath::getPathContent(%s, %d, %d, %d): adding file '%s'", path.c_str(), recurse, wantDir, wantFile, stdName.c_str());
00391                         result.push_back (stdName);
00392                 }
00393         }
00394 
00395         closedir (dir);
00396 
00397         // let s recurse
00398         for (uint i = 0; i < recursPath.size (); i++)
00399                 getPathContent (recursPath[i], recurse, wantDir, wantFile, result);
00400 }
00401 
00402 void CNewPath::addSearchPath (const string &path, bool recurse, bool alternative)
00403 {
00404         CNewPath *inst = CNewPath::getInstance();
00405         string newPath = standardizePath(path);
00406 
00407         // check empty directory
00408         if (newPath.empty())
00409         {
00410                 nlwarning ("CNewPath::addSearchPath(%s, %d, %d): can't add empty directory, skip it", path.c_str(), recurse, alternative);
00411                 return;
00412         }
00413 
00414         // check if it s a directory
00415         if (!CNewFile::isExists (newPath))
00416         {
00417                 nlwarning ("CNewPath::addSearchPath(%s, %d, %d): '%s' is not found, skip it", path.c_str(), recurse, alternative, newPath.c_str());
00418                 return;
00419         }
00420 
00421         // check if it s a directory
00422         if (!CNewFile::isDirectory (newPath))
00423         {
00424                 nlwarning ("CNewPath::addSearchPath(%s, %d, %d): '%s' is not a directory, skip it", path.c_str(), recurse, alternative, newPath.c_str());
00425                 return;
00426         }
00427 
00428         NL_DISPLAY_PATH("CNewPath::addSearchPath(%s, %d, %d): try to add '%s'", path.c_str(), recurse, alternative, newPath.c_str());
00429 
00430         if (alternative)
00431         {
00432                 vector<string> pathsToProcess;
00433 
00434                 // add the current path
00435                 pathsToProcess.push_back (newPath);
00436 
00437                 if (recurse)
00438                 {
00439                         // find all path and subpath
00440                         getPathContent (newPath, recurse, true, false, pathsToProcess);
00441                 }
00442 
00443                 for (uint p = 0; p < pathsToProcess.size(); p++)
00444                 {
00445                         // check if the path not already in the vector
00446                         uint i;
00447                         for (i = 0; i < inst->_AlternativePaths.size(); i++)
00448                         {
00449                                 if (inst->_AlternativePaths[i] == pathsToProcess[p])
00450                                         break;
00451                         }
00452                         if (i == inst->_AlternativePaths.size())
00453                         {
00454                                 // add them in the alternative directory
00455                                 inst->_AlternativePaths.push_back (pathsToProcess[p]);
00456                                 NL_DISPLAY_PATH("CNewPath::addSearchPath(%s, %d, %d): path '%s' added", newPath.c_str(), recurse, alternative, pathsToProcess[p].c_str());
00457                         }
00458                         else
00459                         {
00460                                 nlwarning ("CNewPath::addSearchPath(%s, %d, %d): path '%s' already added", newPath.c_str(), recurse, alternative, pathsToProcess[p].c_str());
00461                         }
00462                 }
00463         }
00464         else
00465         {
00466                 vector<string> filesToProcess;
00467                 // find all files in the path and subpaths
00468                 getPathContent (newPath, recurse, false, true, filesToProcess);
00469 
00470                 // add them in the map
00471                 for (uint f = 0; f < filesToProcess.size(); f++)
00472                 {
00473                         string filename = CNewFile::getFilename (filesToProcess[f]);
00474                         string filepath = CNewFile::getPath (filesToProcess[f]);
00475 //                      insertFileInMap (filename, filepath, false, CNewFile::getExtension(filename));
00476                         addSearchFile (filesToProcess[f]);
00477                 }
00478         }
00479 }
00480 
00481 void CNewPath::addSearchFile (const string &file, bool remap, const string &virtual_ext)
00482 {
00483         CNewPath *inst = CNewPath::getInstance();
00484         string newFile = standardizePath(file, false);
00485 
00486         // check empty file
00487         if (newFile.empty())
00488         {
00489                 nlwarning ("CNewPath::addSearchFile(%s, %d, %s): can't add empty file, skip it", file.c_str(), remap, virtual_ext.c_str());
00490                 return;
00491         }
00492 
00493         // check if the file exists
00494         if (!CNewFile::isExists (newFile))
00495         {
00496                 nlwarning ("CNewPath::addSearchFile(%s, %d, %s): '%s' is not found, skip it", file.c_str(), remap, virtual_ext.c_str(), newFile.c_str());
00497                 return;
00498         }
00499 
00500         // check if it s a file
00501         if (CNewFile::isDirectory (newFile))
00502         {
00503                 nlwarning ("CNewPath::addSearchFile(%s, %d, %s): '%s' is not a file, skip it", file.c_str(), remap, virtual_ext.c_str(), newFile.c_str());
00504                 return;
00505         }
00506 
00507         string filenamewoext = CNewFile::getFilenameWithoutExtension (newFile);
00508         string filename, ext;
00509         
00510         if (virtual_ext.empty())
00511         {
00512                 filename = CNewFile::getFilename (newFile);
00513                 ext = CNewFile::getExtension (filename);
00514         }
00515         else
00516         {
00517                 filename = filenamewoext + "." + virtual_ext;
00518                 ext = virtual_ext;
00519         }
00520 
00521         map<string, CNewFileEntry>::iterator it = inst->_Files.find (filename);
00522         if (it == inst->_Files.end ())
00523         {
00524                 // ok, the room is empty, let s add it
00525                 insertFileInMap (filename, newFile, remap, ext);
00526         }
00527         else
00528         {
00529                 if (remap)
00530                         nlwarning ("CNewPath::addSearchPath(%s, %d, %s): remapped file '%s' already inserted in the map directory", file.c_str(), remap, virtual_ext.c_str(), filename.c_str());
00531                 else
00532                         nlwarning ("CNewPath::addSearchPath(%s, %d, %s): file '%s' already inserted in the map directory", file.c_str(), remap, virtual_ext.c_str(), filename.c_str());
00533         }
00534 
00535         if (!remap && !ext.empty())
00536         {
00537                 // now, we have to see extension and insert in the map the remapped files
00538                 for (uint i = 0; i < inst->_Extensions.size (); i++)
00539                 {
00540                         if (inst->_Extensions[i].first == ext)
00541                         {
00542                                 // need to remap
00543                                 addSearchFile (newFile, true, inst->_Extensions[i].second);
00544                         }
00545                 }
00546         }
00547 }
00548 
00549 void CNewPath::addSearchListFile (const string &filename, bool recurse, bool alternative)
00550 {
00551         CNewPath *inst = CNewPath::getInstance();
00552 
00553         // check empty file
00554         if (filename.empty())
00555         {
00556                 nlwarning ("CNewPath::addSearchListFile(%s, %d, %d): can't add empty file, skip it", filename.c_str(), recurse, alternative);
00557                 return;
00558         }
00559 
00560         // check if the file exists
00561         if (!CNewFile::isExists (filename))
00562         {
00563                 nlwarning ("CNewPath::addSearchListFile(%s, %d, %d): '%s' is not found, skip it", filename.c_str(), recurse, alternative, filename.c_str());
00564                 return;
00565         }
00566 
00567         // check if it s a file
00568         if (CNewFile::isDirectory (filename))
00569         {
00570                 nlwarning ("CNewPath::addSearchListFile(%s, %d, %d): '%s' is not a file, skip it", filename.c_str(), recurse, alternative, filename.c_str());
00571                 return;
00572         }
00573 
00574         // TODO lire le fichier et ajouter les fichiers qui sont dedans
00575 
00576 }
00577 
00578 
00579 void CNewPath::addSearchBigFile (const string &filename, bool recurse, bool alternative)
00580 {
00581         // TODO & CHECK
00582         nlwarning ("CNewPath::addSearchBigFile(): not impremented");
00583 }
00584 
00585 void CNewPath::insertFileInMap (const string &filename, const string &filepath, bool remap, const string &extension)
00586 {
00587         CNewPath *inst = CNewPath::getInstance();
00588 
00589         // find if the file already exist
00590         map<string, CNewFileEntry>::iterator it = inst->_Files.find (filename);
00591         if (it != inst->_Files.end ())
00592         {
00593                 nlwarning ("CNewPath::insertFileInMap(%s, %s, %d, %s): already inserted from '%s', skip it", filename.c_str(), filepath.c_str(), remap, extension.c_str(), (*it).second.Path.c_str());
00594         }
00595         else
00596         {
00597                 inst->_Files.insert (make_pair (filename, CNewFileEntry (filepath, remap, extension)));
00598                 NL_DISPLAY_PATH("CNewPath::insertFileInMap(%s, %s, %d, %s): added", filename.c_str(), filepath.c_str(), remap, extension.c_str());
00599         }
00600 }
00601 
00602 void CNewPath::display ()
00603 {
00604         CNewPath *inst = CNewPath::getInstance ();
00605         nlinfo ("Contents of the map:");
00606         nlinfo ("%-25s %-5s %-5s %s", "filename", "ext", "remap", "full path");
00607         nlinfo ("----------------------------------------------------");
00608         for (map<string, CNewFileEntry>::iterator it = inst->_Files.begin(); it != inst->_Files.end (); it++)
00609         {
00610                 nlinfo ("%-25s %-5s %-5d %s", (*it).first.c_str(), (*it).second.Extension.c_str(), (*it).second.Remapped, (*it).second.Path.c_str());
00611         }
00612         nlinfo ("");
00613         nlinfo ("Contents of the alternative directory:");
00614         for (uint i = 0; i < inst->_AlternativePaths.size(); i++)
00615         {
00616                 nlinfo ("'%s'", inst->_AlternativePaths[i].c_str ());
00617         }
00618         nlinfo ("");
00619         nlinfo ("Contents of the remapped entension table:");
00620         for (uint j = 0; j < inst->_Extensions.size(); j++)
00621         {
00622                 nlinfo ("'%s' -> '%s'", inst->_Extensions[j].first.c_str (), inst->_Extensions[j].second.c_str ());
00623         }
00624         nlinfo ("End of display");
00625 }
00626 
00638 
00639 #if 0
00640 /*
00641  * Adds a search path
00642  */
00643 void CPath::addSearchPath( const string& path )
00644 {
00645         if ( path == "" )
00646         {
00647                 return;
00648         }
00649         string s = path;
00650         const char slash = '/';
00651 
00652         // Add an ending slash if necessary
00653         if ( path[path.size()-1] != slash )
00654         {
00655                 s += slash;
00656         }
00657 
00658         // Add path to the search paths
00659         _SearchPaths.push_back( s );
00660 }
00661 
00662 
00663 /* Returns the long name (path and filename) for the specified file, using search paths
00664  * stored by addSearchPath.
00665  */
00666 string CPath::lookup (const string &filename, bool throwException)
00667 {
00668         if(!filename.empty())
00669         {
00670                 if ( CNewFile::fileExists(filename) )
00671                 {
00672                         NL_DISPLAY_PATH(filename);
00673                         return filename;
00674                 }
00675                 CStringVector::iterator isv;
00676                 string s;
00677                 for ( isv=CPath::_SearchPaths.begin(); isv!=CPath::_SearchPaths.end(); ++isv )
00678                 {
00679                         s = *isv + filename;
00680                         if ( CNewFile::fileExists(s) )
00681                         {
00682                                 NL_DISPLAY_PATH(s);
00683                                 return s;
00684                         }
00685                 }
00686         }
00687 
00688         if (throwException)
00689                 throw EPathNotFound( filename );
00690 
00691         return "";
00692 }
00693 
00694 #endif
00695 
00696 //********************************* CNewFile
00697 
00698 int CNewFile::getLastSeparator (const string &filename)
00699 {
00700         int pos = filename.find_last_of ('/');
00701         if (pos == string::npos)
00702         {
00703                 pos = filename.find_last_of ('\\');
00704         }
00705         return pos;
00706 }
00707 
00708 string CNewFile::getFilename (const string &filename)
00709 {
00710         int pos = CNewFile::getLastSeparator(filename);
00711         if (pos != string::npos)
00712                 return filename.substr (pos + 1);
00713         else
00714                 return filename;
00715 }
00716 
00717 string CNewFile::getFilenameWithoutExtension (const string &filename)
00718 {
00719         string filename2 = getFilename (filename);
00720         int pos = filename2.find_last_of ('.');
00721         if (pos == string::npos)
00722                 return filename2;
00723         else
00724                 return filename2.substr (0, pos);
00725 }
00726 
00727 string CNewFile::getExtension (const string &filename)
00728 {
00729         int pos = filename.find_last_of ('.');
00730         if (pos == string::npos)
00731                 return "";
00732         else
00733                 return filename.substr (pos + 1);
00734 }
00735 
00736 string CNewFile::getPath (const string &filename)
00737 {
00738         int pos = CNewFile::getLastSeparator(filename);
00739         if (pos != string::npos)
00740                 return filename.substr (0, pos + 1);
00741         else
00742                 return filename;
00743 }
00744 
00745 bool CNewFile::isDirectory (const string &filename)
00746 {
00747 #ifdef NL_OS_WINDOWS
00748         DWORD res = GetFileAttributes(filename.c_str());
00749         nlassert (res != -1);
00750         return (res & FILE_ATTRIBUTE_DIRECTORY) != 0;
00751 #else // NL_OS_WINDOWS
00752         struct stat buf;
00753         int result = stat (filename.c_str (), &buf);
00754         nlassert (result == 0);
00755         return (buf.st_mode & S_IFDIR) != 0;
00756 #endif // NL_OS_WINDOWS
00757 }
00758 
00759 bool CNewFile::isExists (const string &filename)
00760 {
00761 #ifdef NL_OS_WINDOWS
00762         return (GetFileAttributes(filename.c_str()) != -1);
00763 #else // NL_OS_WINDOWS
00764         struct stat buf;
00765         return stat (filename.c_str (), &buf) == 0;
00766 #endif NL_OS_WINDOWS
00767 }
00768 
00769 bool CNewFile::fileExists (const string& filename)
00770 {
00771         return ! ! fstream( filename.c_str(), ios::in );
00772 }
00773 
00774 
00775 string CNewFile::findNewFile (const string &filename)
00776 {
00777         int pos = filename.find_last_of ('.');
00778         if (pos == string::npos)
00779                 return filename;
00780         
00781         string start = filename.substr (0, pos);
00782         string end = filename.substr (pos);
00783 
00784         uint num = 0;
00785         char numchar[4];
00786         string npath;
00787         do
00788         {
00789                 npath = start;
00790                 smprintf(numchar,4,"%03d",num++);
00791                 npath += numchar;
00792                 npath += end;
00793                 if (!CNewFile::fileExists(npath)) break;
00794         }
00795         while (num<999);
00796         return npath;
00797 }
00798 
00799 } // NLMISC
00800 #endif