Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
ffactory.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/ffactory.cpp $*
26 * *
27 * $Author:: Jani_p $*
28 * *
29 * $Modtime:: 8/24/01 11:50a $*
30 * *
31 * $Revision:: 17 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
35
36#include "ffactory.h"
37#include "rawfile.h"
38#include "bufffile.h"
39#include "realcrc.h"
40#include <stdio.h>
41#include <stdlib.h>
42#include <assert.h>
43#include <string.h>
44
45/*
46** Statics
47** NOTE: If _TheFileFactory is ever changed to point to an object of a different class which does
48** not derive from SimpleFileFactoryClass, _TheSimpleFileFactory should be set to NULL.
49*/
53
56
57/*
58**
59*/
61 _Ptr(NULL), _Fac(fac)
62{
63 assert(_Fac);
64 _Ptr=_Fac->Get_File(filename);
65 if ( _Ptr == NULL ) {
67 }
68}
69
71{
72 _Fac->Return_File(_Ptr);
73}
74
75
76
77/*
78** RawFileFactoryClass implementation
79*/
81{
82 return W3DNEW RawFileClass( filename );
83}
84
86{
87 delete file;
88}
89
90
91
92/*
93** SimpleFileFactoryClass implementation
94*/
95
101
102
104{
105 // BEGIN SERIALIZATION
106
107 // We cannot return a const char * here because the StringClass
108 // may reallocate its buffer during a call to Set_Sub_Directory.
109 // I opted to return a StringClass instead of a reference to
110 // StringClass because it seems like that would behave more
111 // reasonably. (no sudden changes from or to empty string in
112 // the middle of a calling function.) (DRM, 04/19/01)
113
114 // Jani: Returning a StringClass object causes a memory allocation
115 // and release so it is better to take a reference to the
116 // destination StringClass object and modify that.
117
119 new_dir=SubDirectory;
120 // END SERIALIZATION
121}
122
123
124void SimpleFileFactoryClass::Set_Sub_Directory( const char * sub_directory )
125{
126 // BEGIN SERIALIZATION
127
128 // StringClass makes no guarantees on the atomicity of assignment.
129 // Just to be safe, we lock before executing the assignment code.
130 // (DRM, 04/19/01)
131
133 SubDirectory = sub_directory;
134 // END SERIALIZATION
135}
136
137
138void SimpleFileFactoryClass::Prepend_Sub_Directory( const char * sub_directory )
139{
140 int sub_len = strlen(sub_directory);
141 // Overflow prevention
142 if (sub_len > 1021) {
143 WWASSERT(0);
144 return;
145 } else if (sub_len < 1) {
146 return;
147 }
148
149 // Ensure sub_directory ends with a slash, and append a semicolon
150 char temp_sub_dir[1024];
151 strcpy(temp_sub_dir, sub_directory);
152 if (temp_sub_dir[sub_len - 1] != '\\') {
153 temp_sub_dir[sub_len] = '\\';
154 temp_sub_dir[sub_len + 1] = 0;
155 sub_len++;
156 }
157 temp_sub_dir[sub_len] = ';';
158 temp_sub_dir[sub_len + 1] = 0;
159
160 // BEGIN SERIALIZATION
161
162 // StringClass makes no guarantees on the atomicity of concatenation.
163 // Just to be safe, we lock before executing the concatenation code.
164 // (NH, 04/23/01)
165
167 SubDirectory = temp_sub_dir + SubDirectory;
168
169 // END SERIALIZATION
170}
171
172
173void SimpleFileFactoryClass::Append_Sub_Directory( const char * sub_directory )
174{
175 int sub_len = strlen(sub_directory);
176 // Overflow prevention
177 if (sub_len > 1022) {
178 WWASSERT(0);
179 return;
180 } else if (sub_len < 1) {
181 return;
182 }
183
184 // Ensure sub_directory ends with a slash
185 char temp_sub_dir[1024];
186 strcpy(temp_sub_dir, sub_directory);
187 if (temp_sub_dir[sub_len - 1] != '\\') {
188 temp_sub_dir[sub_len] = '\\';
189 temp_sub_dir[sub_len + 1] = 0;
190 sub_len++;
191 }
192
193 // BEGIN SERIALIZATION
194
195 // We are doing various dependent operations on SubDirectory.
196 // Just to be safe, we lock before this section.
197 // (NH, 04/23/01)
198
200
201 // Ensure a trailing semicolon is present, unless the directory list is empty
202 int len = SubDirectory.Get_Length();
203 if (len && SubDirectory[len - 1] != ';') {
204 SubDirectory += ';';
205 }
206
207 SubDirectory += temp_sub_dir;
208 // END SERIALIZATION
209}
210
211
212/*
213** Is_Full_Path
214*/
215static bool
216Is_Full_Path (const char *path)
217{
218 bool retval = false;
219
220 if (path != NULL && path[0] != 0) {
221
222 // Check for drive designation
223 retval = bool(path[1] == ':');
224
225 // Check for network path
226 retval |= bool((path[0] == '\\') && (path[1] == '\\'));
227 }
228
229 return retval;
230}
231
232/*
233**
234*/
236{
237 // strip off the path (if needed). Note that if path stripping is off, and the requested file
238 // has a path in its name, and the current subdirectory is not empty, the paths will just be
239 // concatenated which may not produce reasonable results.
240 StringClass stripped_name(true);
241 if (IsStripPath) {
242 const char * ptr = ::strrchr( filename, '\\' );
243
244 if (ptr != 0) {
245 ptr++;
246 stripped_name = ptr;
247 } else {
248 stripped_name = filename;
249 }
250 } else {
251 stripped_name = filename;
252 }
253
254 RawFileClass *file = W3DNEW BufferedFileClass();// new RawWritingFileClass();
255 assert( file );
256
257 //
258 // Do we need to find the path for this file request?
259 //
260 StringClass new_name(stripped_name,true);
261 if (Is_Full_Path ( new_name ) == false) {
262
263 // BEGIN SERIALIZATION
264
265 // We need to lock here because we are using the contents of SubDirectory
266 // in two places. I'd rather be overly cautious about the implementation
267 // of StringClass and wrap all calls to it. We can optimize later if this
268 // proves too slow. (DRM, 04/19/01)
269
271
272 if (!SubDirectory.Is_Empty()) {
273
274 //
275 // SubDirectory may contain a semicolon seperated search path...
276 // If the file doesn't exist, we'll set the path to the last dir in
277 // the search path. Therefore newly created files will always go in the
278 // last dir in the search path.
279 //
280 StringClass subdir(SubDirectory,true);
281
282 if (strchr(subdir,';'))
283 {
284 char *tokstart=subdir.Peek_Buffer();
285 const char *tok;
286 while((tok=strtok(tokstart, ";")) != NULL) {
287 tokstart=NULL;
288 new_name.Format("%s%s",tok,stripped_name.Peek_Buffer());
289 file->Set_Name( new_name ); // Call Set_Name to force an allocated name
290 if (file->Open()) {
291 file->Close();
292 break;
293 }
294 }
295 } else {
296 new_name.Format("%s%s",SubDirectory,stripped_name);
297 }
298 }
299
300 // END SERIALIZATION
301 }
302
303 file->Set_Name( new_name ); // Call Set_Name to force an allocated name
304 return file;
305}
306
308{
309 delete file;
310}
311
#define NULL
Definition BaseType.h:92
#define bool
Definition gimex.h:284
#define WWASSERT
#define W3DNEW
Definition always.h:109
@ false
Definition bool.h:59
virtual char const * Set_Name(char const *filename)
Definition rawfile.cpp:313
virtual int Open(char const *filename, int rights=READ)
Definition rawfile.cpp:356
virtual void Close(void)
Definition rawfile.cpp:561
RawFileClass * Get_File(char const *filename)
Definition ffactory.cpp:80
void Return_File(FileClass *file)
Definition ffactory.cpp:85
CriticalSectionClass Mutex
Definition ffactory.h:152
void Append_Sub_Directory(const char *sub_directory)
Definition ffactory.cpp:173
void Get_Sub_Directory(StringClass &new_dir) const
Definition ffactory.cpp:103
virtual void Return_File(FileClass *file)
Definition ffactory.cpp:307
StringClass SubDirectory
Definition ffactory.h:148
virtual FileClass * Get_File(char const *filename)
Definition ffactory.cpp:235
void Set_Sub_Directory(const char *sub_directory)
Definition ffactory.cpp:124
void Prepend_Sub_Directory(const char *sub_directory)
Definition ffactory.cpp:138
int _cdecl Format(const TCHAR *format,...)
Definition wwstring.cpp:273
TCHAR * Peek_Buffer(void)
Definition wwstring.h:560
file_auto_ptr(FileFactoryClass *fac, const char *filename)
Definition ffactory.cpp:60
RawFileFactoryClass * _TheWritingFileFactory
Definition ffactory.cpp:55
FileFactoryClass * _TheFileFactory
Definition ffactory.cpp:51
SimpleFileFactoryClass _DefaultFileFactory
Definition ffactory.cpp:50
SimpleFileFactoryClass * _TheSimpleFileFactory
Definition ffactory.cpp:52
RawFileFactoryClass _DefaultWritingFileFactory
Definition ffactory.cpp:54