From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/path_8cpp-source.html | 1280 ++++++++++++++++++++++++++++++++ 1 file changed, 1280 insertions(+) create mode 100644 docs/doxygen/nel/path_8cpp-source.html (limited to 'docs/doxygen/nel/path_8cpp-source.html') diff --git a/docs/doxygen/nel/path_8cpp-source.html b/docs/doxygen/nel/path_8cpp-source.html new file mode 100644 index 00000000..11cf9330 --- /dev/null +++ b/docs/doxygen/nel/path_8cpp-source.html @@ -0,0 +1,1280 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# 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  
+

path.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2000, 2001 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 
+00027 #include "stdmisc.h"
+00028 
+00029 #include <fstream>
+00030 
+00031 #include "nel/misc/big_file.h"
+00032 #include "nel/misc/path.h"
+00033 #include "nel/misc/hierarchical_timer.h"
+00034 
+00035 #ifdef NL_OS_WINDOWS
+00036 #       include <windows.h>
+00037 #       include <sys/types.h>
+00038 #       include <sys/stat.h>
+00039 #       include <direct.h>
+00040 #       include <io.h>
+00041 #       include <fcntl.h>
+00042 #       include <sys/types.h>
+00043 #       include <sys/stat.h>
+00044 #else
+00045 #   include <sys/types.h>
+00046 #   include <sys/stat.h>
+00047 #       include <dirent.h>
+00048 #   include <unistd.h>
+00049 #   include <errno.h>
+00050 #endif // NL_OS_WINDOWS
+00051 
+00052 using namespace std;
+00053 
+00054 namespace NLMISC {
+00055 
+00056 //
+00057 // Macros
+00058 //
+00059 
+00060 // Use this define if you want to display info about the CPath.
+00061 //#define       NL_DEBUG_PATH
+00062 
+00063 #ifdef  NL_DEBUG_PATH
+00064 #define NL_DISPLAY_PATH nlinfo
+00065 #else 
+00066 #ifdef __GNUC__
+00067 #define NL_DISPLAY_PATH(format, args...)
+00068 #else // __GNUC__
+00069 #define NL_DISPLAY_PATH if(false)
+00070 #endif // __GNUC__
+00071 #endif
+00072 
+00073 
+00074 //
+00075 // Variables
+00076 //
+00077 
+00078 CPath *CPath::_Instance = NULL;
+00079 
+00080 
+00081 //
+00082 // Functions
+00083 //
+00084 
+00085 void CPath::getFileList(const std::string &extension, std::vector<std::string> &filenames)
+00086 {
+00087         std::map<std::string, CFileEntry>::iterator first(getInstance()->_Files.begin()), last(getInstance()->_Files.end());
+00088 
+00089         for (; first != last; ++ first)
+00090         {
+00091                 if (first->second.Extension == extension)
+00092                 {
+00093                         filenames.push_back(first->first);
+00094                 }
+00095         }
+00096 }
+00097 
+00098 CPath *CPath::getInstance ()
+00099 {
+00100         if (_Instance == NULL)
+00101         {
+00102                 _Instance = new CPath;
+00103         }
+00104         return _Instance;
+00105 }
+00106 
+00107 void CPath::clearMap ()
+00108 {
+00109         CPath *inst = CPath::getInstance();
+00110         inst->_Files.clear ();
+00111         NL_DISPLAY_PATH("CPath::clearMap(): map directory cleared");
+00112 }
+00113 
+00114 sint CPath::findExtension (const string &ext1, const string &ext2)
+00115 {
+00116         CPath *inst = CPath::getInstance();
+00117         for (uint i = 0; i < inst->_Extensions.size (); i++)
+00118         {
+00119                 if (inst->_Extensions[i].first == ext1 && inst->_Extensions[i].second == ext2)
+00120                 {
+00121                         return i;
+00122                 }
+00123         }
+00124         return -1;
+00125 }
+00126 
+00127 void CPath::remapExtension (const string &ext1, const string &ext2, bool substitute)
+00128 {
+00129         CPath *inst = CPath::getInstance();
+00130 
+00131         string ext1lwr = strlwr (ext1);
+00132         string ext2lwr = strlwr (ext2);
+00133 
+00134         if (ext1lwr.empty() || ext2lwr.empty())
+00135         {
+00136                 nlwarning ("CPath::remapExtension(%s, %s, %d): can't remap empty extension", ext1lwr.c_str(), ext2lwr.c_str(), substitute);
+00137         }
+00138 
+00139         if (ext1lwr == "bnp" || ext2lwr == "bnp")
+00140         {
+00141                 nlwarning ("CPath::remapExtension(%s, %s, %d): you can't remap a big file", ext1lwr.c_str(), ext2lwr.c_str(), substitute);
+00142         }
+00143 
+00144         if (!substitute)
+00145         {
+00146                 // remove the mapping from the mapping list
+00147                 sint n = inst->findExtension (ext1lwr, ext2lwr);
+00148                 nlassert (n != -1);
+00149                 inst->_Extensions.erase (inst->_Extensions.begin() + n);
+00150 
+00151                 // remove mapping in the map
+00152                 map<string, CFileEntry>::iterator it = inst->_Files.begin();
+00153                 map<string, CFileEntry>::iterator nit = it;
+00154                 while (it != inst->_Files.end ())
+00155                 {
+00156                         nit++;
+00157                         if ((*it).second.Remapped && (*it).second.Extension == ext2lwr)
+00158                         {
+00159                                 inst->_Files.erase (it);
+00160                         }
+00161                         it = nit;
+00162                 }
+00163                 NL_DISPLAY_PATH("CPath::remapExtension(%s, %s, %d): extension removed", ext1lwr.c_str(), ext2lwr.c_str(), substitute);
+00164         }
+00165         else
+00166         {
+00167                 sint n = inst->findExtension (ext1lwr, ext2lwr);
+00168                 if (n != -1)
+00169                 {
+00170                         nlwarning ("CPath::remapExtension(%s, %s, %d): remapping already set", ext1lwr.c_str(), ext2lwr.c_str(), substitute);
+00171                         return;
+00172                 }
+00173 
+00174                 // adding mapping into the mapping list
+00175                 inst->_Extensions.push_back (make_pair (ext1lwr, ext2lwr));
+00176 
+00177                 // adding mapping into the map
+00178                 vector<string> newFiles;
+00179                 map<string, CFileEntry>::iterator it = inst->_Files.begin();
+00180                 while (it != inst->_Files.end ())
+00181                 {
+00182                         if (!(*it).second.Remapped && (*it).second.Extension == ext1lwr)
+00183                         {
+00184                                 // find if already exist
+00185                                 uint32 pos = (*it).first.find_last_of (".");
+00186                                 if (pos != string::npos)
+00187                                 {
+00188                                         string file = (*it).first.substr (0, pos + 1);
+00189                                         file += ext2lwr;
+00190 
+00191 // TODO perhaps a problem because I insert in the current map that i parcours
+00192                                         insertFileInMap (file, (*it).second.Path, true, ext2lwr);
+00193                                 }
+00194                         }
+00195                         it++;
+00196                 }
+00197                 NL_DISPLAY_PATH("CPath::remapExtension(%s, %s, %d): extension added", ext1lwr.c_str(), ext2lwr.c_str(), substitute);
+00198         }
+00199 }
+00200 
+00201 string CPath::lookup (const string &filename, bool throwException, bool displayWarning, bool lookupInLocalDirectory)
+00202 {
+00203         // Try to find in the current directory
+00204         if ( lookupInLocalDirectory && CFile::fileExists(filename) )
+00205         {
+00206                 NL_DISPLAY_PATH("CPath::lookup(%s): found in the current directory: '%s'", filename.c_str(), filename.c_str());
+00207                 return filename;
+00208         }
+00209 
+00210         // If the file already contains a @, it means that a lookup already proceed and returning a big file, do nothing
+00211         if (filename.find ("@") != string::npos)
+00212         {
+00213                 NL_DISPLAY_PATH("CPath::lookup(%s):     already found", filename.c_str());
+00214                 return filename;
+00215         }
+00216 
+00217         // Try to find in the map directories
+00218         CPath *inst = CPath::getInstance();
+00219         string str = strlwr (filename);
+00220 
+00221         // Remove end spaces
+00222         while ((!str.empty()) && (str[str.size()-1] == ' '))
+00223         {
+00224                 str.resize (str.size()-1);
+00225         }
+00226 
+00227         map<string, CFileEntry>::iterator it = inst->_Files.find (str);
+00228         // If found in the map, returns it
+00229         if (it != inst->_Files.end())
+00230         {
+00231                 NL_DISPLAY_PATH("CPath::lookup(%s): found in the map directory: '%s'", filename.c_str(), (*it).second.Path.c_str());
+00232                 return (*it).second.Path;
+00233         }
+00234         
+00235 
+00236         // Try to find in the alternative directories
+00237         for (uint i = 0; i < inst->_AlternativePaths.size(); i++)
+00238         {
+00239                 string s = inst->_AlternativePaths[i] + filename;
+00240                 if ( CFile::fileExists(s) )
+00241                 {
+00242                         NL_DISPLAY_PATH("CPath::lookup(%s): found in the alternative directory: '%s'", filename.c_str(), s.c_str());
+00243                         return s;
+00244                 }
+00245                 
+00246                 // try with the remapping
+00247                 for (uint j = 0; j < inst->_Extensions.size(); j++)
+00248                 {
+00249                         if (strlwr(CFile::getExtension (filename)) == inst->_Extensions[j].second)
+00250                         {
+00251                                 string rs = inst->_AlternativePaths[i] + CFile::getFilenameWithoutExtension (filename) + "." + inst->_Extensions[j].first;
+00252                                 if ( CFile::fileExists(rs) )
+00253                                 {
+00254                                         NL_DISPLAY_PATH("CPath::lookup(%s): found in the alternative directory: '%s'", filename.c_str(), rs.c_str());
+00255                                         return rs;
+00256                                 }
+00257                         }
+00258                 }
+00259         }
+00260 
+00261 
+00262         // Not found
+00263         if (displayWarning)
+00264         {
+00265                 nlwarning ("CPath::lookup(%s): file not found", filename.c_str());
+00266         }
+00267 
+00268         if (throwException)
+00269                 throw EPathNotFound (filename);
+00270 
+00271         return "";
+00272 }
+00273 
+00274 bool CPath::exists (const std::string &filename)
+00275 {
+00276         // Try to find in the map directories
+00277         CPath *inst = CPath::getInstance();
+00278         string str = strlwr (filename);
+00279 
+00280         // Remove end spaces
+00281         while ((!str.empty()) && (str[str.size()-1] == ' '))
+00282         {
+00283                 str.resize (str.size()-1);
+00284         }
+00285 
+00286         map<string, CFileEntry>::iterator it = inst->_Files.find (str);
+00287         // If found in the map, returns it
+00288         if (it != inst->_Files.end())
+00289         {
+00290                 return true;
+00291         }
+00292 
+00293         return false;
+00294 }
+00295 
+00296 string CPath::standardizePath (const string &path, bool addFinalSlash)
+00297 {
+00298         string newPath;
+00299 
+00300         // check empty path
+00301         if (path.empty()) return "";
+00302 
+00303         // don't transform the first \\ for windows network path
+00304 /*      if (path.size() >= 2 && path[0] == '\\' && path[1] == '\\')
+00305         {
+00306                 newPath += "\\\\";
+00307                 i = 2;
+00308         }
+00309 */      
+00310         for (uint i = 0; i < path.size(); i++)
+00311         {
+00312                 // don't transform the first \\ for windows network path
+00313                 if (path[i] == '\\')
+00314                         newPath += '/';
+00315                 else
+00316                         newPath += path[i];
+00317         }
+00318 
+00319         // add terminal slash
+00320         if (addFinalSlash && newPath[path.size()-1] != '/')
+00321                 newPath += '/';
+00322 
+00323         return newPath;
+00324 }
+00325 
+00326 // remplace / wiht \ and put all in lower case
+00327 std::string     CPath::standardizeDosPath (const std::string &path)
+00328 {
+00329         string newPath;
+00330 
+00331         for (uint i = 0; i < path.size(); i++)
+00332         {
+00333                 if (path[i] == '/')
+00334                         newPath += '\\';
+00335                 // Yoyo: supress toLower. Not usefull!?!
+00336                 /*else if (isupper(path[i]))
+00337                         newPath += tolower(path[i]);*/
+00338                 else
+00339                         newPath += path[i];
+00340         }
+00341 
+00342         if (CFile::isExists(path) && CFile::isDirectory(path) && newPath[newPath.size()-1] != '\\')
+00343                 newPath += '\\';
+00344 
+00345         return newPath;
+00346 }
+00347 
+00348 
+00349 std::string CPath::getCurrentPath ()
+00350 {
+00351         char buffer [10000];
+00352 
+00353 #ifdef NL_OS_WINDOWS
+00354         return _getcwd(buffer, 10000);
+00355 #else
+00356         return getcwd(buffer, 10000);
+00357 #endif
+00358 }
+00359 
+00360 std::string CPath::getFullPath (const std::string &path, bool addFinalSlash)
+00361 {
+00362         string currentPath = standardizePath (getCurrentPath ());
+00363         string sPath = standardizePath (path, addFinalSlash);
+00364 
+00365         // current path
+00366         if (path.empty())
+00367         {
+00368                 return currentPath;
+00369         }
+00370 
+00371         // windows full path
+00372         if (path.size() >= 2 && path[1] == ':')
+00373         {
+00374                 return sPath;
+00375         }
+00376 
+00377         if (path.size() >= 2 && (path[0] == '/' || path[0] == '\\') && (path[1] == '/' || path[1] == '\\'))
+00378         {
+00379                 return sPath;
+00380         }
+00381 
+00382 
+00383         // from root
+00384         if (path [0] == '/' || path[0] == '\\')
+00385         {
+00386                 if (currentPath.size() > 2 && currentPath[1] == ':')
+00387                 {
+00388                         return currentPath.substr(0,3) + sPath.substr(1);
+00389                 }
+00390                 else
+00391                 {
+00392                         return sPath;
+00393                 }
+00394         }
+00395 
+00396         // default case
+00397         return currentPath + sPath;
+00398 }
+00399 
+00400 
+00401 
+00402 #ifdef NL_OS_WINDOWS
+00403 #       define dirent   WIN32_FIND_DATA
+00404 #       define DIR              void
+00405 
+00406 static string sDir;
+00407 static char sDirBackup[512];
+00408 static WIN32_FIND_DATA findData;
+00409 static HANDLE hFind;
+00410 
+00411 DIR *opendir (const char *path)
+00412 {
+00413         nlassert (path != NULL);
+00414         nlassert (path[0] != '\0');
+00415 
+00416         nlassert (sDirBackup[0] == '\0');
+00417         if (GetCurrentDirectory (512, sDirBackup) == 0)
+00418         {
+00419                 // failed
+00420                 sDirBackup[0] = 0;
+00421                 return NULL;
+00422         }
+00423 
+00424 
+00425         if (!CFile::isDirectory(path))
+00426         {
+00427                 // failed
+00428                 sDirBackup[0] = 0;
+00429                 return NULL;
+00430         }
+00431         
+00432         sDir = path;
+00433 
+00434         hFind = NULL;
+00435         
+00436         return (void *)1;
+00437 }
+00438 
+00439 int closedir (DIR *dir)
+00440 {
+00441         nlassert (sDirBackup[0] != '\0');
+00442         FindClose(hFind);
+00443         sDirBackup[0] = '\0';
+00444         return 0;
+00445 }
+00446 
+00447 dirent *readdir (DIR *dir)
+00448 {
+00449         // set the current path
+00450         nlassert (!sDir.empty());
+00451         if (SetCurrentDirectory (sDir.c_str()) == 0)
+00452         {
+00453                 // failed
+00454                 return NULL;
+00455         }
+00456 
+00457         if (hFind == NULL)
+00458         {
+00459                 hFind = FindFirstFile ("*", &findData);
+00460         }
+00461         else
+00462         {
+00463                 if (!FindNextFile (hFind, &findData))
+00464                 {
+00465                         nlassert (sDirBackup[0] != '\0');
+00466                         SetCurrentDirectory (sDirBackup);
+00467                         return NULL;
+00468                 }
+00469         }
+00470 
+00471         // restore the current path
+00472         nlassert (sDirBackup[0] != '\0');
+00473         SetCurrentDirectory (sDirBackup);
+00474 
+00475         return &findData;
+00476 }
+00477 
+00478 #endif // NL_OS_WINDOWS
+00479 
+00480 #ifndef NL_OS_WINDOWS
+00481 string BasePathgetPathContent;
+00482 #endif
+00483 
+00484 bool isdirectory (dirent *de)
+00485 {
+00486         nlassert (de != NULL);
+00487 #ifdef NL_OS_WINDOWS
+00488         return ((de->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) && ((de->dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) == 0);
+00489 #else
+00490         //nlinfo ("isdirectory filename %s -> 0x%08x", de->d_name, de->d_type);
+00491         // we can't use "de->d_type & DT_DIR" because it s always NULL on libc2.1
+00492         //return (de->d_type & DT_DIR) != 0;
+00493 
+00494         return CFile::isDirectory (BasePathgetPathContent + de->d_name);
+00495 
+00496 #endif // NL_OS_WINDOWS
+00497 }
+00498 
+00499 bool isfile (dirent *de)
+00500 {
+00501         nlassert (de != NULL);
+00502 #ifdef NL_OS_WINDOWS
+00503         return ((de->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) && ((de->dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) == 0);
+00504 #else
+00505         // we can't use "de->d_type & DT_DIR" because it s always NULL on libc2.1
+00506         //return (de->d_type & DT_DIR) == 0;
+00507 
+00508         return !CFile::isDirectory (BasePathgetPathContent + de->d_name);
+00509 
+00510 #endif // NL_OS_WINDOWS
+00511 }
+00512 
+00513 string getname (dirent *de)
+00514 {
+00515         nlassert (de != NULL);
+00516 #ifdef NL_OS_WINDOWS
+00517         return de->cFileName;
+00518 #else
+00519         return de->d_name;
+00520 #endif // NL_OS_WINDOWS
+00521 }
+00522 
+00523 void CPath::getPathContent (const string &path, bool recurse, bool wantDir, bool wantFile, vector<string> &result)
+00524 {                       
+00525 #ifndef NL_OS_WINDOWS
+00526         BasePathgetPathContent = CPath::standardizePath (path);
+00527 #endif
+00528 
+00529         DIR *dir = opendir (path.c_str());
+00530 
+00531         if (dir == NULL)
+00532         {
+00533                 NL_DISPLAY_PATH("CPath::getPathContent(%s, %d, %d, %d): could not open the directory", path.c_str(), recurse, wantDir, wantFile);
+00534                 return;
+00535         }
+00536 
+00537         // contains path that we have to recurs into
+00538         vector<string> recursPath;
+00539 
+00540         while (true)
+00541         {
+00542                 dirent *de = readdir(dir);
+00543                 if (de == NULL)
+00544                 {
+00545                         NL_DISPLAY_PATH("CPath::getPathContent(%s, %d, %d, %d): end of directory", path.c_str(), recurse, wantDir, wantFile);
+00546                         break;
+00547                 }
+00548 
+00549                 string fn = getname (de);
+00550 
+00551                 // skip . and ..
+00552                 if (fn == "." || fn == "..")
+00553                         continue;
+00554 
+00555                 if (isdirectory(de))
+00556                 {
+00557                         // skip CVS directory
+00558                         if (fn == "CVS")
+00559                         {
+00560                                 NL_DISPLAY_PATH("CPath::getPathContent(%s, %d, %d, %d): skip CVS directory", path.c_str(), recurse, wantDir, wantFile);
+00561                                 continue;
+00562                         }
+00563 
+00564                         string stdName = standardizePath(standardizePath(path) + fn);
+00565                         if (recurse)
+00566                         {
+00567                                 NL_DISPLAY_PATH("CPath::getPathContent(%s, %d, %d, %d): need to recurse into '%s'", path.c_str(), recurse, wantDir, wantFile, stdName.c_str());
+00568                                 recursPath.push_back (stdName);
+00569                         }
+00570 
+00571                         if (wantDir)
+00572                         {
+00573                                 NL_DISPLAY_PATH("CPath::getPathContent(%s, %d, %d, %d): adding path '%s'", path.c_str(), recurse, wantDir, wantFile, stdName.c_str());
+00574                                 result.push_back (stdName);
+00575                         }
+00576                 }
+00577                 if (wantFile && isfile(de))
+00578                 {
+00579                         if (fn.size() >= 4 && fn.substr (fn.size()-4) == ".log")
+00580                         {
+00581                                 NL_DISPLAY_PATH("CPath::getPathContent(%s, %d, %d, %d): skip *.log files (%s)", path.c_str(), recurse, wantDir, wantFile, fn.c_str());
+00582                                 continue;
+00583                         }
+00584 
+00585 /*                      int lastSep = CFile::getLastSeparator(path);
+00586                         #ifdef NL_OS_WINDOWS
+00587                                 char sep = lastSep == std::string::npos ? '\\'
+00588                                                                                                             : path[lastSep];
+00589                         #else
+00590                                 char sep = lastSep == std::string::npos ? '/'
+00591                                                                                                                 : path[lastSep];
+00592                         #endif
+00593 */                      
+00594                         string stdName = standardizePath(path) + getname(de);
+00595                         
+00596                                 
+00597                         NL_DISPLAY_PATH("CPath::getPathContent(%s, %d, %d, %d): adding file '%s'", path.c_str(), recurse, wantDir, wantFile, stdName.c_str());
+00598                         result.push_back (stdName);
+00599                 }
+00600         }
+00601 
+00602         closedir (dir);
+00603 
+00604 #ifndef NL_OS_WINDOWS
+00605         BasePathgetPathContent = "";
+00606 #endif
+00607 
+00608         // let s recurse
+00609         for (uint i = 0; i < recursPath.size (); i++)
+00610         {               
+00611                 getPathContent (recursPath[i], recurse, wantDir, wantFile, result);
+00612         }
+00613 }
+00614 
+00615 void CPath::removeAllAlternativeSearchPath ()
+00616 {
+00617         CPath *inst = CPath::getInstance();
+00618         inst->_AlternativePaths.clear ();
+00619         NL_DISPLAY_PATH("CPath::RemoveAllAternativeSearchPath(): removed");
+00620 }
+00621 
+00622 
+00623 void CPath::addSearchPath (const string &path, bool recurse, bool alternative)
+00624 {
+00625         H_AUTO_INST(addSearchPath);
+00626 
+00627         CPath *inst = CPath::getInstance();
+00628 
+00629         // check empty directory
+00630         if (path.empty())
+00631         {
+00632                 nlwarning ("CPath::addSearchPath(%s, %d, %d): can't add empty directory, skip it", path.c_str(), recurse, alternative);
+00633                 return;
+00634         }
+00635 
+00636         // check if it s a directory
+00637         if (!CFile::isDirectory (path))
+00638         {
+00639                 nlinfo ("CPath::addSearchPath(%s, %d, %d): '%s' is not a directory, I'll call addSearchFile()", path.c_str(), recurse, alternative, path.c_str());
+00640                 addSearchFile (path);
+00641                 return;
+00642         }
+00643 
+00644         string newPath = standardizePath(path);
+00645 
+00646         // check if it s a directory
+00647         if (!CFile::isExists (newPath))
+00648         {
+00649                 nlwarning ("CPath::addSearchPath(%s, %d, %d): '%s' is not found, skip it", path.c_str(), recurse, alternative, newPath.c_str());
+00650                 return;
+00651         }
+00652 
+00653         nlinfo ("CPath::addSearchPath(%s, %d, %d): adding the path '%s'", path.c_str(), recurse, alternative, newPath.c_str());
+00654 
+00655         NL_DISPLAY_PATH("CPath::addSearchPath(%s, %d, %d): try to add '%s'", path.c_str(), recurse, alternative, newPath.c_str());
+00656 
+00657         if (alternative)
+00658         {
+00659                 vector<string> pathsToProcess;
+00660 
+00661                 // add the current path
+00662                 pathsToProcess.push_back (newPath);
+00663 
+00664                 if (recurse)
+00665                 {
+00666                         // find all path and subpath
+00667                         getPathContent (newPath, recurse, true, false, pathsToProcess);
+00668                 }
+00669 
+00670                 for (uint p = 0; p < pathsToProcess.size(); p++)
+00671                 {
+00672                         // check if the path not already in the vector
+00673                         uint i;
+00674                         for (i = 0; i < inst->_AlternativePaths.size(); i++)
+00675                         {
+00676                                 if (inst->_AlternativePaths[i] == pathsToProcess[p])
+00677                                         break;
+00678                         }
+00679                         if (i == inst->_AlternativePaths.size())
+00680                         {
+00681                                 // add them in the alternative directory
+00682                                 inst->_AlternativePaths.push_back (pathsToProcess[p]);
+00683                                 NL_DISPLAY_PATH("CPath::addSearchPath(%s, %d, %d): path '%s' added", newPath.c_str(), recurse, alternative, pathsToProcess[p].c_str());
+00684                         }
+00685                         else
+00686                         {
+00687                                 nlwarning ("CPath::addSearchPath(%s, %d, %d): path '%s' already added", newPath.c_str(), recurse, alternative, pathsToProcess[p].c_str());
+00688                         }
+00689                 }
+00690         }
+00691         else
+00692         {
+00693                 vector<string> filesToProcess;
+00694                 // find all files in the path and subpaths
+00695                 getPathContent (newPath, recurse, false, true, filesToProcess);
+00696 
+00697                 // add them in the map
+00698                 for (uint f = 0; f < filesToProcess.size(); f++)
+00699                 {
+00700                         string filename = CFile::getFilename (filesToProcess[f]);
+00701                         string filepath = CFile::getPath (filesToProcess[f]);
+00702 //                      insertFileInMap (filename, filepath, false, CFile::getExtension(filename));
+00703                         addSearchFile (filesToProcess[f]);
+00704                 }
+00705         }
+00706 }
+00707 
+00708 void CPath::addSearchFile (const string &file, bool remap, const string &virtual_ext)
+00709 {
+00710         CPath *inst = CPath::getInstance();
+00711         string newFile = standardizePath(file, false);
+00712 
+00713         // check empty file
+00714         if (newFile.empty())
+00715         {
+00716                 nlwarning ("CPath::addSearchFile(%s, %d, %s): can't add empty file, skip it", file.c_str(), remap, virtual_ext.c_str());
+00717                 return;
+00718         }
+00719 
+00720         // check if the file exists
+00721         if (!CFile::isExists (newFile))
+00722         {
+00723                 nlwarning ("CPath::addSearchFile(%s, %d, %s): '%s' is not found, skip it", file.c_str(), remap, virtual_ext.c_str(), newFile.c_str());
+00724                 return;
+00725         }
+00726 
+00727         // check if it s a file
+00728         if (CFile::isDirectory (newFile))
+00729         {
+00730                 nlwarning ("CPath::addSearchFile(%s, %d, %s): '%s' is not a file, skip it", file.c_str(), remap, virtual_ext.c_str(), newFile.c_str());
+00731                 return;
+00732         }
+00733 
+00734         // check if it s a big file
+00735         if (CFile::getExtension(newFile) == "bnp")
+00736         {
+00737                 NL_DISPLAY_PATH ("CPath::addSearchFile(%s, %d, %s): '%s' is a big file, add it", file.c_str(), remap, virtual_ext.c_str(), newFile.c_str());
+00738                 addSearchBigFile(file, false, false);
+00739                 return;
+00740         }
+00741 
+00742         string filenamewoext = CFile::getFilenameWithoutExtension (newFile);
+00743         string filename, ext;
+00744         
+00745         if (virtual_ext.empty())
+00746         {
+00747                 filename = CFile::getFilename (newFile);
+00748                 ext = CFile::getExtension (filename);
+00749         }
+00750         else
+00751         {
+00752                 filename = filenamewoext + "." + virtual_ext;
+00753                 ext = virtual_ext;
+00754         }
+00755 
+00756         insertFileInMap (filename, newFile, remap, ext);
+00757 
+00758         if (!remap && !ext.empty())
+00759         {
+00760                 // now, we have to see extension and insert in the map the remapped files
+00761                 for (uint i = 0; i < inst->_Extensions.size (); i++)
+00762                 {
+00763                         if (inst->_Extensions[i].first == strlwr(ext))
+00764                         {
+00765                                 // need to remap
+00766                                 addSearchFile (newFile, true, inst->_Extensions[i].second);
+00767                         }
+00768                 }
+00769         }
+00770 }
+00771 
+00772 void CPath::addSearchListFile (const string &filename, bool recurse, bool alternative)
+00773 {
+00774         // check empty file
+00775         if (filename.empty())
+00776         {
+00777                 nlwarning ("CPath::addSearchListFile(%s, %d, %d): can't add empty file, skip it", filename.c_str(), recurse, alternative);
+00778                 return;
+00779         }
+00780 
+00781         // check if the file exists
+00782         if (!CFile::isExists (filename))
+00783         {
+00784                 nlwarning ("CPath::addSearchListFile(%s, %d, %d): '%s' is not found, skip it", filename.c_str(), recurse, alternative, filename.c_str());
+00785                 return;
+00786         }
+00787 
+00788         // check if it s a file
+00789         if (CFile::isDirectory (filename))
+00790         {
+00791                 nlwarning ("CPath::addSearchListFile(%s, %d, %d): '%s' is not a file, skip it", filename.c_str(), recurse, alternative, filename.c_str());
+00792                 return;
+00793         }
+00794 
+00795         // TODO lire le fichier et ajouter les fichiers qui sont dedans
+00796 
+00797 }
+00798 
+00799 // WARNING : recurse is not used
+00800 void CPath::addSearchBigFile (const string &sBigFilename, bool recurse, bool alternative)
+00801 {
+00802         // Check if filename is not empty
+00803         if (sBigFilename.empty())
+00804         {
+00805                 nlwarning ("CPath::addSearchBigFile(%s, %d, %d): can't add empty file, skip it", sBigFilename.c_str(), recurse, alternative);
+00806                 return;
+00807         }
+00808         // Check if the file exists
+00809         if (!CFile::isExists (sBigFilename))
+00810         {
+00811                 nlwarning ("CPath::addSearchBigFile(%s, %d, %d): '%s' is not found, skip it", sBigFilename.c_str(), recurse, alternative, sBigFilename.c_str());
+00812                 return;
+00813         }
+00814         // Check if it s a file
+00815         if (CFile::isDirectory (sBigFilename))
+00816         {
+00817                 nlwarning ("CPath::addSearchBigFile(%s, %d, %d): '%s' is not a file, skip it", sBigFilename.c_str(), recurse, alternative, sBigFilename.c_str());
+00818                 return;
+00819         }
+00820         // Open and read the big file header
+00821         CPath *inst = CPath::getInstance();
+00822 
+00823         FILE *Handle = fopen (sBigFilename.c_str(), "rb");
+00824         if (Handle == NULL)
+00825         {
+00826                 nlwarning ("CPath::addSearchBigFile(%s, %d, %d): can't open file, skip it", sBigFilename.c_str(), recurse, alternative);
+00827                 return;
+00828         }
+00829 
+00830         // add the link with the CBigFile singleton
+00831         CBigFile::getInstance().add (sBigFilename, BF_ALWAYS_OPENED | BF_CACHE_FILE_ON_OPEN);
+00832 
+00833         // parse the big file to add file in the map
+00834         fseek (Handle, 0, SEEK_END);
+00835         uint32 nFileSize = ftell (Handle);
+00836         fseek (Handle, nFileSize-4, SEEK_SET);
+00837         uint32 nOffsetFromBegining;
+00838         fread (&nOffsetFromBegining, sizeof(uint32), 1, Handle);
+00839         fseek (Handle, nOffsetFromBegining, SEEK_SET);
+00840         uint32 nNbFile;
+00841         fread (&nNbFile, sizeof(uint32), 1, Handle);
+00842         for (uint32 i = 0; i < nNbFile; ++i)
+00843         {
+00844                 char FileName[256];
+00845                 uint8 nStringSize;
+00846                 fread (&nStringSize, 1, 1, Handle);
+00847                 fread (FileName, 1, nStringSize, Handle);
+00848                 FileName[nStringSize] = 0;
+00849                 uint32 nFileSize;
+00850                 fread (&nFileSize, sizeof(uint32), 1, Handle);
+00851                 uint32 nFilePos;
+00852                 fread (&nFilePos, sizeof(uint32), 1, Handle);
+00853                 string sTmp = strlwr(string(FileName));
+00854                 if (sTmp.empty())
+00855                 {
+00856                         nlwarning ("CPath::addSearchBigFile(%s, %d, %d): can't add empty file, skip it", sBigFilename.c_str(), recurse, alternative);
+00857                         continue;
+00858                 }
+00859                 string bigfilenamealone = CFile::getFilename (sBigFilename);
+00860                 string filenamewoext = CFile::getFilenameWithoutExtension (sTmp);
+00861                 string ext = strlwr(CFile::getExtension(sTmp));
+00862 
+00863                 insertFileInMap (sTmp, bigfilenamealone + "@" + sTmp, false, ext);
+00864 
+00865                 for (uint j = 0; j < inst->_Extensions.size (); j++)
+00866                 {
+00867                         if (inst->_Extensions[j].first == ext)
+00868                         {
+00869                                 // need to remap
+00870                                 insertFileInMap (filenamewoext+"."+inst->_Extensions[j].second, 
+00871                                                                 bigfilenamealone + "@" + sTmp, 
+00872                                                                 true, 
+00873                                                                 inst->_Extensions[j].second);
+00874                         }
+00875                 }
+00876 
+00877         }
+00878         fclose (Handle);
+00879 }
+00880 
+00881 void CPath::insertFileInMap (const string &filename, const string &filepath, bool remap, const string &extension)
+00882 {
+00883         CPath *inst = CPath::getInstance();
+00884 
+00885         // find if the file already exist
+00886         map<string, CFileEntry>::iterator it = inst->_Files.find (strlwr(filename));
+00887         if (it != inst->_Files.end ())
+00888         {
+00889                 if ((*it).second.Path.find("@") != string::npos && filepath.find("@") == string::npos)
+00890                 {
+00891                         // if there's a file in a big file and a file in a path, the file in path wins
+00892                         // remplace with the new one
+00893                         nlinfo ("CPath::insertFileInMap(%s, %s, %d, %s): already inserted from '%s' but special case so overide it", filename.c_str(), filepath.c_str(), remap, extension.c_str(), (*it).second.Path.c_str());
+00894                         (*it).second.Path = filepath;
+00895                         (*it).second.Remapped = remap;
+00896                         (*it).second.Extension = extension;
+00897                 }
+00898                 else
+00899                 {
+00900                         nlwarning ("CPath::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());
+00901                 }
+00902         }
+00903         else
+00904         {
+00905                 inst->_Files.insert (make_pair (strlwr(filename), CFileEntry (filepath, remap, strlwr(extension))));
+00906                 NL_DISPLAY_PATH("CPath::insertFileInMap(%s, %s, %d, %s): added", strlwr(filename).c_str(), filepath.c_str(), remap, strlwr(extension).c_str());
+00907         }
+00908 }
+00909 
+00910 void CPath::display ()
+00911 {
+00912         CPath *inst = CPath::getInstance ();
+00913         nlinfo ("Contents of the map:");
+00914         nlinfo ("%-25s %-5s %-5s %s", "filename", "ext", "remap", "full path");
+00915         nlinfo ("----------------------------------------------------");
+00916         for (map<string, CFileEntry>::iterator it = inst->_Files.begin(); it != inst->_Files.end (); it++)
+00917         {
+00918                 nlinfo ("%-25s %-5s %-5d %s", (*it).first.c_str(), (*it).second.Extension.c_str(), (*it).second.Remapped, (*it).second.Path.c_str());
+00919         }
+00920         nlinfo ("");
+00921         nlinfo ("Contents of the alternative directory:");
+00922         for (uint i = 0; i < inst->_AlternativePaths.size(); i++)
+00923         {
+00924                 nlinfo ("'%s'", inst->_AlternativePaths[i].c_str ());
+00925         }
+00926         nlinfo ("");
+00927         nlinfo ("Contents of the remapped entension table:");
+00928         for (uint j = 0; j < inst->_Extensions.size(); j++)
+00929         {
+00930                 nlinfo ("'%s' -> '%s'", inst->_Extensions[j].first.c_str (), inst->_Extensions[j].second.c_str ());
+00931         }
+00932         nlinfo ("End of display");
+00933 }
+00934 
+00940 
+00941 int CFile::getLastSeparator (const string &filename)
+00942 {
+00943         uint32 pos = filename.find_last_of ('/');
+00944         if (pos == string::npos)
+00945         {
+00946                 pos = filename.find_last_of ('\\');
+00947                 if (pos == string::npos)
+00948                 {
+00949                         pos = filename.find_last_of ('@');
+00950                 }
+00951         }
+00952         return pos;
+00953 }
+00954 
+00955 string CFile::getFilename (const string &filename)
+00956 {
+00957         uint32 pos = CFile::getLastSeparator(filename);
+00958         if (pos != string::npos)
+00959                 return filename.substr (pos + 1);
+00960         else
+00961                 return filename;
+00962 }
+00963 
+00964 string CFile::getFilenameWithoutExtension (const string &filename)
+00965 {
+00966         string filename2 = getFilename (filename);
+00967         uint32 pos = filename2.find_last_of ('.');
+00968         if (pos == string::npos)
+00969                 return filename2;
+00970         else
+00971                 return filename2.substr (0, pos);
+00972 }
+00973 
+00974 string CFile::getExtension (const string &filename)
+00975 {
+00976         uint32 pos = filename.find_last_of ('.');
+00977         if (pos == string::npos)
+00978                 return "";
+00979         else
+00980                 return filename.substr (pos + 1);
+00981 }
+00982 
+00983 string CFile::getPath (const string &filename)
+00984 {
+00985         uint32 pos = CFile::getLastSeparator(filename);
+00986         if (pos != string::npos)
+00987                 return filename.substr (0, pos + 1);
+00988         else
+00989                 return "";
+00990 }
+00991 
+00992 bool CFile::isDirectory (const string &filename)
+00993 {
+00994 #ifdef NL_OS_WINDOWS
+00995         DWORD res = GetFileAttributes(filename.c_str());
+00996         if (res == -1)
+00997         {
+00998                 nlwarning ("%s is not a valid file / directory name", filename);
+00999                 return false;
+01000         }
+01001         return (res & FILE_ATTRIBUTE_DIRECTORY) != 0;
+01002 #else // NL_OS_WINDOWS
+01003         struct stat buf;
+01004         int res = stat (filename.c_str (), &buf);
+01005         if (res == -1)
+01006         {
+01007                 nlwarning ("can't stat '%s' error %d '%s'", filename.c_str(), errno, strerror(errno));
+01008                 return false;
+01009         }
+01010         return (buf.st_mode & S_IFDIR) != 0;
+01011 #endif // NL_OS_WINDOWS
+01012 }
+01013 
+01014 bool CFile::isExists (const string &filename)
+01015 {
+01016 #ifdef NL_OS_WINDOWS
+01017         return (GetFileAttributes(filename.c_str()) != -1);
+01018 #else // NL_OS_WINDOWS
+01019         struct stat buf;
+01020         return stat (filename.c_str (), &buf) == 0;
+01021 #endif // NL_OS_WINDOWS
+01022 }
+01023 
+01024 bool CFile::fileExists (const string& filename)
+01025 {
+01026         return ! ! fstream( filename.c_str(), ios::in );
+01027 }
+01028 
+01029 
+01030 string CFile::findNewFile (const string &filename)
+01031 {
+01032         uint32 pos = filename.find_last_of ('.');
+01033         if (pos == string::npos)
+01034                 return filename;
+01035         
+01036         string start = filename.substr (0, pos);
+01037         string end = filename.substr (pos);
+01038 
+01039         uint num = 0;
+01040         char numchar[4];
+01041         string npath;
+01042         do
+01043         {
+01044                 npath = start;
+01045                 smprintf(numchar,4,"%03d",num++);
+01046                 npath += numchar;
+01047                 npath += end;
+01048                 if (!CFile::fileExists(npath)) break;
+01049         }
+01050         while (num<999);
+01051         return npath;
+01052 }
+01053 
+01054 // \warning doesn't work with big file
+01055 uint32  CFile::getFileSize (const std::string &filename)
+01056 {
+01057 /*      FILE *fp = fopen (filename.c_str(), "rb");
+01058         if (fp == NULL) return 0;
+01059         fseek (fp, 0, SEEK_END);
+01060         uint32 size = ftell (fp);
+01061         fclose (fp);
+01062         return size;*/
+01063 
+01064 /*      const char *s = filename.c_str();
+01065         int h = _open (s, _O_RDONLY | _O_BINARY);
+01066         _lseek (h, 0, SEEK_END);
+01067         uint32 size = _tell (h);
+01068         _close (h);
+01069         return size;
+01070 */
+01071 
+01072 #if defined (NL_OS_WINDOWS)
+01073         struct _stat buf;
+01074         int result = _stat (filename.c_str (), &buf);
+01075 #elif defined (NL_OS_UNIX)
+01076         struct stat buf;
+01077         int result = stat (filename.c_str (), &buf);
+01078 #endif
+01079         if (result != 0) return 0;
+01080         else return buf.st_size;
+01081         
+01082 }
+01083 
+01084 uint32  CFile::getFileModificationDate(const std::string &filename)
+01085 {
+01086         uint pos;
+01087         string fn;
+01088         if ((pos=filename.find('@')) != string::npos)
+01089         {
+01090                 fn = filename.substr (0, pos);
+01091         }
+01092         else
+01093         {
+01094                 fn = filename;
+01095         }
+01096 
+01097 #if defined (NL_OS_WINDOWS)
+01098         struct _stat buf;
+01099         int result = _stat (fn.c_str (), &buf);
+01100 #elif defined (NL_OS_UNIX)
+01101         struct stat buf;
+01102         int result = stat (fn.c_str (), &buf);
+01103 #endif
+01104 
+01105         if (result != 0) return 0;
+01106         else return buf.st_mtime;
+01107 }
+01108 
+01109 
+01110 uint32  CFile::getFileCreationDate(const std::string &filename)
+01111 {
+01112         uint pos;
+01113         string fn;
+01114         if ((pos=filename.find('@')) != string::npos)
+01115         {
+01116                 fn = filename.substr (0, pos);
+01117         }
+01118         else
+01119         {
+01120                 fn = filename;
+01121         }
+01122 
+01123 #if defined (NL_OS_WINDOWS)
+01124         struct _stat buf;
+01125         int result = _stat (fn.c_str (), &buf);
+01126 #elif defined (NL_OS_UNIX)
+01127         struct stat buf;
+01128         int result = stat (fn.c_str (), &buf);
+01129 #endif
+01130 
+01131         if (result != 0) return 0;
+01132         else return buf.st_ctime;
+01133 }
+01134 
+01135 struct CFileEntry
+01136 {
+01137         CFileEntry (const string &filename, void (*callback)(const string &filename)) : FileName (filename), Callback (callback)
+01138         {
+01139                 LastModified = CFile::getFileModificationDate(filename);
+01140         }
+01141         string FileName;
+01142         void (*Callback)(const string &filename);
+01143         uint32 LastModified;
+01144 };
+01145 
+01146 static vector <CFileEntry> FileToCheck;
+01147 
+01148 
+01149 void CFile::addFileChangeCallback (const std::string &filename, void (*cb)(const string &filename))
+01150 {
+01151         nlinfo ("CFile::addFileChangeCallback: I'll check the modification date for this file '%s'", CPath::lookup(filename).c_str());
+01152         FileToCheck.push_back(CFileEntry(CPath::lookup(filename), cb));
+01153 }
+01154 
+01155 void CFile::checkFileChange (TTime frequency)
+01156 {
+01157         static TTime lastChecked = CTime::getLocalTime();
+01158 
+01159         if (CTime::getLocalTime() > lastChecked + frequency)
+01160         {
+01161                 for (uint i = 0; i < FileToCheck.size(); i++)
+01162                 {
+01163                         if(CFile::getFileModificationDate(FileToCheck[i].FileName) != FileToCheck[i].LastModified)
+01164                         {
+01165                                 // need to reload it
+01166                                 if(FileToCheck[i].Callback != NULL)
+01167                                         FileToCheck[i].Callback(FileToCheck[i].FileName);
+01168 
+01169                                 FileToCheck[i].LastModified = CFile::getFileModificationDate(FileToCheck[i].FileName);
+01170                         }
+01171                 }
+01172 
+01173                 lastChecked = CTime::getLocalTime();
+01174         }
+01175 }
+01176 
+01177 
+01178 static bool CopyMoveFile(const char *dest, const char *src, bool copyFile, bool failIfExists = false)
+01179 {
+01180         if (!dest || !src) return false;
+01181         if (!strlen(dest) || !strlen(src)) return false;        
+01182 #ifdef NL_OS_WINDOWS
+01183         std::string dosdest = CPath::standardizeDosPath(dest);
+01184         std::string dossrc = CPath::standardizeDosPath(src);
+01185 
+01186         return copyFile  ? CopyFile(dossrc.c_str(), dosdest.c_str(), failIfExists) != FALSE
+01187                                          : MoveFile(dossrc.c_str(), dosdest.c_str()) != FALSE;
+01188 #else
+01189         nlstop; // not implemented yet
+01190         return false;
+01191 #endif  
+01192 }
+01193 
+01194 bool CFile::copyFile(const char *dest, const char *src, bool failIfExists /*=false*/)
+01195 {
+01196         return CopyMoveFile(dest, src, true, failIfExists);
+01197 }
+01198 
+01199 bool CFile::moveFile(const char *dest,const char *src)
+01200 {
+01201         return CopyMoveFile(dest, src, false);
+01202 }
+01203 
+01204 
+01205 bool CFile::createDirectory(const std::string &filename)
+01206 {
+01207 #ifdef NL_OS_WINDOWS
+01208         return _mkdir(filename.c_str())==0;
+01209 #else
+01210         // Set full permissions....
+01211         return mkdir(filename.c_str(), 0xFFFF)==0;
+01212 #endif
+01213 }
+01214 
+01215 
+01216 } // NLMISC
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1