Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
widestring.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 ***********************************************************************************************
22 * *
23 * Project Name : WWSaveLoad *
24 * *
25 * $Archive:: /Commando/Code/wwlib/widestring.cpp $*
26 * *
27 * Author:: Patrick Smith *
28 * *
29 * $Modtime:: 2/06/02 5:27p $*
30 * *
31 * $Revision:: 13 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
36
37#pragma warning(disable : 4514)
38
39#include "widestring.h"
40#include "win.h"
41#include <stdio.h>
42
43
45// Static member initialzation
47
48int WideStringClass::m_UsedTempStringCount = 0;
49
50FastCriticalSectionClass WideStringClass::m_TempMutex;
51
52WCHAR WideStringClass::m_NullChar = 0;
53WCHAR * WideStringClass::m_EmptyString = &m_NullChar;
54
55//
56// A trick to optimize strings that are allocated from the stack and used only temporarily
57//
58char WideStringClass::m_TempString1[WideStringClass::MAX_TEMP_BYTES];
59char WideStringClass::m_TempString2[WideStringClass::MAX_TEMP_BYTES];
60char WideStringClass::m_TempString3[WideStringClass::MAX_TEMP_BYTES];
61char WideStringClass::m_TempString4[WideStringClass::MAX_TEMP_BYTES];
62
63WCHAR * WideStringClass::m_FreeTempPtr[MAX_TEMP_STRING] = {
64 reinterpret_cast<WCHAR *> (m_TempString1 + sizeof (WideStringClass::_HEADER)),
65 reinterpret_cast<WCHAR *> (m_TempString2 + sizeof (WideStringClass::_HEADER)),
66 reinterpret_cast<WCHAR *> (m_TempString3 + sizeof (WideStringClass::_HEADER)),
67 reinterpret_cast<WCHAR *> (m_TempString4 + sizeof (WideStringClass::_HEADER))
68};
69
70WCHAR * WideStringClass::m_ResTempPtr[MAX_TEMP_STRING] = {
71 NULL,
72 NULL,
73 NULL,
74 NULL
75};
76
77
79//
80// Get_String
81//
83void
84WideStringClass::Get_String (int length, bool is_temp)
85{
86 if (!is_temp && length <= 1) {
87 m_Buffer = m_EmptyString;
88 } else {
89
90 WCHAR *string = NULL;
91
92 //
93 // Should we attempt to use a temp buffer for this string?
94 //
95 if (is_temp && length < MAX_TEMP_LEN && m_UsedTempStringCount < MAX_TEMP_STRING) {
96
97 //
98 // Make sure no one else is requesting a temp pointer
99 // at the same time we are.
100 //
101 FastCriticalSectionClass::LockClass lock(m_TempMutex);
102
103 //
104 // Try to find an available temporary buffer
105 //
106 for (int index = 0; index < MAX_TEMP_STRING; index ++) {
107 if (m_FreeTempPtr[index] != NULL) {
108
109 //
110 // Grab this unused buffer for our string
111 //
112 string = m_FreeTempPtr[index];
113 m_ResTempPtr[index] = m_FreeTempPtr[index];
114 m_FreeTempPtr[index] = NULL;
115 Set_Buffer_And_Allocated_Length (string, MAX_TEMP_LEN);
116
117 //
118 // Increment the count of used buffers
119 //
120 m_UsedTempStringCount ++;
121 break;
122 }
123 }
124 }
125
126 if (string == NULL) {
127 Set_Buffer_And_Allocated_Length (Allocate_Buffer (length), length);
128 }
129 }
130
131 return ;
132}
133
134
136//
137// Resize
138//
140void
141WideStringClass::Resize (int new_len)
142{
143 int allocated_len = Get_Allocated_Length ();
144 if (new_len > allocated_len) {
145
146 //
147 // Allocate the new buffer and copy the contents of our current
148 // string.
149 //
150 WCHAR *new_buffer = Allocate_Buffer (new_len);
151 wcscpy (new_buffer, m_Buffer);
152
153 //
154 // Switch to the new buffer
155 //
156 Set_Buffer_And_Allocated_Length (new_buffer, new_len);
157 }
158
159 return ;
160}
161
162
164//
165// Uninitialised_Grow
166//
168void
169WideStringClass::Uninitialised_Grow (int new_len)
170{
171 int allocated_len = Get_Allocated_Length ();
172 if (new_len > allocated_len) {
173
174 //
175 // Switch to a newly allocated buffer
176 //
177 WCHAR *new_buffer = Allocate_Buffer (new_len);
178 Set_Buffer_And_Allocated_Length (new_buffer, new_len);
179 }
180
181 //
182 // Whenever this function is called, clear the cached length
183 //
184 Store_Length (0);
185 return ;
186}
187
188
190//
191// Uninitialised_Grow
192//
194void
195WideStringClass::Free_String (void)
196{
197 if (m_Buffer != m_EmptyString) {
198
199 //
200 // Check to see if this string was a temporary string
201 //
202 bool found = false;
203 for (int index = 0; index < MAX_TEMP_STRING; index ++) {
204 if (m_Buffer == m_ResTempPtr[index]) {
205 //
206 // Make sure no one else is modifying a temp pointer
207 // at the same time we are.
208 //
209 FastCriticalSectionClass::LockClass lock(m_TempMutex);
210
211 //
212 // Release our hold on this temporary buffer
213 //
214 m_Buffer[0] = 0;
215 m_FreeTempPtr[index] = m_Buffer;
216 m_ResTempPtr[index] = 0;
217 m_UsedTempStringCount --;
218 found = true;
219 break;
220 }
221 }
222
223 //
224 // String wasn't temporary, so free the memory
225 //
226 if (found == false) {
227 char *buffer = ((char *)m_Buffer) - sizeof (WideStringClass::_HEADER);
228 delete [] buffer;
229 }
230
231 //
232 // Reset the buffer
233 //
234 m_Buffer = m_EmptyString;
235 }
236
237 return ;
238}
239
240
242//
243// Format
244//
246int _cdecl
247WideStringClass::Format_Args (const WCHAR *format, const va_list & arg_list )
248{
249 if (format == NULL) {
250 return 0;
251 }
252
253 //
254 // Make a guess at the maximum length of the resulting string
255 //
256 WCHAR temp_buffer[512] = { 0 };
257
258 //
259 // Format the string
260 //
261 int retval = _vsnwprintf (temp_buffer, 512, format, arg_list);
262
263 //
264 // Copy the string into our buffer
265 //
266 (*this) = temp_buffer;
267
268 return retval;
269}
270
271
273//
274// Format
275//
277int _cdecl
278WideStringClass::Format (const WCHAR *format, ...)
279{
280 if (format == NULL) {
281 return 0;
282 }
283
284 va_list arg_list;
285 va_start (arg_list, format);
286
287 //
288 // Make a guess at the maximum length of the resulting string
289 //
290 WCHAR temp_buffer[512] = { 0 };
291
292 //
293 // Format the string
294 //
295 int retval = _vsnwprintf (temp_buffer, 512, format, arg_list);
296
297 //
298 // Copy the string into our buffer
299 //
300 (*this) = temp_buffer;
301
302 va_end (arg_list);
303 return retval;
304}
305
306
308//
309// Release_Resources
310//
312void
317
319// Convert_From
321bool WideStringClass::Convert_From (const char *text)
322{
323 if (text != NULL) {
324
325 int length;
326
327 length = MultiByteToWideChar (CP_ACP, 0, text, -1, NULL, 0);
328 if (length > 0) {
329
330 Uninitialised_Grow (length);
331 Store_Length (length - 1);
332
333 // Convert.
334 MultiByteToWideChar (CP_ACP, 0, text, -1, m_Buffer, length);
335
336 // Success.
337 return (true);
338 }
339 }
340
341 // Failure.
342 return (false);
343}
344
346// Test if a Unicode string is within the ANSI range. (0 - 255)
349 {
350 if (m_Buffer) {
351 for (int index = 0; m_Buffer[index] != 0; index++) {
352 unsigned short value = m_Buffer[index];
353
354 if (value > 255) {
355 return false;
356 }
357 }
358 }
359
360 return true;
361 }
362
#define NULL
Definition BaseType.h:92
void const char * value
friend class LockClass
Definition mutex.h:174
bool Is_ANSI(void)
int _cdecl Format(const WCHAR *format,...)
int _cdecl Format_Args(const WCHAR *format, const va_list &arg_list)
bool Convert_From(const char *text)
static void Release_Resources(void)
else return(RetVal)
char buffer[1024]