/* 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 #include #include #include #include #include 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 _afnmNoCRC; extern BOOL FileMatchesList(CDynamicStackArray &afnm, const CTFileName &fnm); #define TYPE CCRCEntry #define CNameTable_TYPE CNameTable_CCRCEntry #define CNameTableSlot_TYPE CNameTableSlot_CCRCEntry #include #include #undef CNameTableSlot_TYPE #undef CNameTable_TYPE #undef TYPE static CDynamicStackArray _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<>ctFiles; // for each one for(INDEX i=0; i>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; }