mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-11-22 18:30:27 +01:00
197 lines
4.8 KiB
C++
197 lines
4.8 KiB
C++
/* Copyright (c) 2002-2012 Croteam Ltd.
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of version 2 of the GNU General Public License as published by
|
|
the Free Software Foundation
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
|
|
|
|
#include "Engine/StdH.h"
|
|
|
|
#include <Engine/Base/CRCTable.h>
|
|
#include <Engine/Base/FileName.h>
|
|
#include <Engine/Base/Stream.h>
|
|
#include <Engine/Base/Console.h>
|
|
#include <Engine/Base/CRC.h>
|
|
#include <Engine/Templates/DynamicStackArray.cpp>
|
|
|
|
extern INDEX net_bReportCRC;
|
|
|
|
class CCRCEntry {
|
|
public:
|
|
CTFileName ce_fnmFile; // the file that CRC is for
|
|
ULONG ce_ulCRC; // CRC of the file
|
|
BOOL ce_bActive; // set if the file is now active for CRC checking
|
|
|
|
// filename is its name (used for storing in nametable)
|
|
inline const CTFileName &GetName(void) { return ce_fnmFile; };
|
|
void Clear(void)
|
|
{
|
|
ce_fnmFile.Clear();
|
|
ce_ulCRC = 0;
|
|
ce_bActive = FALSE;
|
|
}
|
|
};
|
|
|
|
extern CDynamicStackArray<CTFileName> _afnmNoCRC;
|
|
extern BOOL FileMatchesList(CDynamicStackArray<CTFileName> &afnm, const CTFileName &fnm);
|
|
|
|
#define TYPE CCRCEntry
|
|
#define CNameTable_TYPE CNameTable_CCRCEntry
|
|
#define CNameTableSlot_TYPE CNameTableSlot_CCRCEntry
|
|
#include <Engine/Templates/NameTable.h>
|
|
#include <Engine/Templates/NameTable.cpp>
|
|
#undef CNameTableSlot_TYPE
|
|
#undef CNameTable_TYPE
|
|
#undef TYPE
|
|
|
|
static CDynamicStackArray<CCRCEntry> _aceEntries;
|
|
static CNameTable_CCRCEntry _ntEntries;
|
|
|
|
BOOL CRCT_bGatherCRCs = FALSE; // set while gathering CRCs of all loaded files
|
|
|
|
// init CRC table
|
|
void CRCT_Init(void)
|
|
{
|
|
_ntEntries.SetAllocationParameters(50, 10, 10);
|
|
}
|
|
|
|
// check if a file is added
|
|
BOOL CRCT_IsFileAdded(const CTFileName &fnm)
|
|
{
|
|
return _ntEntries.Find(fnm)!=NULL;
|
|
}
|
|
|
|
// add one file to active list and get its crc
|
|
void CRCT_AddFile_t(const CTFileName &fnm, ULONG ulCRC/*=0*/) // throw char *
|
|
{
|
|
// if not gathering CRCs now
|
|
if (!CRCT_bGatherCRCs) {
|
|
// do nothing
|
|
return;
|
|
}
|
|
|
|
// try to find it in table
|
|
CCRCEntry *pce = _ntEntries.Find(fnm);
|
|
|
|
BOOL bNew = FALSE;
|
|
// if found
|
|
if (pce!=NULL) {
|
|
// just activate it
|
|
bNew = !pce->ce_bActive;
|
|
pce->ce_bActive = TRUE;
|
|
// if crc is given
|
|
if (ulCRC!=0) {
|
|
// force it
|
|
pce->ce_ulCRC = ulCRC;
|
|
}
|
|
// if not found
|
|
} else {
|
|
// calculate checksum
|
|
if (ulCRC==0) {
|
|
|
|
if (FileMatchesList(_afnmNoCRC, fnm)) {
|
|
ulCRC = 0x12345678;
|
|
} else {
|
|
ulCRC = GetFileCRC32_t(fnm);
|
|
}
|
|
}
|
|
// add to the table
|
|
pce = &_aceEntries.Push();
|
|
pce->ce_fnmFile = fnm;
|
|
pce->ce_ulCRC = ulCRC;
|
|
pce->ce_bActive = TRUE;
|
|
_ntEntries.Add(pce);
|
|
bNew = TRUE;
|
|
}
|
|
if (bNew && net_bReportCRC) {
|
|
CPrintF("CRC %08x: '%s'\n", pce->ce_ulCRC, (const char*)pce->ce_fnmFile);
|
|
}
|
|
}
|
|
|
|
// free all memory used by the crc cache
|
|
void CRCT_Clear(void)
|
|
{
|
|
_ntEntries.Clear();
|
|
_aceEntries.Clear();
|
|
}
|
|
|
|
// reset all files to not active
|
|
void CRCT_ResetActiveList(void)
|
|
{
|
|
for(INDEX ice=0; ice<_aceEntries.Count(); ice++) {
|
|
_aceEntries[ice].ce_bActive = FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
static INDEX GetNumberOfActiveEntries(void)
|
|
{
|
|
INDEX ctActive = 0;
|
|
for(INDEX ice=0; ice<_aceEntries.Count(); ice++) {
|
|
if (_aceEntries[ice].ce_bActive) {
|
|
ctActive++;
|
|
}
|
|
}
|
|
return ctActive;
|
|
}
|
|
|
|
// dump list of all active files to the stream
|
|
void CRCT_MakeFileList_t(CTStream &strmFiles) // throw char *
|
|
{
|
|
// save number of active entries
|
|
INDEX ctActive = GetNumberOfActiveEntries();
|
|
strmFiles<<ctActive;
|
|
// for each active entry
|
|
for(INDEX ice=0; ice<_aceEntries.Count(); ice++) {
|
|
CCRCEntry &ce = _aceEntries[ice];
|
|
if (!ce.ce_bActive) {
|
|
continue;
|
|
}
|
|
// save name to stream
|
|
strmFiles<<(CTString&)ce.ce_fnmFile;
|
|
}
|
|
}
|
|
|
|
// dump checksums for all files from the list
|
|
ULONG CRCT_MakeCRCForFiles_t(CTStream &strmFiles) // throw char *
|
|
{
|
|
BOOL bOld = CRCT_bGatherCRCs;
|
|
CRCT_bGatherCRCs = TRUE;
|
|
|
|
ULONG ulCRC;
|
|
CRC_Start(ulCRC);
|
|
// read number of active files
|
|
INDEX ctFiles;
|
|
strmFiles>>ctFiles;
|
|
// for each one
|
|
for(INDEX i=0; i<ctFiles; i++) {
|
|
// read the name
|
|
CTString strName;
|
|
strmFiles>>strName;
|
|
CTFileName fname = strName;
|
|
// try to find it in table
|
|
CCRCEntry *pce = _ntEntries.Find(fname);
|
|
// if not there
|
|
if (pce==NULL) {
|
|
CRCT_AddFile_t(fname);
|
|
// add it now
|
|
pce = _ntEntries.Find(fname);
|
|
}
|
|
// add the crc
|
|
CRC_AddLONG(ulCRC, pce->ce_ulCRC);
|
|
}
|
|
CRCT_bGatherCRCs = bOld;
|
|
CRC_Finish(ulCRC);
|
|
return ulCRC;
|
|
}
|
|
|
|
|