00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "stdmisc.h"
00029
00030 #include "nel/misc/file.h"
00031 #include "nel/misc/path.h"
00032
00033 #include "nel/misc/sheet_id.h"
00034 #include "nel/misc/common.h"
00035 #include "nel/misc/hierarchical_timer.h"
00036
00037 using namespace std;
00038
00039 namespace NLMISC {
00040
00041 CSheetId::CChar CSheetId::_AllStrings;
00042 CStaticMap<uint32,CSheetId::CChar> CSheetId::_SheetIdToName;
00043 CStaticMap<CSheetId::CChar,uint32, CSheetId::CCharComp> CSheetId::_SheetNameToId;
00044
00045
00046 vector<std::string> CSheetId::_FileExtensions;
00047 bool CSheetId::_Initialised=false;
00048 bool CSheetId::_RemoveUnknownSheet=true;
00049 bool CSheetId::_DontHaveSheetKnowledge = false;
00050
00051 const CSheetId CSheetId::Unknown(0);
00052
00053 void CSheetId::cbFileChange (const std::string &filename)
00054 {
00055 nlinfo ("SHEETID: %s changed, reload it", filename.c_str());
00056
00057 loadSheetId();
00058 }
00059
00060
00061
00062
00063
00064 CSheetId::CSheetId( uint32 sheetRef)
00065 {
00066 _Id.Id = sheetRef;
00067
00068 #ifdef NL_DEBUG_SHEET_ID
00069
00070
00071 if(sheetRef)
00072 {
00073 CStaticMap<uint32, CChar>::iterator it(_SheetIdToName.find(sheetRef));
00074 if (it != _SheetIdToName.end())
00075 {
00076 _DebugSheetName = it->second.Ptr;
00077 }
00078 else
00079 _DebugSheetName = NULL;
00080 }
00081 else
00082 {
00083 _DebugSheetName = NULL;
00084 }
00085 #endif
00086 }
00087
00088
00089
00090
00091
00092
00093 CSheetId::CSheetId( const string& sheetName )
00094 {
00095 if (!buildSheetId(sheetName))
00096 {
00097 if(sheetName.empty())
00098 nlwarning("SHEETID: Try to create an CSheetId with empty name. TODO: check why.");
00099 else
00100 nlwarning("SHEETID: The sheet '%s' is not in sheet_id.bin, setting it to Unknown",sheetName.c_str());
00101
00102
00103
00104
00105
00106
00107
00108 *this = Unknown;
00109 }
00110
00111 }
00112
00113
00114
00115
00116
00117
00118 bool CSheetId::buildSheetId(const std::string& sheetName)
00119 {
00120 nlassert(_Initialised);
00121 nlassert(!_DontHaveSheetKnowledge);
00122
00123
00124 CStaticMap<CChar,uint32,CCharComp>::const_iterator itId;
00125 CChar c;
00126 c.Ptr = new char [sheetName.size()+1];
00127 strcpy(c.Ptr, sheetName.c_str());
00128 toLower(c.Ptr);
00129
00130 itId = _SheetNameToId.find (c);
00131 delete [] c.Ptr;
00132 if( itId != _SheetNameToId.end() )
00133 {
00134 _Id.Id = itId->second;
00135 #ifdef NL_DEBUG_SHEET_ID
00136
00137 _DebugSheetName = itId->first.Ptr;
00138 #endif
00139 return true;
00140 }
00141
00142
00143 if (sheetName.size()>1 && sheetName[0]=='#')
00144 {
00145 uint32 numericId;
00146 NLMISC::fromString((const char*)(sheetName.c_str()+1), numericId);
00147 if (NLMISC::toString("#%u",numericId)==sheetName)
00148 {
00149 _Id.Id= numericId;
00150 return true;
00151 }
00152 }
00153 return false;
00154 }
00155
00156 void CSheetId::loadSheetId ()
00157 {
00158 H_AUTO(CSheetIdInit);
00159 nldebug("Loading sheet_id.bin");
00160
00161
00162 CIFile file;
00163 std::string path = CPath::lookup("sheet_id.bin", false, false);
00164 if(!path.empty() && file.open(path))
00165 {
00166
00167 _FileExtensions.clear ();
00168 _SheetIdToName.clear ();
00169 _SheetNameToId.clear ();
00170
00171
00172 _FileExtensions.resize(1 << (NL_SHEET_ID_TYPE_BITS));
00173
00174
00175 map<uint32,string> tempMap;
00176 contReset(tempMap);
00177 file.serialCont(tempMap);
00178 file.close();
00179
00180 if (_RemoveUnknownSheet)
00181 {
00182 uint32 removednbfiles = 0;
00183 uint32 nbfiles = tempMap.size();
00184
00185
00186 map<uint32,string>::iterator itStr2;
00187 for( itStr2 = tempMap.begin(); itStr2 != tempMap.end(); )
00188 {
00189 if (CPath::exists ((*itStr2).second))
00190 {
00191 ++itStr2;
00192 }
00193 else
00194 {
00195 map<uint32,string>::iterator olditStr = itStr2;
00196
00197 itStr2++;
00198 tempMap.erase (olditStr);
00199 removednbfiles++;
00200 }
00201 }
00202 nlinfo ("SHEETID: Removed %d files on %d from CSheetId because these files doesn't exists", removednbfiles, nbfiles);
00203 }
00204
00205
00206 {
00207
00208 vector<CChar> tempVec;
00209 uint32 nNb = 0;
00210 uint32 nSize = 0;
00211 map<uint32,string>::const_iterator it = tempMap.begin();
00212 while (it != tempMap.end())
00213 {
00214 nSize += it->second.size()+1;
00215 nNb++;
00216 it++;
00217 }
00218
00219
00220 tempVec.resize(nNb);
00221 _AllStrings.Ptr = new char[nSize];
00222 it = tempMap.begin();
00223 nSize = 0;
00224 nNb = 0;
00225 while (it != tempMap.end())
00226 {
00227 tempVec[nNb].Ptr = _AllStrings.Ptr+nSize;
00228 strcpy(_AllStrings.Ptr+nSize, it->second.c_str());
00229 toLower(_AllStrings.Ptr+nSize);
00230 nSize += it->second.size()+1;
00231 nNb++;
00232 it++;
00233 }
00234
00235
00236 _SheetIdToName.reserve(tempVec.size());
00237 it = tempMap.begin();
00238 nNb = 0;
00239 while (it != tempMap.end())
00240 {
00241 _SheetIdToName.add(pair<uint32, CChar>::pair(it->first, CChar(tempVec[nNb])));
00242
00243 nNb++;
00244 it++;
00245 }
00246
00247
00248
00249 }
00250
00251
00252 {
00253 uint32 nSize = _SheetIdToName.size();
00254 _SheetNameToId.reserve(nSize);
00255 CStaticMap<uint32,CChar>::iterator itStr;
00256 for( itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr )
00257 {
00258
00259 _SheetNameToId.add( make_pair((*itStr).second, (*itStr).first) );
00260
00261
00262 TSheetId sheetId;
00263 sheetId.Id=(*itStr).first;
00264 uint32 type = sheetId.IdInfos.Type;
00265
00266
00267 if (_FileExtensions[type].empty())
00268 {
00269
00270 _FileExtensions[type] = toLower(CFile::getExtension((*itStr).second.Ptr));
00271 }
00272 nSize--;
00273 }
00274 _SheetNameToId.endAdd();
00275 }
00276 }
00277 else
00278 {
00279 nlerror("<CSheetId::init> Can't open the file sheet_id.bin");
00280 }
00281 nldebug("Finished loading sheet_id.bin: %u entries read",_SheetIdToName.size());
00282 }
00283
00284
00285
00286
00287
00288
00289 void CSheetId::init(bool removeUnknownSheet)
00290 {
00291
00292 if (_Initialised)
00293 return;
00294
00295
00296
00297 _RemoveUnknownSheet = removeUnknownSheet;
00298
00299 loadSheetId ();
00300 _Initialised=true;
00301
00302
00303 }
00304
00305 void CSheetId::initWithoutSheet()
00306 {
00307 _Initialised = true;
00308 _DontHaveSheetKnowledge = true;
00309 }
00310
00311
00312
00313
00314
00315
00316
00317 void CSheetId::uninit()
00318 {
00319 delete [] _AllStrings.Ptr;
00320 }
00321
00322
00323
00324
00325
00326 CSheetId& CSheetId::operator=( const CSheetId& sheetId )
00327 {
00328 if (!_Initialised) init(false);
00329
00330 if(this == &sheetId)
00331 {
00332 return *this;
00333 }
00334
00335 _Id.Id = sheetId.asInt();
00336
00337 #ifdef NL_DEBUG_SHEET_ID
00338 _DebugSheetName = sheetId._DebugSheetName;
00339 #endif
00340
00341 return *this;
00342
00343
00344 }
00345
00346
00347
00348
00349
00350
00351 CSheetId& CSheetId::operator=( const string& sheetName )
00352 {
00353 nlassert(_Initialised);
00354 nlassert(!_DontHaveSheetKnowledge);
00355
00356 CStaticMap<CChar,uint32,CCharComp>::const_iterator itId;
00357 CChar c;
00358 c.Ptr = new char [sheetName.size()+1];
00359 strcpy(c.Ptr, sheetName.c_str());
00360 toLower(c.Ptr);
00361
00362 itId = _SheetNameToId.find (c);
00363 delete [] c.Ptr;
00364 if( itId != _SheetNameToId.end() )
00365 {
00366 _Id.Id = (*itId).second;
00367 return *this;
00368 }
00369 *this = Unknown;
00370 return *this;
00371
00372 }
00373
00374
00375
00376
00377
00378
00379 CSheetId& CSheetId::operator=( uint32 sheetRef )
00380 {
00381 if (!_Initialised) init(false);
00382
00383 _Id.Id = sheetRef;
00384
00385 return *this;
00386
00387 }
00388
00389
00390
00391
00392
00393
00394
00395 bool CSheetId::operator < (const CSheetId& sheetRef ) const
00396 {
00397 if (!_Initialised) init(false);
00398
00399 if (_Id.Id < sheetRef.asInt())
00400 {
00401 return true;
00402 }
00403
00404 return false;
00405
00406 }
00407
00408
00409
00410
00411
00412
00413
00414 string CSheetId::toString(bool ifNotFoundUseNumericId) const
00415 {
00416 if (!_Initialised) init(false);
00417
00418 CStaticMap<uint32,CChar>::const_iterator itStr = _SheetIdToName.find (_Id.Id);
00419 if( itStr != _SheetIdToName.end() )
00420 {
00421 return string((*itStr).second.Ptr);
00422 }
00423 else
00424 {
00425
00426
00427
00428 if (ifNotFoundUseNumericId)
00429 {
00430 return NLMISC::toString( "#%u", _Id.Id );
00431 }
00432 else
00433 {
00434 return NLMISC::toString( "<Sheet %d not found in sheet_id.bin>", _Id.Id );
00435 }
00436 }
00437
00438 }
00439
00440 void CSheetId::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00441 {
00442 f.serial( _Id.Id );
00443
00444 #ifdef NL_DEBUG_SHEET_ID
00445 CStaticMap<uint32, CChar>::iterator it(_SheetIdToName.find(_Id.Id));
00446 if (it != _SheetIdToName.end())
00447 _DebugSheetName = it->second.Ptr;
00448 else
00449 _DebugSheetName = NULL;
00450 #endif
00451 }
00452
00453
00454
00455
00456
00457
00458
00459 void CSheetId::display()
00460 {
00461 if (!_Initialised) init(false);
00462
00463 CStaticMap<uint32,CChar>::const_iterator itStr;
00464 for( itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr )
00465 {
00466
00467 nlinfo("SHEETID: (%08x %d) %s",(*itStr).first,(*itStr).first,(*itStr).second.Ptr);
00468 }
00469
00470 }
00471
00472
00473
00474
00475
00476
00477
00478 void CSheetId::display(uint32 type)
00479 {
00480 if (!_Initialised) init(false);
00481
00482 CStaticMap<uint32,CChar>::const_iterator itStr;
00483 for( itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr )
00484 {
00485
00486 TSheetId sheetId;
00487 sheetId.Id=(*itStr).first;
00488
00489
00490 if (type==sheetId.IdInfos.Type)
00491 {
00492
00493 nlinfo("SHEETID: (%08x %d) %s",(*itStr).first,(*itStr).first,(*itStr).second.Ptr);
00494 }
00495 }
00496
00497 }
00498
00499
00500
00501
00502
00503
00504
00505 void CSheetId::buildIdVector(std::vector <CSheetId> &result)
00506 {
00507 if (!_Initialised) init(false);
00508
00509 CStaticMap<uint32,CChar>::const_iterator itStr;
00510 for( itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr )
00511 {
00512 result.push_back( (CSheetId)(*itStr).first );
00513 }
00514
00515 }
00516
00517
00518
00519
00520
00521
00522 void CSheetId::buildIdVector(std::vector <CSheetId> &result, uint32 type)
00523 {
00524 if (!_Initialised) init(false);
00525 nlassert(type < (1 << (NL_SHEET_ID_TYPE_BITS)));
00526
00527 CStaticMap<uint32,CChar>::const_iterator itStr;
00528 for( itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr )
00529 {
00530
00531 TSheetId sheetId;
00532 sheetId.Id=(*itStr).first;
00533
00534
00535 if (type==sheetId.IdInfos.Type)
00536 {
00537 result.push_back( (CSheetId)sheetId.Id );
00538 }
00539 }
00540
00541 }
00542
00543
00544
00545
00546
00547 void CSheetId::buildIdVector(std::vector <CSheetId> &result, std::vector <std::string> &resultFilenames,uint32 type)
00548 {
00549 if (!_Initialised) init(false);
00550 nlassert(type < (1 << (NL_SHEET_ID_TYPE_BITS)));
00551
00552 CStaticMap<uint32,CChar>::const_iterator itStr;
00553 for( itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr )
00554 {
00555
00556 TSheetId sheetId;
00557 sheetId.Id=(*itStr).first;
00558
00559
00560 if (type==sheetId.IdInfos.Type)
00561 {
00562 result.push_back( (CSheetId)sheetId.Id );
00563 resultFilenames.push_back( (*itStr).second.Ptr );
00564 }
00565 }
00566
00567 }
00568
00569
00570
00571
00572
00573 void CSheetId::buildIdVector(std::vector <CSheetId> &result,const std::string &fileExtension)
00574 {
00575 uint32 type=typeFromFileExtension(fileExtension);
00576 if (type!=(uint32)~0)
00577 buildIdVector(result, type);
00578
00579 }
00580
00581
00582
00583
00584
00585 void CSheetId::buildIdVector(std::vector <CSheetId> &result, std::vector <std::string> &resultFilenames,const std::string &fileExtension)
00586 {
00587 uint32 type=typeFromFileExtension(fileExtension);
00588 if (type != (uint32)~0)
00589 buildIdVector(result,resultFilenames, type);
00590
00591 }
00592
00593
00594
00595
00596
00597
00598 uint32 CSheetId::typeFromFileExtension(const std::string &fileExtension)
00599 {
00600 if (!_Initialised) init(false);
00601
00602 unsigned i;
00603 for (i=0;i<_FileExtensions.size();i++)
00604 if (toLower(fileExtension)==_FileExtensions[i])
00605 return i;
00606
00607 return ~0;
00608 }
00609
00610
00611
00612
00613
00614
00615 const std::string &CSheetId::fileExtensionFromType(uint32 type)
00616 {
00617 if (!_Initialised) init(false);
00618 nlassert(type < (1<<(NL_SHEET_ID_TYPE_BITS)));
00619
00620 return _FileExtensions[type];
00621
00622 }
00623
00624
00625
00626
00627
00628 void CSheetId::buildSheetId(uint32 shortId, uint32 type)
00629 {
00630 nlassert(shortId < (1<<NL_SHEET_ID_ID_BITS));
00631 nlassert(type < (1<<(NL_SHEET_ID_TYPE_BITS)));
00632
00633 _Id.IdInfos.Id= shortId;
00634 _Id.IdInfos.Type= type;
00635
00636 #ifdef NL_DEBUG_SHEET_ID
00637 CStaticMap<uint32, CChar>::iterator it(_SheetIdToName.find(_Id.Id));
00638 if (it != _SheetIdToName.end())
00639 {
00640 _DebugSheetName = it->second.Ptr;
00641 }
00642 else
00643 _DebugSheetName = NULL;
00644 #endif
00645
00646 }
00647
00648 }