CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

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 }