Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
wstring.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/****************************************************************************\
20* 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 *
21******************************************************************************
22Project Name: Carpenter (The RedAlert ladder creator)
23File Name : string.cpp
24Author : Neal Kettler
25Start Date : June 1, 1997
26Last Update : June 17, 1997
27
28A fairly typical string class. This string class always copies any input
29string to it's own memory (for assignment or construction).
30\***************************************************************************/
31
32#include <ctype.h>
33#include <stdlib.h>
34#include <stdio.h>
35#include <string.h>
36#include <stdarg.h>
37
38#include "wstring.h"
39
40#define PADSIZE 32 // include a little padding on alloc for future growth
41
42Wstring::Wstring() : str(NULL), strsize(0)
43{ }
44
45Wstring::Wstring(IN char *string):str(NULL), strsize(0)
46{ set(string); }
47
48Wstring::Wstring(IN Wstring &other):str(NULL), strsize(0)
49{
50 if (other.str!=NULL)
51 {
52 str=new char[strlen(other.str)+PADSIZE+1];
53 strsize=strlen(other.str)+PADSIZE+1;
54 strcpy(str,other.str);
55 }
56}
57
59{
60 clear();
61}
62
64{
65 if (str == NULL && other.str == NULL)
66 return false;
67
68 if (str == NULL)
69 return true;
70
71 return ( strcmp(str, other.str) < 0 );
72}
73
74bit8 Wstring::operator==(IN char *other) RO
75{
76 if ((str==NULL)&&(other==NULL))
77 return(TRUE);
78 if(strcmp(str, other) != 0)
79 return(FALSE);
80 else
81 return(TRUE);
82}
83
85{
86 if((str == NULL) && (other.str == NULL))
87 return(TRUE);
88
89 if((str == NULL) || (other.str == NULL))
90 return(FALSE);
91
92 if(strcmp(str, other.str) != 0)
93 return(FALSE);
94 else
95 return(TRUE);
96}
97
98
99bit8 Wstring::operator!=(IN char *other) RO
100{
101 if(strcmp(str, other) != 0)
102 return(TRUE);
103 else
104 return(FALSE);
105}
106
107
109{
110 if((str == NULL) && (other.str == NULL))
111 return(FALSE);
112
113 if((str == NULL) || (other.str == NULL))
114 return(TRUE);
115
116 if(strcmp(str, other.str) != 0)
117 return(TRUE);
118 else
119 return(FALSE);
120}
121
122
124{
125 set(other);
126 return(*this);
127}
128
129
131{
132 if(*this == other)
133 return(*this);
134
135 set(other.get());
136 return(*this);
137}
138
139
140bit8 Wstring::cat(IN char *s)
141{
142 uint32 len;
143
144 if (s==NULL) // it's OK to cat nothing
145 return(TRUE);
146
147 // Determine the length of the resultant string.
148 len = strlen(s) + 1;
149 if(str)
150 len += strlen(str);
151
152 // Space check
153 strgrow(len);
154
155 strcat(str, s);
156
157 return(TRUE);
158}
159
160
161bit8 Wstring::cat(uint32 size, IN char *s)
162{
163 uint32 len;
164
165 // Determine the length of the resultant string.
166 len = size + 1;
167 if(str)
168 len += strlen(str);
169
170 // Allocate memory for the new string.
171 strgrow(len);
172
173 strncat(str, s, size);
174 str[len-1]=0; // make sure null term'd
175
176 return(TRUE);
177}
178
180{
181 return cat(other.get());
182}
183
184Wstring &Wstring::operator+=(IN char *string)
185{
186 cat(string);
187 return(*this);
188}
189
191{
192 cat(other.get());
193 return(*this);
194}
195
196Wstring Wstring::operator+(IN char *string)
197{
198 Wstring temp = *this;
199 temp.cat(string);
200 return(temp);
201}
202
204{
205 Wstring temp = *this;
206 temp.cat(s);
207 return(temp);
208}
209
210//
211// This function deletes 'count' characters indexed by `pos' from the Wstring.
212// If `pos'+'count' is > the length of the array, the last 'count' characters
213// of the string are removed. If an error occurs, FALSE is returned.
214// Otherwise, TRUE is returned. Note: count has a default value of 1.
215//
216//
217char Wstring::remove(sint32 pos,sint32 count)
218{
219 //char *s;
220 sint32 len;
221
222 len = (sint32)strlen(str);
223
224 if(pos+count > len)
225 pos = len - count;
226 if (pos < 0)
227 {
228 count+=pos; // If they remove before 0, ignore up till beginning
229 pos=0;
230 }
231 if (count<=0)
232 return(FALSE);
233
234 memmove(str+pos,str+pos+count,len-pos-count+1);
235
236 return(TRUE);
237}
238
239// Remove all instances of a char from the string
241{
242 int len=0;
243 char *cptr=NULL;
244 bit8 removed=FALSE;
245
246 if (str==NULL)
247 return(FALSE);
248
249 len=strlen(str);
250 while ((cptr=strchr(str,c)) !=NULL)
251 {
252 memmove(cptr,cptr+1,len-1-((int)(cptr-str)));
253 len--;
254 str[len]=0;
255 removed=TRUE;
256 }
257 return(removed);
258}
259
260void Wstring::removeSpaces(void)
261{
262 removeChar(' ');
263 removeChar('\t');
264}
265
266void Wstring::clear(void)
267{
268 if(str)
269 delete[](str);
270 strsize=0;
271 str=NULL;
272}
273
274// This is usually used for raw storage instead of string ops...
275void Wstring::setSize(sint32 size)
276{
277 clear();
278 if (size<0)
279 return;
280
281 str=new char[size];
282 strsize=size;
283 memset(str,0,size);
284}
285
286void Wstring::cellCopy(char *dest, uint32 len)
287{
288 uint32 i;
289
290 strncpy(dest, str, len);
291 for(i = (uint32)strlen(str); i < len; i++)
292 dest[i] = ' ';
293 dest[len] = 0;
294}
295
296char *Wstring::get(void) RO
297{
298 if(!str)
299 return "";
300 return str;
301}
302
303char Wstring::get(uint32 index) RO
304{
305 if(index < strlen(str))
306 return str[index];
307 return(0);
308}
309
311{
312 if(str == NULL)
313 return(0);
314 return((uint32)strlen(str));
315}
316
317
318// Insert at given position and shift old stuff to right
319bit8 Wstring::insert(char *instring, uint32 pos)
320{
321 if (str==NULL)
322 return(set(instring));
323 if (pos>strlen(str))
324 pos=strlen(str);
325
326 strgrow(strlen(str)+strlen(instring)+1);
327 memmove(str+pos+strlen(instring),str+pos,strlen(str)-pos+1);
328 memmove(str+pos,instring,strlen(instring));
329
330 return(TRUE);
331}
332
333// This function inserts the character specified by `k' into the string at the
334// position indexed by `pos'. If `pos' is >= the length of the string, it is
335// appended to the string. If an error occurs, FALSE is returned. Otherwise,
336// TRUE is returned.
337bit8 Wstring::insert(char k, uint32 pos)
338{
339 char temp[2];
340 temp[0]=k;
341 temp[1]=0;
342 return(insert(temp,pos));
343}
344
345
346// Joe Howes (05/19/2000): This function inserts commas to nicely format a
347// large number (i.e. 1234567890 -> 1,234,567,890). It doesn't really care
348// if the string is really a number or not.
350{
351 int len = length();
352 int accum = 3 - (len % 3);
353 int numcommas = 0;
354
355
356 if( accum == 3 ) accum = -1;
357 for(int i = 0; i < len; i++)
358 {
359 if( accum == 3 )
360 {
361 insert(',', i + numcommas);
362 numcommas++;
363 }
364 accum = ( accum == 3 || accum == -1 ) ? 1 : accum + 1;
365 }
366
367 return(TRUE);
368}
369
370
371// This function replaces any occurences of the string pointed to by
372// `replaceThis' with the string pointed to by `withThis'. If an error
373// occurs, FALSE is returned. Otherwise, TRUE is returned.
374bit8 Wstring::replace(IN char *replaceThis,IN char *withThis)
375{
376 Wstring dest;
377 char *foundStr, *src;
378 uint32 len;
379
380 src=get();
381 while(src && src[0])
382 {
383 foundStr = strstr(src, replaceThis);
384 if(foundStr)
385 {
386 len = (uint32)foundStr - (uint32)src;
387 if(len)
388 {
389 if(!dest.cat(len, src))
390 return(FALSE);
391 }
392 if(!dest.cat(withThis))
393 return(FALSE);
394 src = foundStr + strlen(replaceThis);
395 }
396 else
397 {
398 if(!dest.cat(src))
399 return(FALSE);
400
401 src=NULL;
402 }
403 }
404 return(set(dest.get()));
405}
406
407
408bit8 Wstring::set(IN char *s)
409{
410 //uint32 len;
411
412 strgrow(strlen(s)+1);
413 strcpy(str,s);
414
415 return(TRUE);
416}
417
418
419bit8 Wstring::set(char c, uint32 index)
420{
421 if(index >= (uint32)strlen(str))
422 return FALSE;
423
424 str[index] = c;
425
426 return TRUE;
427}
428
429
430char Wstring::set(uint32 size, IN char *string)
431{
432 //uint32 len;
433
434 strgrow(size+1);
435 strncpy(str,string,size);
436 str[size]=0;
437
438 return(TRUE);
439}
440
441
442// Added by Joe Howes. Takes a printf formatted string and a set of args.
443// The expanded string must not exceed 1k or twice the length of the format
444// string, whichever is larger. It would probably be better to traverse
445// the format string and properly calculate, the length so this will
446// work in all cases, but this should be good enough for 99% of Wstring usage.
448{
449 if( msg == NULL || strlen(msg) <= 0 ) return FALSE;
450
451 char* string;
452 va_list args;
453 int len = (strlen(msg) < 1024) ? 1024 : (strlen(msg)*2);
454
455 string = new char[len];
456 va_start(args, msg);
457 vsprintf(string, msg, args);
458 va_end(args);
459 set(string);
460 delete[] string;
461 return(TRUE);
462}
463
464
465// This function converts all alphabetical characters in the string to lower
466// case.
467void Wstring::toLower(void)
468{
469 uint32 i;
470 int strlength=length();
471
472 for(i = 0; i < (uint32)strlength; i++)
473 {
474 if((str[i] >= 'A') && (str[i] <= 'Z'))
475 str[i] = (sint8)tolower(str[i]);
476 }
477}
478
479
480// This function converts all alphabetical characters in the string to upper
481// case.
482void Wstring::toUpper(void)
483{
484 uint32 i;
485 int strlength=length();
486
487 for(i = 0; i < (uint32)strlength; i++)
488 {
489 if((str[i] >= 'a') && (str[i] <= 'z'))
490 str[i] = (sint8)toupper(str[i]);
491 }
492}
493
494
495// This function truncates the string so its length will match the specified
496// `len'. If an error occurs, FALSE is returned. Otherwise, TRUE is returned.
498{
499 strgrow(len+1);
500 str[len]=0;
501 return(TRUE);
502}
503
504// Truncate the string after the character 'c' (gets rid of 'c' as well)
505// Do nothing if 'c' isn't in the string
507{
508 sint32 len;
509
510 if (str==NULL)
511 return(FALSE);
512
513 char *cptr=strchr(str,c);
514 if (cptr==NULL)
515 return(FALSE);
516 len=(sint32)(cptr-str);
517 truncate((uint32)len);
518 return(TRUE);
519}
520
521// Get a token from this string that's seperated by one or more
522// chars from the 'delim' string , start at offset & return offset
523sint32 Wstring::getToken(int offset,char *delim,Wstring &out) RO
524{
525 int i;
526 sint32 start;
527 sint32 stop;
528
529 if (offset<0) // check for bad input
530 return(-1);
531
532 for (i=offset; i<(int)length(); i++) {
533 if(strchr(delim,str[i])==NULL)
534 break;
535 }
536 if (i>=(int)length())
537 return(-1);
538 start=i;
539
540 for (; i<(int)length(); i++) {
541 if(strchr(delim,str[i])!=NULL)
542 break;
543 }
544 stop=i-1;
545 out.set(str+start);
546 out.truncate((uint32)stop-start+1);
547 return(stop+1);
548}
549
550// Get the first line of text after offset. Lines are terminated by '\r\n' or '\n'
551sint32 Wstring::getLine(int offset, Wstring &out)
552{
553 int i;
554 sint32 start;
555 sint32 stop;
556
557 start=i=offset;
558 if (start >= (sint32)length())
559 return(-1);
560
561 for (; i<(int)length(); i++) {
562 if(strchr("\r\n",str[i])!=NULL)
563 break;
564 }
565 stop=i;
566 if ((str[stop]=='\r')&&(str[stop+1]=='\n'))
567 stop++;
568
569 out.set(str+start);
570 out.truncate((uint32)stop-start+1);
571 return(stop+1);
572}
573
574//
575// Make sure there's AT LEAST length bytes in this string object
576//
578{
579 if (str==NULL)
580 {
581 str=new char[length+PADSIZE];
582 str[0]=0;
583 strsize=length+PADSIZE;
584 return;
585 }
586 else if (strsize >= length) // no need to alloc more data
587 return;
588 else // bah, gotta grow...
589 {
590 char *newstr=new char[length+PADSIZE];
591 strsize=length+PADSIZE;
592 strcpy(newstr,str);
593 delete[](str);
594 str=newstr;
595 return;
596 }
597}
#define NULL
Definition BaseType.h:92
#define TRUE
Definition BaseType.h:109
#define FALSE
Definition BaseType.h:113
char bit8
Definition wstypes.h:61
#define IN
Definition wstypes.h:57
signed char sint8
Definition bittype.h:49
unsigned long uint32
Definition bittype.h:46
signed long sint32
Definition bittype.h:51
uint32 length(void)
Definition wstring.cpp:350
bit8 operator==(IN char *other)
Definition wstring.cpp:57
void strgrow(int length)
Definition wstring.cpp:577
void cellCopy(OUT char *dest, uint32 len)
void clear(void)
Definition wstring.cpp:310
bit8 beautifyNumber()
Definition wstring.cpp:349
bit8 removeChar(char c)
Definition wstring.cpp:277
char remove(sint32 pos, sint32 count)
Definition wstring.cpp:236
bool operator<(IN Wstring &other) RO
Definition wstring.cpp:63
void toLower(void)
Definition wstring.cpp:511
~Wstring()
Definition wstring.cpp:54
bit8 cat(IN char *string)
Definition wstring.cpp:123
void toUpper(void)
Definition wstring.cpp:525
bit8 operator!=(IN char *other)
Definition wstring.cpp:82
void setSize(sint32 bytes)
Definition wstring.cpp:317
Wstring & operator+=(IN char *other)
Definition wstring.cpp:203
char * get(void)
Definition wstring.cpp:336
void removeSpaces(void)
Definition wstring.cpp:304
char setFormatted(IN char *str,...)
Definition wstring.cpp:447
char set(IN char *str)
Definition wstring.cpp:458
Wstring & operator=(IN char *other)
Definition wstring.cpp:123
Wstring operator+(IN char *other)
Definition wstring.cpp:215
bit8 truncate(uint32 len)
Definition wstring.cpp:539
bit8 insert(char c, uint32 pos)
Definition wstring.cpp:382
sint32 getLine(int offset, Wstring &out)
Definition wstring.cpp:590
Wstring()
Definition wstring.cpp:39
sint32 getToken(int offset, char *delim, Wstring &out)
Definition wstring.cpp:566
bit8 replace(IN char *replaceThis, IN char *withThis)
Definition wstring.cpp:374
#define PADSIZE
Definition wstring.cpp:40
#define RO
Definition wstypes.h:92
MSG msg
Definition patch.cpp:409