CRCTable.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /* Copyright (c) 2002-2012 Croteam Ltd.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of version 2 of the GNU General Public License as published by
  4. the Free Software Foundation
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along
  10. with this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
  12. #include "StdH.h"
  13. #include <Engine/Base/CRCTable.h>
  14. #include <Engine/Base/FileName.h>
  15. #include <Engine/Base/Stream.h>
  16. #include <Engine/Base/Console.h>
  17. #include <Engine/Base/CRC.h>
  18. #include <Engine/Templates/DynamicStackArray.cpp>
  19. extern INDEX net_bReportCRC;
  20. class CCRCEntry {
  21. public:
  22. CTFileName ce_fnmFile; // the file that CRC is for
  23. ULONG ce_ulCRC; // CRC of the file
  24. BOOL ce_bActive; // set if the file is now active for CRC checking
  25. // filename is its name (used for storing in nametable)
  26. inline const CTFileName &GetName(void) { return ce_fnmFile; };
  27. void Clear(void)
  28. {
  29. ce_fnmFile.Clear();
  30. ce_ulCRC = 0;
  31. ce_bActive = FALSE;
  32. }
  33. };
  34. extern CDynamicStackArray<CTFileName> _afnmNoCRC;
  35. extern BOOL FileMatchesList(CDynamicStackArray<CTFileName> &afnm, const CTFileName &fnm);
  36. #ifndef SE_INCL_CRCTABLE_CPP
  37. #define SE_INCL_CRCTABLE_CPP
  38. #ifdef PRAGMA_ONCE
  39. #pragma once
  40. #endif
  41. #define TYPE CCRCEntry
  42. #define CNameTable_TYPE CNameTable_CCRCEntry
  43. #define CNameTableSlot_TYPE CNameTableSlot_CCRCEntry
  44. #include <Engine/Templates/NameTable.h>
  45. #include <Engine/Templates/NameTable.cpp>
  46. #undef CNameTableSlot_TYPE
  47. #undef CNameTable_TYPE
  48. #undef TYPE
  49. static CDynamicStackArray<CCRCEntry> _aceEntries;
  50. static CNameTable_CCRCEntry _ntEntries;
  51. extern BOOL CRCT_bGatherCRCs = FALSE; // set while gathering CRCs of all loaded files
  52. // init CRC table
  53. void CRCT_Init(void)
  54. {
  55. _ntEntries.SetAllocationParameters(50, 10, 10);
  56. }
  57. // check if a file is added
  58. BOOL CRCT_IsFileAdded(const CTFileName &fnm)
  59. {
  60. return _ntEntries.Find(fnm)!=NULL;
  61. }
  62. // add one file to active list and get its crc
  63. void CRCT_AddFile_t(const CTFileName &fnm, ULONG ulCRC/*=0*/) // throw char *
  64. {
  65. // if not gathering CRCs now
  66. if (!CRCT_bGatherCRCs) {
  67. // do nothing
  68. return;
  69. }
  70. // try to find it in table
  71. CCRCEntry *pce = _ntEntries.Find(fnm);
  72. BOOL bNew = FALSE;
  73. // if found
  74. if (pce!=NULL) {
  75. // just activate it
  76. bNew = !pce->ce_bActive;
  77. pce->ce_bActive = TRUE;
  78. // if crc is given
  79. if (ulCRC!=0) {
  80. // force it
  81. pce->ce_ulCRC = ulCRC;
  82. }
  83. // if not found
  84. } else {
  85. // calculate checksum
  86. if (ulCRC==0) {
  87. if (FileMatchesList(_afnmNoCRC, fnm)) {
  88. ulCRC = 0x12345678;
  89. } else {
  90. ulCRC = GetFileCRC32_t(fnm);
  91. }
  92. }
  93. // add to the table
  94. pce = &_aceEntries.Push();
  95. pce->ce_fnmFile = fnm;
  96. pce->ce_ulCRC = ulCRC;
  97. pce->ce_bActive = TRUE;
  98. _ntEntries.Add(pce);
  99. bNew = TRUE;
  100. }
  101. if (bNew && net_bReportCRC) {
  102. CPrintF("CRC %08x: '%s'\n", pce->ce_ulCRC, (const char*)pce->ce_fnmFile);
  103. }
  104. }
  105. // free all memory used by the crc cache
  106. void CRCT_Clear(void)
  107. {
  108. _ntEntries.Clear();
  109. _aceEntries.Clear();
  110. }
  111. // reset all files to not active
  112. void CRCT_ResetActiveList(void)
  113. {
  114. for(INDEX ice=0; ice<_aceEntries.Count(); ice++) {
  115. _aceEntries[ice].ce_bActive = FALSE;
  116. }
  117. }
  118. static INDEX GetNumberOfActiveEntries(void)
  119. {
  120. INDEX ctActive = 0;
  121. for(INDEX ice=0; ice<_aceEntries.Count(); ice++) {
  122. if (_aceEntries[ice].ce_bActive) {
  123. ctActive++;
  124. }
  125. }
  126. return ctActive;
  127. }
  128. // dump list of all active files to the stream
  129. void CRCT_MakeFileList_t(CTStream &strmFiles) // throw char *
  130. {
  131. // save number of active entries
  132. INDEX ctActive = GetNumberOfActiveEntries();
  133. strmFiles<<ctActive;
  134. // for each active entry
  135. for(INDEX ice=0; ice<_aceEntries.Count(); ice++) {
  136. CCRCEntry &ce = _aceEntries[ice];
  137. if (!ce.ce_bActive) {
  138. continue;
  139. }
  140. // save name to stream
  141. strmFiles<<(CTString&)ce.ce_fnmFile;
  142. }
  143. }
  144. // dump checksums for all files from the list
  145. ULONG CRCT_MakeCRCForFiles_t(CTStream &strmFiles) // throw char *
  146. {
  147. BOOL bOld = CRCT_bGatherCRCs;
  148. CRCT_bGatherCRCs = TRUE;
  149. ULONG ulCRC;
  150. CRC_Start(ulCRC);
  151. // read number of active files
  152. INDEX ctFiles;
  153. strmFiles>>ctFiles;
  154. // for each one
  155. for(INDEX i=0; i<ctFiles; i++) {
  156. // read the name
  157. CTString strName;
  158. strmFiles>>strName;
  159. // try to find it in table
  160. CCRCEntry *pce = _ntEntries.Find(strName);
  161. // if not there
  162. if (pce==NULL) {
  163. CRCT_AddFile_t(strName);
  164. // add it now
  165. pce = _ntEntries.Find(strName);
  166. }
  167. // add the crc
  168. CRC_AddLONG(ulCRC, pce->ce_ulCRC);
  169. }
  170. CRCT_bGatherCRCs = bOld;
  171. CRC_Finish(ulCRC);
  172. return ulCRC;
  173. }
  174. #endif /* include-once check. */