RAMFILE.CPP (28024B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 /* $Header: /CounterStrike/RAMFILE.CPP 1 3/03/97 10:25a Joe_bostic $ */ 17 /*********************************************************************************************** 18 *** 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 *** 19 *********************************************************************************************** 20 * * 21 * Project Name : Command & Conquer * 22 * * 23 * File Name : RAMFILE.CPP * 24 * * 25 * Programmer : Joe L. Bostic * 26 * * 27 * Start Date : 06/30/96 * 28 * * 29 * Last Update : July 3, 1996 [JLB] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * RAMFileClass::Close -- This will 'close' the ram file. * 34 * RAMFileClass::Create -- Effectively clears the buffer of data. * 35 * RAMFileClass::Delete -- Effectively clears the buffer of data. * 36 * RAMFileClass::Is_Available -- Determines if the "file" is available. * 37 * RAMFileClass::Is_Open -- Is the file open? * 38 * RAMFileClass::Open -- Opens a RAM based file for read or write. * 39 * RAMFileClass::Open -- Opens the RAM based file. * 40 * RAMFileClass::RAMFileClass -- Construct a RAM buffer based "file" object. * 41 * RAMFileClass::Read -- Read data from the file. * 42 * RAMFileClass::Seek -- Controls the ram file virtual read position. * 43 * RAMFileClass::Size -- Returns with the size of the ram file. * 44 * RAMFileClass::Write -- Copies data to the ram file. * 45 * RAMFileClass::~RAMFileClass -- Destructor for the RAM file class. * 46 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 47 48 #include "FUNCTION.H" 49 #include "ramfile.h" 50 #include <string.h> 51 52 53 /*********************************************************************************************** 54 * RAMFileClass::RAMFileClass -- Construct a RAM buffer based "file" object. * 55 * * 56 * This routine will construct a "file" object that actually is just a front end processor * 57 * for a buffer. Access to the buffer will appear as if it was accessing a file. This * 58 * is different from the caching ability of the buffered file class in that this file * 59 * class has no real file counterpart. Typical use of this is for algorithms that were * 60 * originally designed for file processing, but are now desired to work with a buffer. * 61 * * 62 * INPUT: buffer -- Pointer to the buffer to use for this file. The buffer will already * 63 * contain data if the file is opened for READ. It will be considered * 64 * a scratch buffer if opened for WRITE. If the buffer pointer is NULL * 65 * but the length parameter is not, then a buffer will be allocated * 66 * of the specified length. This case is only useful for opening the * 67 * file for WRITE. * 68 * * 69 * length -- The length of the buffer submitted to this routine. * 70 * * 71 * OUTPUT: none * 72 * * 73 * WARNINGS: none * 74 * * 75 * HISTORY: * 76 * 07/03/1996 JLB : Created. * 77 *=============================================================================================*/ 78 RAMFileClass::RAMFileClass(void * buffer, int len) : 79 Buffer((char *)buffer), 80 MaxLength(len), 81 Length(len), 82 Offset(0), 83 Access(READ), 84 IsOpen(false), 85 IsAllocated(false) 86 { 87 if (buffer == NULL && len > 0) { 88 Buffer = new char[len]; 89 IsAllocated = true; 90 } 91 } 92 93 94 /*********************************************************************************************** 95 * RAMFileClass::~RAMFileClass -- Destructor for the RAM file class. * 96 * * 97 * The destructor will deallocate any buffer that it allocated. Otherwise it does nothing. * 98 * * 99 * INPUT: none * 100 * * 101 * OUTPUT: none * 102 * * 103 * WARNINGS: none * 104 * * 105 * HISTORY: * 106 * 07/03/1996 JLB : Created. * 107 *=============================================================================================*/ 108 RAMFileClass::~RAMFileClass(void) 109 { 110 Close(); 111 if (IsAllocated) { 112 delete [] Buffer; 113 Buffer = NULL; 114 IsAllocated = false; 115 } 116 } 117 118 119 /*********************************************************************************************** 120 * RAMFileClass::Create -- Effectively clears the buffer of data. * 121 * * 122 * This routine "clears" the buffer of data. It only makes the buffer appear empty by * 123 * resetting the internal length to zero. * 124 * * 125 * INPUT: none * 126 * * 127 * OUTPUT: Was the file reset in this fashion? * 128 * * 129 * WARNINGS: If the file was open, then resetting by this routine is not allowed. * 130 * * 131 * HISTORY: * 132 * 07/03/1996 JLB : Created. * 133 *=============================================================================================*/ 134 int RAMFileClass::Create(void) 135 { 136 if (!Is_Open()) { 137 Length = 0; 138 return(true); 139 } 140 return(false); 141 } 142 143 144 /*********************************************************************************************** 145 * RAMFileClass::Delete -- Effectively clears the buffer of data. * 146 * * 147 * This routine "clears" the buffer of data. It only makes the buffer appear empty by * 148 * resetting the internal length to zero. * 149 * * 150 * INPUT: none * 151 * * 152 * OUTPUT: Was the file reset in this fashion? * 153 * * 154 * WARNINGS: If the file was open, then resetting by this routine is not allowed. * 155 * * 156 * HISTORY: * 157 * 07/03/1996 JLB : Created. * 158 *=============================================================================================*/ 159 int RAMFileClass::Delete(void) 160 { 161 if (!Is_Open()) { 162 Length = 0; 163 return(true); 164 } 165 return(false); 166 } 167 168 169 /*********************************************************************************************** 170 * RAMFileClass::Is_Available -- Determines if the "file" is available. * 171 * * 172 * RAM files are always available. * 173 * * 174 * INPUT: none * 175 * * 176 * OUTPUT: TRUE * 177 * * 178 * WARNINGS: none * 179 * * 180 * HISTORY: * 181 * 07/03/1996 JLB : Created. * 182 *=============================================================================================*/ 183 int RAMFileClass::Is_Available(int ) 184 { 185 return(true); 186 } 187 188 189 /*********************************************************************************************** 190 * RAMFileClass::Is_Open -- Is the file open? * 191 * * 192 * This answers the question whether the file is open or not. * 193 * * 194 * INPUT: none * 195 * * 196 * OUTPUT: bool; Is the file open? * 197 * * 198 * WARNINGS: none * 199 * * 200 * HISTORY: * 201 * 07/03/1996 JLB : Created. * 202 *=============================================================================================*/ 203 int RAMFileClass::Is_Open(void) const 204 { 205 return(IsOpen); 206 } 207 208 209 /*********************************************************************************************** 210 * RAMFileClass::Open -- Opens a RAM based file for read or write. * 211 * * 212 * This routine will open the ram file. The name is meaningless so that parameter is * 213 * ignored. If the access mode is for write, then the pseudo-file can be written until the * 214 * buffer is full. If the file is opened for read, then the buffer is presumed to be full * 215 * of the data to be read. * 216 * * 217 * INPUT: name -- ignored. * 218 * * 219 * access-- The access method to use for the data buffer -- either READ or WRITE. * 220 * * 221 * OUTPUT: bool; Was the open successful? * 222 * * 223 * WARNINGS: none * 224 * * 225 * HISTORY: * 226 * 07/03/1996 JLB : Created. * 227 *=============================================================================================*/ 228 int RAMFileClass::Open(char const * , int access) 229 { 230 return(Open(access)); 231 } 232 233 234 /*********************************************************************************************** 235 * RAMFileClass::Open -- Opens the RAM based file. * 236 * * 237 * This will open the ram based file for read or write. If the file is opened for write, * 238 * the the 'file' can be written up to the limit of the buffer's size. If the file is * 239 * opened for read, then the buffer is presumed to hold the data to be read. * 240 * * 241 * INPUT: * 242 * * 243 * OUTPUT: * 244 * * 245 * WARNINGS: * 246 * * 247 * HISTORY: * 248 * 07/03/1996 JLB : Created. * 249 *=============================================================================================*/ 250 int RAMFileClass::Open(int access) 251 { 252 if (Buffer == NULL || Is_Open()) { 253 return(false); 254 } 255 256 Offset = 0; 257 Access = access; 258 IsOpen = true; 259 260 switch (access) { 261 default: 262 case READ: 263 break; 264 265 case WRITE: 266 Length = 0; 267 break; 268 269 case READ|WRITE: 270 break; 271 } 272 273 return(Is_Open()); 274 } 275 276 277 /*********************************************************************************************** 278 * RAMFileClass::Read -- Read data from the file. * 279 * * 280 * Use this routine just like a normal file read. It will copy the bytes from the ram * 281 * buffer to the destination specified. When the ram buffer is exhausted, less bytes than * 282 * requested will be read. * 283 * * 284 * INPUT: buffer -- Pointer to the buffer to store the data to. * 285 * * 286 * size -- The number of bytes to 'read' into the specified buffer. * 287 * * 288 * OUTPUT: Returns with the number of bytes copied to the destination buffer. If the number * 289 * of bytes returned is less than requested, then this indicates that the source * 290 * buffer is exhausted. * 291 * * 292 * WARNINGS: The read function only applies to ram 'files' opened for read access. * 293 * * 294 * HISTORY: * 295 * 07/03/1996 JLB : Created. * 296 *=============================================================================================*/ 297 long RAMFileClass::Read(void * buffer, long size) 298 { 299 if (Buffer == NULL || buffer == NULL || size == 0) { 300 return(0); 301 } 302 303 bool hasopened = false; 304 if (!Is_Open()) { 305 Open(READ); 306 hasopened = true; 307 } else { 308 if ((Access & READ) == 0) { 309 return(0); 310 } 311 } 312 313 int tocopy = (size < (Length-Offset)) ? size : (Length-Offset); 314 memmove(buffer, &Buffer[Offset], tocopy); 315 Offset += tocopy; 316 317 if (hasopened) { 318 Close(); 319 } 320 321 return(tocopy); 322 } 323 324 325 /*********************************************************************************************** 326 * RAMFileClass::Seek -- Controls the ram file virtual read position. * 327 * * 328 * This routine will move the read/write position of the ram file to the location specified * 329 * by the offset and direction parameters. It functions similarly to the regular file * 330 * seek method. * 331 * * 332 * INPUT: pos -- The signed offset from the home position specified by the "dir" * 333 * parameter. * 334 * * 335 * dir -- The home position to base the position offset on. This will either be * 336 * the start of the file, the end of the file, or the current read/write * 337 * position. * 338 * * 339 * OUTPUT: Returns with the new file position. * 340 * * 341 * WARNINGS: none * 342 * * 343 * HISTORY: * 344 * 07/03/1996 JLB : Created. * 345 *=============================================================================================*/ 346 long RAMFileClass::Seek(long pos, int dir) 347 { 348 if (Buffer == NULL || !Is_Open()) { 349 return(Offset); 350 } 351 352 int maxoffset = Length; 353 if ((Access & WRITE) != 0) { 354 maxoffset = MaxLength; 355 } 356 357 switch (dir) { 358 case SEEK_CUR: 359 Offset += pos; 360 break; 361 362 case SEEK_SET: 363 Offset = 0 + pos; 364 break; 365 366 case SEEK_END: 367 Offset = maxoffset + pos; 368 break; 369 } 370 371 if (Offset < 0) Offset = 0; 372 if (Offset > maxoffset) Offset = maxoffset; 373 374 if (Offset > Length) { 375 Length = Offset; 376 } 377 378 return(Offset); 379 } 380 381 382 /*********************************************************************************************** 383 * RAMFileClass::Size -- Returns with the size of the ram file. * 384 * * 385 * This will return the size of the 'real' data in the ram file. The real data is either * 386 * the entire buffer, if opened for READ, or just the written data if opened for WRITE. * 387 * * 388 * INPUT: none * 389 * * 390 * OUTPUT: Returns with the number of bytes that the ram file system considers to be valid * 391 * data of the 'file'. * 392 * * 393 * WARNINGS: none * 394 * * 395 * HISTORY: * 396 * 07/03/1996 JLB : Created. * 397 *=============================================================================================*/ 398 long RAMFileClass::Size(void) 399 { 400 return(Length); 401 } 402 403 404 /*********************************************************************************************** 405 * RAMFileClass::Write -- Copies data to the ram file. * 406 * * 407 * This function similarly to the regular write operation supported for files. It copies * 408 * the data specified to the current write position in the ram file. * 409 * * 410 * INPUT: buffer -- Pointer to the data to be written. * 411 * * 412 * size -- The number of bytes to write to the file. * 413 * * 414 * OUTPUT: Returns with the actual number of bytes written. This will be less than requested * 415 * if the buffer is exhausted of space prematurely. * 416 * * 417 * WARNINGS: none * 418 * * 419 * HISTORY: * 420 * 07/03/1996 JLB : Created. * 421 *=============================================================================================*/ 422 long RAMFileClass::Write(void const * buffer, long size) 423 { 424 if (Buffer == NULL || buffer == NULL || size == 0) { 425 return(0); 426 } 427 428 bool hasopened = false; 429 if (!Is_Open()) { 430 Open(WRITE); 431 hasopened = true; 432 } else { 433 if ((Access & WRITE) == 0) { 434 return(0); 435 } 436 } 437 438 int maxwrite = MaxLength - Offset; 439 int towrite = (size < maxwrite) ? size : maxwrite; 440 memmove(&Buffer[Offset], buffer, towrite); 441 Offset += towrite; 442 443 if (Offset > Length) { 444 Length = Offset; 445 } 446 447 if (hasopened) { 448 Close(); 449 } 450 451 return(towrite); 452 } 453 454 455 /*********************************************************************************************** 456 * RAMFileClass::Close -- This will 'close' the ram file. * 457 * * 458 * Closing a ram file actually does nothing but record that it is now closed. * 459 * * 460 * INPUT: none * 461 * * 462 * OUTPUT: none * 463 * * 464 * WARNINGS: none * 465 * * 466 * HISTORY: * 467 * 07/03/1996 JLB : Created. * 468 *=============================================================================================*/ 469 void RAMFileClass::Close(void) 470 { 471 IsOpen = false; 472 }