CnC_Remastered_Collection/REDALERT/RAMFILE.CPP
PG-SteveT 03416d24e1 Initial Source Code commit
Initial commit of original Tiberian Dawn and Red Alert source code converted to build as DLLs, and compatible with the release version of Command & Conquer Remastered.
2020-05-27 12:16:20 -07:00

473 lines
27 KiB
C++

//
// 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 <string.h>
/***********************************************************************************************
* 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;
}