XferCRC.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: XferCRC.cpp //////////////////////////////////////////////////////////////////////////////
  24. // Author: Matt Campbell, February 2002
  25. // Desc: Xfer CRC implementation
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. // USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
  28. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  29. #include "Common/XferCRC.h"
  30. #include "Common/XferDeepCRC.h"
  31. #include "Common/CRC.h"
  32. #include "Common/Snapshot.h"
  33. #include "winsock2.h" // for htonl
  34. //-------------------------------------------------------------------------------------------------
  35. //-------------------------------------------------------------------------------------------------
  36. XferCRC::XferCRC( void )
  37. {
  38. m_xferMode = XFER_CRC;
  39. //Added By Sadullah Nader
  40. //Initialization(s) inserted
  41. m_crc = 0;
  42. //
  43. } // end XferCRC
  44. //-------------------------------------------------------------------------------------------------
  45. //-------------------------------------------------------------------------------------------------
  46. XferCRC::~XferCRC( void )
  47. {
  48. } // end ~XferCRC
  49. //-------------------------------------------------------------------------------------------------
  50. /** Open file 'identifier' for writing */
  51. //-------------------------------------------------------------------------------------------------
  52. void XferCRC::open( AsciiString identifier )
  53. {
  54. // call base class
  55. Xfer::open( identifier );
  56. // initialize CRC to brand new one at zero
  57. m_crc = 0;
  58. } // end open
  59. //-------------------------------------------------------------------------------------------------
  60. /** Close our current file */
  61. //-------------------------------------------------------------------------------------------------
  62. void XferCRC::close( void )
  63. {
  64. } // end close
  65. //-------------------------------------------------------------------------------------------------
  66. //-------------------------------------------------------------------------------------------------
  67. Int XferCRC::beginBlock( void )
  68. {
  69. return 0;
  70. } // end beginBlock
  71. //-------------------------------------------------------------------------------------------------
  72. //-------------------------------------------------------------------------------------------------
  73. void XferCRC::endBlock( void )
  74. {
  75. } // end endBlock
  76. //-------------------------------------------------------------------------------------------------
  77. //-------------------------------------------------------------------------------------------------
  78. void XferCRC::addCRC( UnsignedInt val )
  79. {
  80. int hibit;
  81. val = htonl(val);
  82. if (m_crc & 0x80000000)
  83. {
  84. hibit = 1;
  85. }
  86. else
  87. {
  88. hibit = 0;
  89. }
  90. m_crc <<= 1;
  91. m_crc += val;
  92. m_crc += hibit;
  93. } // end addCRC
  94. // ------------------------------------------------------------------------------------------------
  95. /** Entry point for xfering a snapshot */
  96. // ------------------------------------------------------------------------------------------------
  97. void XferCRC::xferSnapshot( Snapshot *snapshot )
  98. {
  99. if( snapshot == NULL )
  100. {
  101. return;
  102. } // end if
  103. // run the crc function of the snapshot
  104. snapshot->crc( this );
  105. } // end xferSnapshot
  106. //-------------------------------------------------------------------------------------------------
  107. /** Perform a single CRC operation on the data passed in */
  108. //-------------------------------------------------------------------------------------------------
  109. void XferCRC::xferImplementation( void *data, Int dataSize )
  110. {
  111. if (!data || dataSize < 1)
  112. {
  113. return;
  114. }
  115. const UnsignedInt *uintPtr = (const UnsignedInt *) (data);
  116. for (Int i=0 ; i<dataSize/4 ; i++)
  117. {
  118. addCRC (*uintPtr++);
  119. }
  120. int leftover = dataSize & 3;
  121. if (leftover)
  122. {
  123. UnsignedInt val = 0;
  124. const unsigned char *c = (const unsigned char *)uintPtr;
  125. for (Int i=0; i<leftover; i++)
  126. {
  127. val += (c[i] << (i*8));
  128. }
  129. val = htonl(val);
  130. addCRC (val);
  131. }
  132. } // end xferImplementation
  133. //-------------------------------------------------------------------------------------------------
  134. //-------------------------------------------------------------------------------------------------
  135. void XferCRC::skip( Int dataSize )
  136. {
  137. } // end skip
  138. //-------------------------------------------------------------------------------------------------
  139. //-------------------------------------------------------------------------------------------------
  140. UnsignedInt XferCRC::getCRC( void )
  141. {
  142. return htonl(m_crc);
  143. } // end skip
  144. //-------------------------------------------------------------------------------------------------
  145. //-------------------------------------------------------------------------------------------------
  146. XferDeepCRC::XferDeepCRC( void )
  147. {
  148. m_xferMode = XFER_SAVE;
  149. m_fileFP = NULL;
  150. } // end XferCRC
  151. //-------------------------------------------------------------------------------------------------
  152. //-------------------------------------------------------------------------------------------------
  153. XferDeepCRC::~XferDeepCRC( void )
  154. {
  155. // warn the user if a file was left open
  156. if( m_fileFP != NULL )
  157. {
  158. DEBUG_CRASH(( "Warning: Xfer file '%s' was left open\n", m_identifier.str() ));
  159. close();
  160. } // end if
  161. } // end ~XferCRC
  162. //-------------------------------------------------------------------------------------------------
  163. /** Open file 'identifier' for writing */
  164. //-------------------------------------------------------------------------------------------------
  165. void XferDeepCRC::open( AsciiString identifier )
  166. {
  167. m_xferMode = XFER_SAVE;
  168. // sanity, check to see if we're already open
  169. if( m_fileFP != NULL )
  170. {
  171. DEBUG_CRASH(( "Cannot open file '%s' cause we've already got '%s' open\n",
  172. identifier.str(), m_identifier.str() ));
  173. throw XFER_FILE_ALREADY_OPEN;
  174. } // end if
  175. // call base class
  176. Xfer::open( identifier );
  177. // open the file
  178. m_fileFP = fopen( identifier.str(), "w+b" );
  179. if( m_fileFP == NULL )
  180. {
  181. DEBUG_CRASH(( "File '%s' not found\n", identifier.str() ));
  182. throw XFER_FILE_NOT_FOUND;
  183. } // end if
  184. // initialize CRC to brand new one at zero
  185. m_crc = 0;
  186. } // end open
  187. //-------------------------------------------------------------------------------------------------
  188. /** Close our current file */
  189. //-------------------------------------------------------------------------------------------------
  190. void XferDeepCRC::close( void )
  191. {
  192. // sanity, if we don't have an open file we can do nothing
  193. if( m_fileFP == NULL )
  194. {
  195. DEBUG_CRASH(( "Xfer close called, but no file was open\n" ));
  196. throw XFER_FILE_NOT_OPEN;
  197. } // end if
  198. // close the file
  199. fclose( m_fileFP );
  200. m_fileFP = NULL;
  201. // erase the filename
  202. m_identifier.clear();
  203. } // end close
  204. //-------------------------------------------------------------------------------------------------
  205. /** Perform a single CRC operation on the data passed in */
  206. //-------------------------------------------------------------------------------------------------
  207. void XferDeepCRC::xferImplementation( void *data, Int dataSize )
  208. {
  209. if (!data || dataSize < 1)
  210. {
  211. return;
  212. }
  213. // sanity
  214. DEBUG_ASSERTCRASH( m_fileFP != NULL, ("XferSave - file pointer for '%s' is NULL\n",
  215. m_identifier.str()) );
  216. // write data to file
  217. if( fwrite( data, dataSize, 1, m_fileFP ) != 1 )
  218. {
  219. DEBUG_CRASH(( "XferSave - Error writing to file '%s'\n", m_identifier.str() ));
  220. throw XFER_WRITE_ERROR;
  221. } // end if
  222. XferCRC::xferImplementation( data, dataSize );
  223. } // end xferImplementation
  224. // ------------------------------------------------------------------------------------------------
  225. /** Save ascii string */
  226. // ------------------------------------------------------------------------------------------------
  227. void XferDeepCRC::xferMarkerLabel( AsciiString asciiStringData )
  228. {
  229. } // end xferAsciiString
  230. // ------------------------------------------------------------------------------------------------
  231. /** Save ascii string */
  232. // ------------------------------------------------------------------------------------------------
  233. void XferDeepCRC::xferAsciiString( AsciiString *asciiStringData )
  234. {
  235. // sanity
  236. if( asciiStringData->getLength() > 16385 )
  237. {
  238. DEBUG_CRASH(( "XferSave cannot save this ascii string because it's too long. Change the size of the length header (but be sure to preserve save file compatability\n" ));
  239. throw XFER_STRING_ERROR;
  240. } // end if
  241. // save length of string to follow
  242. UnsignedShort len = asciiStringData->getLength();
  243. xferUnsignedShort( &len );
  244. // save string data
  245. if( len > 0 )
  246. xferUser( (void *)asciiStringData->str(), sizeof( Byte ) * len );
  247. } // end xferAsciiString
  248. // ------------------------------------------------------------------------------------------------
  249. /** Save unicodee string */
  250. // ------------------------------------------------------------------------------------------------
  251. void XferDeepCRC::xferUnicodeString( UnicodeString *unicodeStringData )
  252. {
  253. // sanity
  254. if( unicodeStringData->getLength() > 255 )
  255. {
  256. DEBUG_CRASH(( "XferSave cannot save this unicode string because it's too long. Change the size of the length header (but be sure to preserve save file compatability\n" ));
  257. throw XFER_STRING_ERROR;
  258. } // end if
  259. // save length of string to follow
  260. Byte len = unicodeStringData->getLength();
  261. xferByte( &len );
  262. // save string data
  263. if( len > 0 )
  264. xferUser( (void *)unicodeStringData->str(), sizeof( WideChar ) * len );
  265. } // end xferUnicodeString