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