mirror of
https://github.com/electronicarts/CnC_Red_Alert.git
synced 2025-12-15 23:21:40 -05:00
Initial commit of Command & Conquer Red Alert source code.
This commit is contained in:
611
LAUNCHER/WSTRING.CPP
Normal file
611
LAUNCHER/WSTRING.CPP
Normal file
@@ -0,0 +1,611 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/****************************************************************************\
|
||||
* 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: Carpenter (The RedAlert ladder creator)
|
||||
File Name : string.cpp
|
||||
Author : Neal Kettler
|
||||
Start Date : June 1, 1997
|
||||
Last Update : June 17, 1997
|
||||
|
||||
A fairly typical string class. This string class always copies any input
|
||||
string to it's own memory (for assignment or construction).
|
||||
\***************************************************************************/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wstring.h"
|
||||
|
||||
Wstring::Wstring():str(NULL)
|
||||
{ }
|
||||
|
||||
Wstring::Wstring(IN char *string):str(NULL)
|
||||
{ set(string); }
|
||||
|
||||
Wstring::Wstring(IN const Wstring &other):str(NULL)
|
||||
{
|
||||
if (other.str!=NULL)
|
||||
{
|
||||
str=new char[strlen(other.str)+1];
|
||||
strcpy(str,other.str);
|
||||
}
|
||||
}
|
||||
|
||||
Wstring::~Wstring()
|
||||
{ clear(); }
|
||||
|
||||
bit8 Wstring::operator==(IN char *other)
|
||||
{
|
||||
if ((str==NULL)&&(other==NULL))
|
||||
return(TRUE);
|
||||
if(strcmp(str, other) != 0)
|
||||
return(FALSE);
|
||||
else
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
bit8 Wstring::operator==(IN Wstring &other)
|
||||
{
|
||||
if((str == NULL) && (other.str == NULL))
|
||||
return(TRUE);
|
||||
|
||||
if((str == NULL) || (other.str == NULL))
|
||||
return(FALSE);
|
||||
|
||||
if(strcmp(str, other.str) != 0)
|
||||
return(FALSE);
|
||||
else
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
bit8 Wstring::operator!=(IN char *other)
|
||||
{
|
||||
if(strcmp(str, other) != 0)
|
||||
return(TRUE);
|
||||
else
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
|
||||
bit8 Wstring::operator!=(IN Wstring &other)
|
||||
{
|
||||
if((str == NULL) && (other.str == NULL))
|
||||
return(FALSE);
|
||||
|
||||
if((str == NULL) || (other.str == NULL))
|
||||
return(TRUE);
|
||||
|
||||
if(strcmp(str, other.str) != 0)
|
||||
return(TRUE);
|
||||
else
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
|
||||
Wstring &Wstring::operator=(char *other)
|
||||
{
|
||||
set(other);
|
||||
return(*this);
|
||||
}
|
||||
|
||||
|
||||
Wstring &Wstring::operator=(IN Wstring &other)
|
||||
{
|
||||
if(*this == other)
|
||||
return(*this);
|
||||
|
||||
set(other.get());
|
||||
return(*this);
|
||||
}
|
||||
|
||||
|
||||
bit8 Wstring::cat(IN char *s)
|
||||
{
|
||||
char *oldStr;
|
||||
uint32 len;
|
||||
|
||||
if (s==NULL) // it's OK to cat nothing
|
||||
return(TRUE);
|
||||
|
||||
// Save the contents of the string.
|
||||
oldStr = str;
|
||||
|
||||
// Determine the length of the resultant string.
|
||||
len = strlen(s) + 1;
|
||||
if(oldStr)
|
||||
len += strlen(oldStr);
|
||||
|
||||
// Allocate memory for the new string.
|
||||
|
||||
if(!(str = new char[(len * sizeof(char))]))
|
||||
{
|
||||
str = oldStr;
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
// Copy the contents of the old string and concatenate the passed
|
||||
// string.
|
||||
if(oldStr) strcpy(str, oldStr);
|
||||
else str[0] = 0;
|
||||
|
||||
strcat(str, s);
|
||||
|
||||
// delete the old string.
|
||||
if(oldStr)
|
||||
delete[](oldStr);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
bit8 Wstring::cat(uint32 size, IN char *s)
|
||||
{
|
||||
char *oldStr;
|
||||
uint32 len;
|
||||
|
||||
// Save the contents of the string.
|
||||
oldStr = str;
|
||||
|
||||
// Determine the length of the resultant string.
|
||||
len = size + 1;
|
||||
if(oldStr)
|
||||
len += strlen(oldStr);
|
||||
|
||||
// Allocate memory for the new string.
|
||||
if(!(str = new char[(len * sizeof(char))]))
|
||||
{
|
||||
str = oldStr;
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
// Copy the contents of the old string and concatenate the passed
|
||||
// string.
|
||||
if(oldStr)
|
||||
strcpy(str, oldStr);
|
||||
else
|
||||
str[0] = 0;
|
||||
|
||||
strncat(str, s, size);
|
||||
|
||||
// delete the old string.
|
||||
if(oldStr)
|
||||
delete[](oldStr);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
bit8 Wstring::cat(IN Wstring &other)
|
||||
{
|
||||
return cat(other.get());
|
||||
}
|
||||
|
||||
Wstring &Wstring::operator+=(IN char *string)
|
||||
{
|
||||
cat(string);
|
||||
return(*this);
|
||||
}
|
||||
|
||||
Wstring &Wstring::operator+=(IN Wstring &other)
|
||||
{
|
||||
cat(other.get());
|
||||
return(*this);
|
||||
}
|
||||
|
||||
Wstring Wstring::operator+(IN char *string)
|
||||
{
|
||||
Wstring temp = *this;
|
||||
temp.cat(string);
|
||||
return(temp);
|
||||
}
|
||||
|
||||
Wstring Wstring::operator+(IN Wstring &s)
|
||||
{
|
||||
Wstring temp = *this;
|
||||
temp.cat(s);
|
||||
return(temp);
|
||||
}
|
||||
|
||||
//
|
||||
// This function deletes 'count' characters indexed by `pos' from the Wstring.
|
||||
// If `pos'+'count' is > the length of the array, the last 'count' characters
|
||||
// of the string are removed. If an error occurs, FALSE is returned.
|
||||
// Otherwise, TRUE is returned. Note: count has a default value of 1.
|
||||
//
|
||||
//
|
||||
char Wstring::remove(sint32 pos,sint32 count)
|
||||
{
|
||||
char *s;
|
||||
sint32 len;
|
||||
|
||||
if (!str)
|
||||
return(FALSE);
|
||||
|
||||
len = (sint32)strlen(str);
|
||||
|
||||
if(pos+count > len)
|
||||
pos = len - count;
|
||||
if (pos < 0)
|
||||
{
|
||||
count+=pos; // If they remove before 0, ignore up till beginning
|
||||
pos=0;
|
||||
}
|
||||
if (count<=0)
|
||||
return(FALSE);
|
||||
|
||||
if(!(s = new char[len-count+1]))
|
||||
{
|
||||
//ErrorMessage(SET_EM, "Insufficient memory to modify Wstring.");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
///////DBGMSG("Wstring::remove POS: "<<pos<<" LEN: "<<len);
|
||||
|
||||
// put nulls on both ends of substring to be removed
|
||||
str[pos] = 0;
|
||||
str[pos+count-1] = 0;
|
||||
|
||||
strcpy(s, str);
|
||||
strcat(s, &(str[pos + count]));
|
||||
delete[](str);
|
||||
str = s;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
// Remove all instances of a char from the string
|
||||
bit8 Wstring::removeChar(char c)
|
||||
{
|
||||
int len=0;
|
||||
char *cptr=NULL;
|
||||
bit8 removed=FALSE;
|
||||
|
||||
if (str==NULL)
|
||||
return(FALSE);
|
||||
|
||||
len=strlen(str);
|
||||
while ((cptr=strchr(str,c)) !=NULL)
|
||||
{
|
||||
memmove(cptr,cptr+1,len-1-((int)(cptr-str)));
|
||||
len--;
|
||||
str[len]=0;
|
||||
removed=TRUE;
|
||||
}
|
||||
if (removed)
|
||||
{
|
||||
char *newStr=new char[strlen(str)+1];
|
||||
strcpy(newStr,str);
|
||||
delete[](str);
|
||||
str=newStr;
|
||||
}
|
||||
return(removed);
|
||||
}
|
||||
|
||||
void Wstring::removeSpaces(void)
|
||||
{
|
||||
removeChar(' ');
|
||||
removeChar('\t');
|
||||
}
|
||||
|
||||
void Wstring::clear(void)
|
||||
{
|
||||
if(str)
|
||||
delete[](str);
|
||||
str=NULL;
|
||||
}
|
||||
|
||||
void Wstring::setSize(sint32 size)
|
||||
{
|
||||
clear();
|
||||
if (size<0)
|
||||
return;
|
||||
str=new char[size];
|
||||
memset(str,0,size);
|
||||
}
|
||||
|
||||
void Wstring::cellCopy(char *dest, uint32 len)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
strncpy(dest, str, len);
|
||||
for(i = (uint32)strlen(str); i < len; i++)
|
||||
dest[i] = ' ';
|
||||
dest[len] = 0;
|
||||
}
|
||||
|
||||
char *Wstring::get(void)
|
||||
{
|
||||
if(!str)
|
||||
return "";
|
||||
return str;
|
||||
}
|
||||
|
||||
char Wstring::get(uint32 index)
|
||||
{
|
||||
if(index < strlen(str))
|
||||
return str[index];
|
||||
return(0);
|
||||
}
|
||||
|
||||
uint32 Wstring::length(void)
|
||||
{
|
||||
if(str == NULL)
|
||||
return(0);
|
||||
return((uint32)strlen(str));
|
||||
}
|
||||
|
||||
|
||||
// Insert at given position and shift old stuff to right
|
||||
bit8 Wstring::insert(char *instring, uint32 pos)
|
||||
{
|
||||
if (str==NULL)
|
||||
return(set(instring));
|
||||
if (pos>strlen(str))
|
||||
pos=strlen(str);
|
||||
char *newstr=new char[strlen(str)+strlen(instring)+1];
|
||||
memset(newstr,0,strlen(str)+strlen(instring)+1);
|
||||
strcpy(newstr,str);
|
||||
// move the old data out of the way
|
||||
int bytes=strlen(str)+1-pos;
|
||||
memmove(newstr+pos+strlen(instring),newstr+pos,bytes);
|
||||
// move the new data into place
|
||||
memmove(newstr+pos,instring,strlen(instring));
|
||||
delete[](str);
|
||||
str=newstr;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
// This function inserts the character specified by `k' into the string at the
|
||||
// position indexed by `pos'. If `pos' is >= the length of the string, it is
|
||||
// appended to the string. If an error occurs, FALSE is returned. Otherwise,
|
||||
// TRUE is returned.
|
||||
bit8 Wstring::insert(char k, uint32 pos)
|
||||
{
|
||||
char *s;
|
||||
uint32 len;
|
||||
char c[2];
|
||||
|
||||
if(!str)
|
||||
{
|
||||
c[0] = k;
|
||||
c[1] = 0;
|
||||
return(set(c));
|
||||
}
|
||||
|
||||
len = (uint32)strlen(str);
|
||||
|
||||
if(pos > len)
|
||||
pos = len;
|
||||
|
||||
if(!(s = (char *)new char[(len + 2)]))
|
||||
{
|
||||
//ErrorMessage(SET_EM, "Insufficient memory to modify Wstring.");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
c[0] = str[pos];
|
||||
str[pos] = 0;
|
||||
c[1] = 0;
|
||||
strcpy(s, str);
|
||||
str[pos] = c[0];
|
||||
c[0] = k;
|
||||
strcat(s, c);
|
||||
strcat(s, &(str[pos]));
|
||||
delete[](str);
|
||||
str = s;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
// This function replaces any occurences of the string pointed to by
|
||||
// `replaceThis' with the string pointed to by `withThis'. If an error
|
||||
// occurs, FALSE is returned. Otherwise, TRUE is returned.
|
||||
bit8 Wstring::replace(char *replaceThis, char *withThis)
|
||||
{
|
||||
Wstring dest;
|
||||
char *foundStr, *src;
|
||||
uint32 len;
|
||||
|
||||
src=get();
|
||||
while(src && src[0])
|
||||
{
|
||||
foundStr = strstr(src, replaceThis);
|
||||
if(foundStr)
|
||||
{
|
||||
len = (uint32)foundStr - (uint32)src;
|
||||
if(len)
|
||||
{
|
||||
if(!dest.cat(len, src))
|
||||
return(FALSE);
|
||||
}
|
||||
if(!dest.cat(withThis))
|
||||
return(FALSE);
|
||||
src = foundStr + strlen(replaceThis);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!dest.cat(src))
|
||||
return(FALSE);
|
||||
|
||||
src=NULL;
|
||||
}
|
||||
}
|
||||
return(set(dest.get()));
|
||||
}
|
||||
|
||||
|
||||
bit8 Wstring::set(IN char *s)
|
||||
{
|
||||
uint32 len;
|
||||
|
||||
clear();
|
||||
|
||||
len = (uint32)strlen(s) + 1;
|
||||
|
||||
if(!(str = new char[len]))
|
||||
{
|
||||
//ErrorMessage(SET_EM, "Insufficient memory to set Wstring.");
|
||||
return(FALSE);
|
||||
}
|
||||
strcpy(str, s);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
bit8 Wstring::set(char c, uint32 index)
|
||||
{
|
||||
if(index >= (uint32)strlen(str))
|
||||
return FALSE;
|
||||
|
||||
str[index] = c;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
char Wstring::set(uint32 size, IN char *string)
|
||||
{
|
||||
uint32 len;
|
||||
|
||||
clear();
|
||||
len = size + 1;
|
||||
|
||||
if(!(str = new char[len]))
|
||||
{
|
||||
//ErrorMessage(SET_EM, "Insufficient memory to set Wstring.");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
// Copy the bytes in the string, and NULL-terminate it.
|
||||
strncpy(str, string, size);
|
||||
str[size] = 0;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
// This function converts all alphabetical characters in the string to lower
|
||||
// case.
|
||||
void Wstring::toLower(void)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
for(i = 0; i < length(); i++)
|
||||
{
|
||||
if((str[i] >= 'A') && (str[i] <= 'Z'))
|
||||
str[i] = tolower(str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This function converts all alphabetical characters in the string to upper
|
||||
// case.
|
||||
void Wstring::toUpper(void)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
for(i = 0; i < length(); i++)
|
||||
{
|
||||
if((str[i] >= 'a') && (str[i] <= 'z'))
|
||||
str[i] = toupper(str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This function truncates the string so its length will match the specified
|
||||
// `len'. If an error occurs, FALSE is returned. Otherwise, TRUE is returned.
|
||||
bit8 Wstring::truncate(uint32 len)
|
||||
{
|
||||
Wstring tmp;
|
||||
if(!tmp.set(len, get()) || !set(tmp.get()))
|
||||
return(FALSE);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
// Truncate the string after the character 'c' (gets rid of 'c' as well)
|
||||
// Do nothing if 'c' isn't in the string
|
||||
bit8 Wstring::truncate(char c)
|
||||
{
|
||||
sint32 len;
|
||||
|
||||
if (str==NULL)
|
||||
return(FALSE);
|
||||
|
||||
char *cptr=strchr(str,c);
|
||||
if (cptr==NULL)
|
||||
return(FALSE);
|
||||
len=(sint32)(cptr-str);
|
||||
truncate((uint32)len);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
// Get a token from this string that's seperated by one or more
|
||||
// chars from the 'delim' string , start at offset & return offset
|
||||
sint32 Wstring::getToken(int offset,char *delim,Wstring &out)
|
||||
{
|
||||
int i;
|
||||
sint32 start;
|
||||
sint32 stop;
|
||||
for (i=offset; i<length(); i++) {
|
||||
if(strchr(delim,str[i])==NULL)
|
||||
break;
|
||||
}
|
||||
if (i>=length())
|
||||
return(-1);
|
||||
start=i;
|
||||
|
||||
for (; i<length(); i++) {
|
||||
if(strchr(delim,str[i])!=NULL)
|
||||
break;
|
||||
}
|
||||
stop=i-1;
|
||||
out.set(str+start);
|
||||
out.truncate((uint32)stop-start+1);
|
||||
return(stop+1);
|
||||
}
|
||||
|
||||
// Get the first line of text after offset. Lines are terminated by '\r\n' or '\n'
|
||||
sint32 Wstring::getLine(int offset, Wstring &out)
|
||||
{
|
||||
int i;
|
||||
sint32 start;
|
||||
sint32 stop;
|
||||
|
||||
start=i=offset;
|
||||
if (start >= length())
|
||||
return(-1);
|
||||
|
||||
for (; i<length(); i++) {
|
||||
if(strchr("\r\n",str[i])!=NULL)
|
||||
break;
|
||||
}
|
||||
stop=i;
|
||||
if ((str[stop]=='\r')&&(str[stop+1]=='\n'))
|
||||
stop++;
|
||||
|
||||
out.set(str+start);
|
||||
out.truncate((uint32)stop-start+1);
|
||||
return(stop+1);
|
||||
}
|
||||
Reference in New Issue
Block a user