XferLoad.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /*
  2. ** Command & Conquer Generals Zero Hour(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: XferLoad.cpp /////////////////////////////////////////////////////////////////////////////
  24. // Author: Colin Day, February 2002
  25. // Desc: Xfer implemenation for loading from disk
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. // USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
  28. #include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine
  29. #include "Common/Debug.h"
  30. #include "Common/GameState.h"
  31. #include "Common/Snapshot.h"
  32. #include "Common/XferLoad.h"
  33. //-------------------------------------------------------------------------------------------------
  34. //-------------------------------------------------------------------------------------------------
  35. XferLoad::XferLoad( void )
  36. {
  37. m_xferMode = XFER_LOAD;
  38. m_fileFP = NULL;
  39. } // end XferLoad
  40. //-------------------------------------------------------------------------------------------------
  41. //-------------------------------------------------------------------------------------------------
  42. XferLoad::~XferLoad( void )
  43. {
  44. // warn the user if a file was left open
  45. if( m_fileFP != NULL )
  46. {
  47. DEBUG_CRASH(( "Warning: Xfer file '%s' was left open\n", m_identifier.str() ));
  48. close();
  49. } // end if
  50. } // end ~XferLoad
  51. //-------------------------------------------------------------------------------------------------
  52. /** Open file 'identifier' for reading */
  53. //-------------------------------------------------------------------------------------------------
  54. void XferLoad::open( AsciiString identifier )
  55. {
  56. // sanity, check to see if we're already open
  57. if( m_fileFP != NULL )
  58. {
  59. DEBUG_CRASH(( "Cannot open file '%s' cause we've already got '%s' open\n",
  60. identifier.str(), m_identifier.str() ));
  61. throw XFER_FILE_ALREADY_OPEN;
  62. } // end if
  63. // call base class
  64. Xfer::open( identifier );
  65. // open the file
  66. m_fileFP = fopen( identifier.str(), "rb" );
  67. if( m_fileFP == NULL )
  68. {
  69. DEBUG_CRASH(( "File '%s' not found\n", identifier.str() ));
  70. throw XFER_FILE_NOT_FOUND;
  71. } // end if
  72. } // end open
  73. //-------------------------------------------------------------------------------------------------
  74. /** Close our current file */
  75. //-------------------------------------------------------------------------------------------------
  76. void XferLoad::close( void )
  77. {
  78. // sanity, if we don't have an open file we can do nothing
  79. if( m_fileFP == NULL )
  80. {
  81. DEBUG_CRASH(( "Xfer close called, but no file was open\n" ));
  82. throw XFER_FILE_NOT_OPEN;
  83. } // end if
  84. // close the file
  85. fclose( m_fileFP );
  86. m_fileFP = NULL;
  87. // erase the filename
  88. m_identifier.clear();
  89. } // end close
  90. //-------------------------------------------------------------------------------------------------
  91. /** Read a block size descriptor from the file at the current position */
  92. //-------------------------------------------------------------------------------------------------
  93. Int XferLoad::beginBlock( void )
  94. {
  95. // sanity
  96. DEBUG_ASSERTCRASH( m_fileFP != NULL, ("Xfer begin block - file pointer for '%s' is NULL\n",
  97. m_identifier.str()) );
  98. // read block size
  99. XferBlockSize blockSize;
  100. if( fread( &blockSize, sizeof( XferBlockSize ), 1, m_fileFP ) != 1 )
  101. {
  102. DEBUG_CRASH(( "Xfer - Error reading block size for '%s'\n", m_identifier.str() ));
  103. return 0;
  104. } // end if
  105. // return the block size
  106. return blockSize;
  107. } // end beginBlock
  108. // ------------------------------------------------------------------------------------------------
  109. /** End block ... this does nothing when reading */
  110. // ------------------------------------------------------------------------------------------------
  111. void XferLoad::endBlock( void )
  112. {
  113. } // end endBlock
  114. //-------------------------------------------------------------------------------------------------
  115. /** Skip forward 'dataSize' bytes in the file */
  116. //-------------------------------------------------------------------------------------------------
  117. void XferLoad::skip( Int dataSize )
  118. {
  119. // sanity
  120. DEBUG_ASSERTCRASH( m_fileFP != NULL, ("XferLoad::skip - file pointer for '%s' is NULL\n",
  121. m_identifier.str()) );
  122. // sanity
  123. DEBUG_ASSERTCRASH( dataSize >=0, ("XferLoad::skip - dataSize '%d' must be greater than 0\n",
  124. dataSize) );
  125. // skip datasize in the file from the current position
  126. if( fseek( m_fileFP, dataSize, SEEK_CUR ) != 0 )
  127. throw XFER_SKIP_ERROR;
  128. } // end skip
  129. // ------------------------------------------------------------------------------------------------
  130. /** Entry point for xfering a snapshot */
  131. // ------------------------------------------------------------------------------------------------
  132. void XferLoad::xferSnapshot( Snapshot *snapshot )
  133. {
  134. if( snapshot == NULL )
  135. {
  136. DEBUG_CRASH(( "XferLoad::xferSnapshot - Invalid parameters\n" ));
  137. throw XFER_INVALID_PARAMETERS;
  138. } // end if
  139. // run the xfer function of the snapshot
  140. snapshot->xfer( this );
  141. // add this snapshot to the game state for later post processing if not restricted
  142. if( BitTest( getOptions(), XO_NO_POST_PROCESSING ) == FALSE )
  143. TheGameState->addPostProcessSnapshot( snapshot );
  144. } // end xferSnapshot
  145. // ------------------------------------------------------------------------------------------------
  146. /** Read string from file and store in ascii string */
  147. // ------------------------------------------------------------------------------------------------
  148. void XferLoad::xferAsciiString( AsciiString *asciiStringData )
  149. {
  150. // read bytes of string length to follow
  151. UnsignedByte len;
  152. xferUnsignedByte( &len );
  153. // read all the string data
  154. const Int MAX_XFER_LOAD_STRING_BUFFER = 1024;
  155. static Char buffer[ MAX_XFER_LOAD_STRING_BUFFER ];
  156. if( len > 0 )
  157. xferUser( buffer, sizeof( Byte ) * len );
  158. buffer[ len ] = 0; // terminate
  159. // save into ascii string
  160. asciiStringData->set( buffer );
  161. } // end xferAsciiString
  162. // ------------------------------------------------------------------------------------------------
  163. /** Read string from file and store in unicode string */
  164. // ------------------------------------------------------------------------------------------------
  165. void XferLoad::xferUnicodeString( UnicodeString *unicodeStringData )
  166. {
  167. // read bytes of string length to follow
  168. UnsignedByte len;
  169. xferUnsignedByte( &len );
  170. // read all the string data
  171. const Int MAX_XFER_LOAD_STRING_BUFFER = 1024;
  172. static WideChar buffer[ MAX_XFER_LOAD_STRING_BUFFER ];
  173. if( len > 0 )
  174. xferUser( buffer, sizeof( WideChar ) * len );
  175. buffer[ len ] = 0; // terminate
  176. // save into unicode string
  177. unicodeStringData->set( buffer );
  178. } // end xferUnicodeString
  179. //-------------------------------------------------------------------------------------------------
  180. /** Perform the read operation */
  181. //-------------------------------------------------------------------------------------------------
  182. void XferLoad::xferImplementation( void *data, Int dataSize )
  183. {
  184. // sanity
  185. DEBUG_ASSERTCRASH( m_fileFP != NULL, ("XferLoad - file pointer for '%s' is NULL\n",
  186. m_identifier.str()) );
  187. // read data from file
  188. if( fread( data, dataSize, 1, m_fileFP ) != 1 )
  189. {
  190. DEBUG_CRASH(( "XferLoad - Error reading from file '%s'\n", m_identifier.str() ));
  191. throw XFER_READ_ERROR;
  192. } // end if
  193. } // end xferImplementation