// // Copyright 2020 Electronic Arts Inc. // // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free // software: you can redistribute it and/or modify it under the terms of // the GNU General Public License as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed // in the hope that it will be useful, but with permitted additional restrictions // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT // distributed with this program. You should have received a copy of the // GNU General Public License along with permitted additional restrictions // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection /* $Header: /CounterStrike/RAMFILE.CPP 1 3/03/97 10:25a Joe_bostic $ */ /*********************************************************************************************** *** 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 *** *********************************************************************************************** * * * Project Name : Command & Conquer * * * * File Name : RAMFILE.CPP * * * * Programmer : Joe L. Bostic * * * * Start Date : 06/30/96 * * * * Last Update : July 3, 1996 [JLB] * * * *---------------------------------------------------------------------------------------------* * Functions: * * RAMFileClass::Close -- This will 'close' the ram file. * * RAMFileClass::Create -- Effectively clears the buffer of data. * * RAMFileClass::Delete -- Effectively clears the buffer of data. * * RAMFileClass::Is_Available -- Determines if the "file" is available. * * RAMFileClass::Is_Open -- Is the file open? * * RAMFileClass::Open -- Opens a RAM based file for read or write. * * RAMFileClass::Open -- Opens the RAM based file. * * RAMFileClass::RAMFileClass -- Construct a RAM buffer based "file" object. * * RAMFileClass::Read -- Read data from the file. * * RAMFileClass::Seek -- Controls the ram file virtual read position. * * RAMFileClass::Size -- Returns with the size of the ram file. * * RAMFileClass::Write -- Copies data to the ram file. * * RAMFileClass::~RAMFileClass -- Destructor for the RAM file class. * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "FUNCTION.H" #include "ramfile.h" #include /*********************************************************************************************** * RAMFileClass::RAMFileClass -- Construct a RAM buffer based "file" object. * * * * This routine will construct a "file" object that actually is just a front end processor * * for a buffer. Access to the buffer will appear as if it was accessing a file. This * * is different from the caching ability of the buffered file class in that this file * * class has no real file counterpart. Typical use of this is for algorithms that were * * originally designed for file processing, but are now desired to work with a buffer. * * * * INPUT: buffer -- Pointer to the buffer to use for this file. The buffer will already * * contain data if the file is opened for READ. It will be considered * * a scratch buffer if opened for WRITE. If the buffer pointer is NULL * * but the length parameter is not, then a buffer will be allocated * * of the specified length. This case is only useful for opening the * * file for WRITE. * * * * length -- The length of the buffer submitted to this routine. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 07/03/1996 JLB : Created. * *=============================================================================================*/ RAMFileClass::RAMFileClass(void * buffer, int len) : Buffer((char *)buffer), MaxLength(len), Length(len), Offset(0), Access(READ), IsOpen(false), IsAllocated(false) { if (buffer == NULL && len > 0) { Buffer = new char[len]; IsAllocated = true; } } /*********************************************************************************************** * RAMFileClass::~RAMFileClass -- Destructor for the RAM file class. * * * * The destructor will deallocate any buffer that it allocated. Otherwise it does nothing. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 07/03/1996 JLB : Created. * *=============================================================================================*/ RAMFileClass::~RAMFileClass(void) { Close(); if (IsAllocated) { delete [] Buffer; Buffer = NULL; IsAllocated = false; } } /*********************************************************************************************** * RAMFileClass::Create -- Effectively clears the buffer of data. * * * * This routine "clears" the buffer of data. It only makes the buffer appear empty by * * resetting the internal length to zero. * * * * INPUT: none * * * * OUTPUT: Was the file reset in this fashion? * * * * WARNINGS: If the file was open, then resetting by this routine is not allowed. * * * * HISTORY: * * 07/03/1996 JLB : Created. * *=============================================================================================*/ int RAMFileClass::Create(void) { if (!Is_Open()) { Length = 0; return(true); } return(false); } /*********************************************************************************************** * RAMFileClass::Delete -- Effectively clears the buffer of data. * * * * This routine "clears" the buffer of data. It only makes the buffer appear empty by * * resetting the internal length to zero. * * * * INPUT: none * * * * OUTPUT: Was the file reset in this fashion? * * * * WARNINGS: If the file was open, then resetting by this routine is not allowed. * * * * HISTORY: * * 07/03/1996 JLB : Created. * *=============================================================================================*/ int RAMFileClass::Delete(void) { if (!Is_Open()) { Length = 0; return(true); } return(false); } /*********************************************************************************************** * RAMFileClass::Is_Available -- Determines if the "file" is available. * * * * RAM files are always available. * * * * INPUT: none * * * * OUTPUT: TRUE * * * * WARNINGS: none * * * * HISTORY: * * 07/03/1996 JLB : Created. * *=============================================================================================*/ int RAMFileClass::Is_Available(int ) { return(true); } /*********************************************************************************************** * RAMFileClass::Is_Open -- Is the file open? * * * * This answers the question whether the file is open or not. * * * * INPUT: none * * * * OUTPUT: bool; Is the file open? * * * * WARNINGS: none * * * * HISTORY: * * 07/03/1996 JLB : Created. * *=============================================================================================*/ int RAMFileClass::Is_Open(void) const { return(IsOpen); } /*********************************************************************************************** * RAMFileClass::Open -- Opens a RAM based file for read or write. * * * * This routine will open the ram file. The name is meaningless so that parameter is * * ignored. If the access mode is for write, then the pseudo-file can be written until the * * buffer is full. If the file is opened for read, then the buffer is presumed to be full * * of the data to be read. * * * * INPUT: name -- ignored. * * * * access-- The access method to use for the data buffer -- either READ or WRITE. * * * * OUTPUT: bool; Was the open successful? * * * * WARNINGS: none * * * * HISTORY: * * 07/03/1996 JLB : Created. * *=============================================================================================*/ int RAMFileClass::Open(char const * , int access) { return(Open(access)); } /*********************************************************************************************** * RAMFileClass::Open -- Opens the RAM based file. * * * * This will open the ram based file for read or write. If the file is opened for write, * * the the 'file' can be written up to the limit of the buffer's size. If the file is * * opened for read, then the buffer is presumed to hold the data to be read. * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 07/03/1996 JLB : Created. * *=============================================================================================*/ int RAMFileClass::Open(int access) { if (Buffer == NULL || Is_Open()) { return(false); } Offset = 0; Access = access; IsOpen = true; switch (access) { default: case READ: break; case WRITE: Length = 0; break; case READ|WRITE: break; } return(Is_Open()); } /*********************************************************************************************** * RAMFileClass::Read -- Read data from the file. * * * * Use this routine just like a normal file read. It will copy the bytes from the ram * * buffer to the destination specified. When the ram buffer is exhausted, less bytes than * * requested will be read. * * * * INPUT: buffer -- Pointer to the buffer to store the data to. * * * * size -- The number of bytes to 'read' into the specified buffer. * * * * OUTPUT: Returns with the number of bytes copied to the destination buffer. If the number * * of bytes returned is less than requested, then this indicates that the source * * buffer is exhausted. * * * * WARNINGS: The read function only applies to ram 'files' opened for read access. * * * * HISTORY: * * 07/03/1996 JLB : Created. * *=============================================================================================*/ long RAMFileClass::Read(void * buffer, long size) { if (Buffer == NULL || buffer == NULL || size == 0) { return(0); } bool hasopened = false; if (!Is_Open()) { Open(READ); hasopened = true; } else { if ((Access & READ) == 0) { return(0); } } int tocopy = (size < (Length-Offset)) ? size : (Length-Offset); memmove(buffer, &Buffer[Offset], tocopy); Offset += tocopy; if (hasopened) { Close(); } return(tocopy); } /*********************************************************************************************** * RAMFileClass::Seek -- Controls the ram file virtual read position. * * * * This routine will move the read/write position of the ram file to the location specified * * by the offset and direction parameters. It functions similarly to the regular file * * seek method. * * * * INPUT: pos -- The signed offset from the home position specified by the "dir" * * parameter. * * * * dir -- The home position to base the position offset on. This will either be * * the start of the file, the end of the file, or the current read/write * * position. * * * * OUTPUT: Returns with the new file position. * * * * WARNINGS: none * * * * HISTORY: * * 07/03/1996 JLB : Created. * *=============================================================================================*/ long RAMFileClass::Seek(long pos, int dir) { if (Buffer == NULL || !Is_Open()) { return(Offset); } int maxoffset = Length; if ((Access & WRITE) != 0) { maxoffset = MaxLength; } switch (dir) { case SEEK_CUR: Offset += pos; break; case SEEK_SET: Offset = 0 + pos; break; case SEEK_END: Offset = maxoffset + pos; break; } if (Offset < 0) Offset = 0; if (Offset > maxoffset) Offset = maxoffset; if (Offset > Length) { Length = Offset; } return(Offset); } /*********************************************************************************************** * RAMFileClass::Size -- Returns with the size of the ram file. * * * * This will return the size of the 'real' data in the ram file. The real data is either * * the entire buffer, if opened for READ, or just the written data if opened for WRITE. * * * * INPUT: none * * * * OUTPUT: Returns with the number of bytes that the ram file system considers to be valid * * data of the 'file'. * * * * WARNINGS: none * * * * HISTORY: * * 07/03/1996 JLB : Created. * *=============================================================================================*/ long RAMFileClass::Size(void) { return(Length); } /*********************************************************************************************** * RAMFileClass::Write -- Copies data to the ram file. * * * * This function similarly to the regular write operation supported for files. It copies * * the data specified to the current write position in the ram file. * * * * INPUT: buffer -- Pointer to the data to be written. * * * * size -- The number of bytes to write to the file. * * * * OUTPUT: Returns with the actual number of bytes written. This will be less than requested * * if the buffer is exhausted of space prematurely. * * * * WARNINGS: none * * * * HISTORY: * * 07/03/1996 JLB : Created. * *=============================================================================================*/ long RAMFileClass::Write(void const * buffer, long size) { if (Buffer == NULL || buffer == NULL || size == 0) { return(0); } bool hasopened = false; if (!Is_Open()) { Open(WRITE); hasopened = true; } else { if ((Access & WRITE) == 0) { return(0); } } int maxwrite = MaxLength - Offset; int towrite = (size < maxwrite) ? size : maxwrite; memmove(&Buffer[Offset], buffer, towrite); Offset += towrite; if (Offset > Length) { Length = Offset; } if (hasopened) { Close(); } return(towrite); } /*********************************************************************************************** * RAMFileClass::Close -- This will 'close' the ram file. * * * * Closing a ram file actually does nothing but record that it is now closed. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 07/03/1996 JLB : Created. * *=============================================================================================*/ void RAMFileClass::Close(void) { IsOpen = false; }