NLMISC::CBigFile Class Reference

#include <big_file.h>


Public Member Functions

bool add (const std::string &sBigFileName, uint32 nOptions)
FILE * getFile (const std::string &sFileName, uint32 &rFileSize, uint32 &rBigFileOffset, bool &rCacheFileOnOpen, bool &rAlwaysOpened)
char * getFileNamePtr (const std::string &sFileName, const std::string &sBigFileName)
bool isBigFileAdded (const std::string &sBigFileName)
void list (const std::string &sBigFileName, std::vector< std::string > &vAllFiles)
void remove (const std::string &sBigFileName)
void removeAll ()

Static Public Member Functions

CBigFilegetInstance ()

Private Member Functions

 CBigFile ()

Private Attributes

std::map< std::string, BNP_BNPs
CThreadFileArray _ThreadFileArray

Static Private Attributes

CBigFile_Singleton = NULL

Friends

class CThreadFileArray


Constructor & Destructor Documentation

NLMISC::CBigFile::CBigFile  )  [private]
 

Definition at line 71 of file big_file.cpp.

Referenced by getInstance().

00072 {
00073 }


Member Function Documentation

bool NLMISC::CBigFile::add const std::string &  sBigFileName,
uint32  nOptions
 

Definition at line 86 of file big_file.cpp.

References _BNPs, _ThreadFileArray, NLMISC::CBigFile::CThreadFileArray::allocate(), NLMISC::CBigFile::BNP::AlwaysOpened, NLMISC::BF_ALWAYS_OPENED, NLMISC::BF_CACHE_FILE_ON_OPEN, NLMISC::CBigFile::BNP::BigFileName, NLMISC::CBigFile::BNP::CacheFileOnOpen, NLMISC::CBigFile::CHandleFile::File, NLMISC::CBigFile::BNP::FileNames, NLMISC::CBigFile::BNP::Files, NLMISC::CBigFile::CThreadFileArray::get(), NLMISC::nlfseek64(), nlwarning, NLMISC::CBigFile::BNPFile::Pos, NLMISC::CBigFile::BNPFile::Size, NLMISC::strlwr(), NLMISC::CBigFile::BNP::ThreadFileId, uint, uint32, and uint8.

00087 {
00088         BNP bnpTmp;
00089 
00090         bnpTmp.BigFileName= sBigFileName;
00091 
00092         // Is already the same bigfile name ?
00093         string bigfilenamealone = CFile::getFilename (sBigFileName);
00094         if (_BNPs.find(bigfilenamealone) != _BNPs.end())
00095         {
00096                 nlwarning ("CBigFile::add : bigfile %s already added.", bigfilenamealone.c_str());
00097                 return false;
00098         }
00099 
00100         // Allocate a new ThreadSafe FileId for this bnp.
00101         bnpTmp.ThreadFileId= _ThreadFileArray.allocate();
00102 
00103         // Get a ThreadSafe handle on the file
00104         CHandleFile             &handle= _ThreadFileArray.get(bnpTmp.ThreadFileId);
00105         // Open the big file.
00106         handle.File = fopen (sBigFileName.c_str(), "rb");
00107         if (handle.File == NULL)
00108                 return false;
00109         uint32 nFileSize=CFile::getFileSize (handle.File);
00110         //nlfseek64 (handle.File, 0, SEEK_END);
00111         //uint32 nFileSize = ftell (handle.File);
00112 
00113         // Result
00114         if (nlfseek64 (handle.File, nFileSize-4, SEEK_SET) != 0)
00115                 return false;
00116 
00117         uint32 nOffsetFromBegining;
00118         if (fread (&nOffsetFromBegining, sizeof(uint32), 1, handle.File) != 1)
00119                 return false;
00120 
00121         if (nlfseek64 (handle.File, nOffsetFromBegining, SEEK_SET) != 0)
00122                 return false;
00123 
00124         // Read the file count
00125         uint32 nNbFile;
00126         if (fread (&nNbFile, sizeof(uint32), 1, handle.File) != 1)
00127                 return false;
00128         map<string,BNPFile> tempMap;
00129         for (uint32 i = 0; i < nNbFile; ++i)
00130         {
00131                 char FileName[256];
00132                 uint8 nStringSize;
00133                 if (fread (&nStringSize, 1, 1, handle.File) != 1)
00134                         return false;
00135                 
00136                 if (fread (FileName, 1, nStringSize, handle.File) != nStringSize)
00137                         return false;
00138 
00139                 FileName[nStringSize] = 0;
00140                 uint32 nFileSize2;
00141                 if (fread (&nFileSize2, sizeof(uint32), 1, handle.File) != 1)
00142                         return false;
00143 
00144                 uint32 nFilePos;
00145                 if (fread (&nFilePos, sizeof(uint32), 1, handle.File) != 1)
00146                         return false;
00147 
00148                 BNPFile bnpfTmp;
00149                 bnpfTmp.Pos = nFilePos;
00150                 bnpfTmp.Size = nFileSize2;
00151                 tempMap.insert (make_pair(strlwr(string(FileName)), bnpfTmp));
00152         }
00153 
00154         if (nlfseek64 (handle.File, 0, SEEK_SET) != 0)
00155                 return false;
00156 
00157         // Convert temp map
00158         if (nNbFile > 0)
00159         {
00160                 uint nSize = 0, nNb = 0;
00161                 map<string,BNPFile>::iterator it = tempMap.begin();
00162                 while (it != tempMap.end())
00163                 {
00164                         nSize += it->first.size() + 1;
00165                         nNb++;
00166                         it++;
00167                 }
00168 
00169                 bnpTmp.FileNames = new char[nSize];
00170                 memset(bnpTmp.FileNames, 0, nSize);
00171                 bnpTmp.Files.resize(nNb);
00172 
00173                 it = tempMap.begin();
00174                 nSize = 0;
00175                 nNb = 0;
00176                 while (it != tempMap.end())
00177                 {
00178                         strcpy(bnpTmp.FileNames+nSize, it->first.c_str());
00179                         
00180                         bnpTmp.Files[nNb].Name = bnpTmp.FileNames+nSize;
00181                         bnpTmp.Files[nNb].Size = it->second.Size;
00182                         bnpTmp.Files[nNb].Pos = it->second.Pos;
00183 
00184                         nSize += it->first.size() + 1;
00185                         nNb++;
00186                         it++;
00187                 }
00188         }
00189         // End of temp map conversion
00190 
00191         if (nOptions&BF_CACHE_FILE_ON_OPEN)
00192                 bnpTmp.CacheFileOnOpen = true;
00193         else
00194                 bnpTmp.CacheFileOnOpen = false;
00195 
00196         if (!(nOptions&BF_ALWAYS_OPENED))
00197         {
00198                 fclose (handle.File);
00199                 handle.File = NULL;
00200                 bnpTmp.AlwaysOpened = false;
00201         }
00202         else
00203         {
00204                 bnpTmp.AlwaysOpened = true;
00205         }
00206 
00207         _BNPs.insert (make_pair(strlwr(bigfilenamealone), bnpTmp));
00208 
00209         return true;
00210 }

FILE * NLMISC::CBigFile::getFile const std::string &  sFileName,
uint32 rFileSize,
uint32 rBigFileOffset,
bool &  rCacheFileOnOpen,
bool &  rAlwaysOpened
 

Definition at line 273 of file big_file.cpp.

References _BNPs, _ThreadFileArray, NLMISC::CBigFile::BNP::AlwaysOpened, NLMISC::CBigFile::BNP::BigFileName, NLMISC::CBigFile::BNP::CacheFileOnOpen, NLMISC::CBigFile::CHandleFile::File, NLMISC::CBigFile::BNP::Files, NLMISC::CBigFile::CThreadFileArray::get(), nlwarning, NLMISC::CBigFile::BNPFile::Pos, NLMISC::CBigFile::BNPFile::Size, NLMISC::strlwr(), NLMISC::CBigFile::BNP::ThreadFileId, and uint32.

00275 {
00276         string zeFileName, zeBigFileName, lwrFileName = strlwr (sFileName);
00277         uint32 i, nPos = sFileName.find ('@');
00278         if (nPos == string::npos)
00279         {
00280                 nlwarning ("BF: Couldn't load '%s'", sFileName.c_str());
00281                 return NULL;
00282         }
00283 
00284         for (i = 0; i < nPos; ++i)
00285                 zeBigFileName += lwrFileName[i];
00286         ++i; // Skip @
00287         for (; i < lwrFileName.size(); ++i)
00288                 zeFileName += lwrFileName[i];
00289 
00290         if (_BNPs.find (zeBigFileName) == _BNPs.end())
00291         {
00292                 nlwarning ("BF: Couldn't load '%s'", sFileName.c_str());
00293                 return NULL;
00294         }
00295 
00296         BNP &rbnp = _BNPs.find (zeBigFileName)->second;
00297         if (rbnp.Files.size() == 0)
00298         {
00299                 nlwarning ("BF: Couldn't load '%s'", sFileName.c_str());
00300                 return NULL;
00301         }
00302 
00303         vector<BNPFile>::iterator itNBPFile;
00304         itNBPFile = lower_bound(rbnp.Files.begin(), rbnp.Files.end(), zeFileName.c_str(), CBNPFileComp());
00305         if (itNBPFile != rbnp.Files.end())
00306         {
00307                 if (strcmp(itNBPFile->Name, zeFileName.c_str()) != 0)
00308                 {
00309                         nlwarning ("BF: Couldn't load '%s'", sFileName.c_str());
00310                         return NULL;
00311                 }
00312         }
00313         else
00314         {
00315                 nlwarning ("BF: Couldn't load '%s'", sFileName.c_str());
00316                 return NULL;
00317         }
00318 
00319         BNPFile &rbnpfile = *itNBPFile;
00320 
00321         // Get a ThreadSafe handle on the file
00322         CHandleFile             &handle= _ThreadFileArray.get(rbnp.ThreadFileId);
00323         /* If not opened, open it now. There is 2 reason for it to be not opened: 
00324                 rbnp.AlwaysOpened==false, or it is a new thread which use it for the first time.
00325         */
00326         if(handle.File== NULL)
00327         {
00328                 handle.File = fopen (rbnp.BigFileName.c_str(), "rb");
00329                 if (handle.File == NULL)
00330                         return NULL;
00331         }
00332 
00333         rCacheFileOnOpen = rbnp.CacheFileOnOpen;
00334         rAlwaysOpened = rbnp.AlwaysOpened;
00335         rBigFileOffset = rbnpfile.Pos;
00336         rFileSize = rbnpfile.Size;
00337         return handle.File;
00338 }

char * NLMISC::CBigFile::getFileNamePtr const std::string &  sFileName,
const std::string &  sBigFileName
 

Definition at line 341 of file big_file.cpp.

References _BNPs, NLMISC::CBigFile::BNP::Files, and NLMISC::strlwr().

00342 {
00343         string bigfilenamealone = CFile::getFilename (sBigFileName);
00344         if (_BNPs.find(bigfilenamealone) != _BNPs.end())
00345         {
00346                 BNP &rbnp = _BNPs.find (bigfilenamealone)->second;
00347                 vector<BNPFile>::iterator itNBPFile;
00348                 if (rbnp.Files.size() == 0)
00349                         return NULL;
00350                 string lwrFileName = strlwr (sFileName);
00351                 itNBPFile = lower_bound(rbnp.Files.begin(), rbnp.Files.end(), lwrFileName.c_str(), CBNPFileComp());
00352                 if (itNBPFile != rbnp.Files.end())
00353                 {
00354                         if (strcmp(itNBPFile->Name, lwrFileName.c_str()) == 0)
00355                         {
00356                                 return itNBPFile->Name;
00357                         }
00358                 }
00359         }
00360 
00361         return NULL;
00362 }

CBigFile & NLMISC::CBigFile::getInstance  )  [static]
 

Definition at line 76 of file big_file.cpp.

References CBigFile().

00077 {
00078         if (_Singleton == NULL)
00079         {
00080                 _Singleton = new CBigFile();
00081         }
00082         return *_Singleton;
00083 }

bool NLMISC::CBigFile::isBigFileAdded const std::string &  sBigFileName  ) 
 

Definition at line 240 of file big_file.cpp.

References _BNPs.

00241 {
00242         // Is already the same bigfile name ?
00243         string bigfilenamealone = CFile::getFilename (sBigFileName);
00244         return _BNPs.find(bigfilenamealone) != _BNPs.end();
00245 }

void NLMISC::CBigFile::list const std::string &  sBigFileName,
std::vector< std::string > &  vAllFiles
 

Definition at line 248 of file big_file.cpp.

References _BNPs, NLMISC::CBigFile::BNP::Files, and NLMISC::strlwr().

00249 {
00250         string lwrFileName = strlwr (sBigFileName);
00251         if (_BNPs.find (lwrFileName) == _BNPs.end())
00252                 return;
00253         vAllFiles.clear ();
00254         BNP &rbnp = _BNPs.find (lwrFileName)->second;
00255         vector<BNPFile>::iterator it = rbnp.Files.begin();
00256         while (it != rbnp.Files.end())
00257         {
00258                 vAllFiles.push_back (string(it->Name)); // Add the name of the file to the return vector
00259                 ++it;
00260         }
00261 }

void NLMISC::CBigFile::remove const std::string &  sBigFileName  ) 
 

Definition at line 213 of file big_file.cpp.

References _BNPs, _ThreadFileArray, NLMISC::CBigFile::CHandleFile::File, NLMISC::CBigFile::BNP::FileNames, NLMISC::CBigFile::CThreadFileArray::get(), and NLMISC::CBigFile::BNP::ThreadFileId.

Referenced by removeAll().

00214 {
00215         if (_BNPs.find (sBigFileName) != _BNPs.end())
00216         {
00217                 map<string, BNP>::iterator it = _BNPs.find (sBigFileName);
00218                 BNP &rbnp = it->second;
00219                 /* \todo yoyo: THERE is a MAJOR drawback here: Only the FILE * of the current (surely main) thread
00220                         is closed. other FILE* in other threads are still opened. This is not a big issue (system close the FILE* 
00221                         at the end of the process) and this is important so AsyncLoading of a currentTask can end up correclty 
00222                         (without an intermediate fclose()).
00223                 */
00224                 // Get a ThreadSafe handle on the file
00225                 CHandleFile             &handle= _ThreadFileArray.get(rbnp.ThreadFileId);
00226                 // close it if needed
00227                 if (handle.File != NULL)
00228                 {
00229                         fclose (handle.File);
00230                         handle.File= NULL;
00231                 }
00232                 /* \todo trap : can make the CPath crash. CPath must be informed that the files in bigfiles have been removed
00233                         this is because CPath use memory of CBigFile if it runs in memoryCompressed mode */
00234                 delete [] rbnp.FileNames;
00235                 _BNPs.erase (it);
00236         }
00237 }

void NLMISC::CBigFile::removeAll  ) 
 

Definition at line 264 of file big_file.cpp.

References _BNPs, and remove().

00265 {
00266         while (_BNPs.begin() != _BNPs.end())
00267         {
00268                 remove (_BNPs.begin()->first);
00269         }
00270 }


Friends And Related Function Documentation

friend class CThreadFileArray [friend]
 

Definition at line 79 of file big_file.h.


Field Documentation

std::map<std::string, BNP> NLMISC::CBigFile::_BNPs [private]
 

Definition at line 153 of file big_file.h.

Referenced by add(), getFile(), getFileNamePtr(), isBigFileAdded(), list(), remove(), and removeAll().

CBigFile * NLMISC::CBigFile::_Singleton = NULL [static, private]
 

Definition at line 36 of file big_file.cpp.

CThreadFileArray NLMISC::CBigFile::_ThreadFileArray [private]
 

Definition at line 151 of file big_file.h.

Referenced by add(), getFile(), and remove().


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 13:02:12 2004 for NeL by doxygen 1.3.6