bufffile.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*
  2. ** Command & Conquer Renegade(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. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Command & Conquer *
  23. * *
  24. * $Archive:: /Commando/Code/wwlib/bufffile.cpp $*
  25. * *
  26. * $Author:: Jani_p $*
  27. * *
  28. * $Modtime:: 9/13/01 7:15p $*
  29. * *
  30. * $Revision:: 4 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  34. #include "always.h"
  35. #include "bufffile.h"
  36. #include "wwdebug.h"
  37. #include <string.h>
  38. int BufferedFileClass::_DesiredBufferSize = 1024*16;
  39. /***********************************************************************************************
  40. * BufferedFileClass::BufferedFileClass -- Default constructor for a file object. *
  41. *=============================================================================================*/
  42. BufferedFileClass::BufferedFileClass(void) :
  43. RawFileClass(),
  44. Buffer( NULL ),
  45. BufferSize( 0 ),
  46. BufferAvailable( 0 ),
  47. BufferOffset( 0 )
  48. {
  49. }
  50. /***********************************************************************************************
  51. * BufferedFileClass::BufferedFileClass -- Simple constructor for a file object. *
  52. *=============================================================================================*/
  53. BufferedFileClass::BufferedFileClass(char const * filename) :
  54. RawFileClass( filename ),
  55. Buffer( NULL ),
  56. BufferSize( 0 ),
  57. BufferAvailable( 0 ),
  58. BufferOffset( 0 )
  59. {
  60. }
  61. /***********************************************************************************************
  62. * BufferedFileClass::~BufferedFileClass -- Default deconstructor for a file object. *
  63. *=============================================================================================*/
  64. BufferedFileClass::~BufferedFileClass(void)
  65. {
  66. Reset_Buffer();
  67. }
  68. /***********************************************************************************************
  69. * BufferedFileClass::Close -- Perform a closure of the file. *
  70. *=============================================================================================*/
  71. void BufferedFileClass::Close(void)
  72. {
  73. BASECLASS::Close();
  74. Reset_Buffer();
  75. }
  76. /***********************************************************************************************
  77. * BufferedFileClass::Read -- Reads the specified number of bytes into a memory buffer. *
  78. * *
  79. * This routine will read the specified number of bytes and place the data into the buffer *
  80. * indicated. It is legal to call this routine with a request for more bytes than are in *
  81. * the file. This condition can result in fewer bytes being read than requested. Determine *
  82. * this by examining the return value. *
  83. * *
  84. * INPUT: buffer -- Pointer to the buffer to read data into. If NULL is passed, no read *
  85. * is performed. *
  86. * *
  87. * size -- The number of bytes to read. If NULL is passed, then no read is *
  88. * performed. *
  89. * *
  90. * OUTPUT: Returns with the number of bytes read into the buffer. If this number is less *
  91. * than requested, it indicates that the file has been exhausted. *
  92. * *
  93. * WARNINGS: none *
  94. * *
  95. * HISTORY: *
  96. * 10/18/1994 JLB : Created. *
  97. *=============================================================================================*/
  98. int BufferedFileClass::Read(void * buffer, int size)
  99. {
  100. int read = 0;
  101. // If there is anything in the buffer, copy it in.
  102. if ( BufferAvailable > 0 ) {
  103. int amount = min( size, BufferAvailable );
  104. ::memcpy( buffer, &Buffer[BufferOffset], amount );
  105. BufferAvailable -= amount;
  106. BufferOffset += amount;
  107. size -= amount;
  108. buffer = (char *)buffer + amount;
  109. read += amount;
  110. }
  111. if ( size == 0 ) {
  112. return read;
  113. }
  114. // We need to get a copy of the _DesiredBufferSize into
  115. // a local variable to protect us from modifications
  116. // from another thread. Otherwise, we could pass the test
  117. // (size > amount) below, only to allocate a buffer that's
  118. // too small in the next block. (DRM, 04/20/01)
  119. int desired_buffer_size = _DesiredBufferSize;
  120. // If we need more than the buffer will hold, just read it
  121. int amount = BufferSize;
  122. if ( amount == 0 ) {
  123. amount = desired_buffer_size;
  124. }
  125. if ( size > amount ) {
  126. return BASECLASS::Read( buffer, size ) + read;
  127. }
  128. // If we dont have a buffer, get one
  129. if ( BufferSize == 0 ) {
  130. BufferSize = desired_buffer_size;
  131. Buffer = new unsigned char [BufferSize];
  132. BufferAvailable = 0;
  133. BufferOffset = 0;
  134. }
  135. // Fill the buffer
  136. if ( BufferAvailable == 0 ) {
  137. BufferAvailable = BASECLASS::Read( Buffer, BufferSize );
  138. BufferOffset = 0;
  139. }
  140. // If there is anything in the buffer, copy it in.
  141. if ( BufferAvailable > 0 ) {
  142. int amount = min( size, BufferAvailable );
  143. ::memcpy( buffer, &Buffer[BufferOffset], amount );
  144. BufferAvailable -= amount;
  145. BufferOffset += amount;
  146. read += amount;
  147. }
  148. return read;
  149. }
  150. /***********************************************************************************************
  151. * BufferedFileClass::Write -- Writes the specified data to the buffer specified. *
  152. * *
  153. * This routine will write the data specified to the file. *
  154. * *
  155. * INPUT: buffer -- The buffer that holds the data to write. *
  156. * *
  157. * size -- The number of bytes to write to the file. *
  158. * *
  159. * OUTPUT: Returns with the number of bytes written to the file. This routine catches the *
  160. * case of a disk full condition, so this routine will always return with the number *
  161. * matching the size request. *
  162. * *
  163. * WARNINGS: A fatal file condition could cause this routine to never return. *
  164. * *
  165. * HISTORY: *
  166. * 10/18/1994 JLB : Created. *
  167. *=============================================================================================*/
  168. int BufferedFileClass::Write(void const * buffer, int size)
  169. {
  170. if ( BufferSize != 0 ) {
  171. WWASSERT( 0 );
  172. }
  173. return BASECLASS::Write( buffer, size );
  174. }
  175. /***********************************************************************************************
  176. * BufferedFileClass::Seek -- Reposition the file pointer as indicated. *
  177. * *
  178. * Use this routine to move the filepointer to the position indicated. It can move either *
  179. * relative to current position or absolute from the beginning or ending of the file. This *
  180. * routine will only return if it successfully performed the seek. *
  181. * *
  182. * INPUT: pos -- The position to seek to. This is interpreted as relative to the position *
  183. * indicated by the "dir" parameter. *
  184. * *
  185. * dir -- The relative position to relate the seek to. This can be either SEEK_SET *
  186. * for the beginning of the file, SEEK_CUR for the current position, or *
  187. * SEEK_END for the end of the file. *
  188. * *
  189. * OUTPUT: This routine returns the position that the seek ended up at. *
  190. * *
  191. * WARNINGS: If there was a file error, then this routine might never return. *
  192. * *
  193. * HISTORY: *
  194. * 10/18/1994 JLB : Created. *
  195. *=============================================================================================*/
  196. int BufferedFileClass::Seek(int pos, int dir)
  197. {
  198. if ( (dir != SEEK_CUR) || (pos < 0) ) {
  199. Reset_Buffer();
  200. }
  201. // If not buffered, pass through
  202. if ( BufferAvailable == 0 ) {
  203. return BASECLASS::Seek( pos, dir );
  204. }
  205. // use up what we can of the buffer
  206. int amount = min( pos, BufferAvailable );
  207. pos -= amount;
  208. BufferAvailable -= amount;
  209. BufferOffset += amount;
  210. return BASECLASS::Seek( pos, dir ) - BufferAvailable;
  211. }
  212. /*
  213. **
  214. */
  215. void BufferedFileClass::Reset_Buffer( void )
  216. {
  217. if ( Buffer != NULL ) {
  218. delete [] Buffer;
  219. Buffer = NULL;
  220. BufferSize = 0;
  221. BufferAvailable = 0;
  222. BufferOffset = 0;
  223. }
  224. }