UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
GenericWidePlatformString.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "HAL/Platform.h"
6
7#if PLATFORM_USE_GENERIC_STRING_IMPLEMENTATION
8
9#include "CoreTypes.h"
12#include "HAL/PlatformCrt.h"
13#include "Misc/Char.h"
14
18struct FGenericWidePlatformString : public FGenericPlatformString
19{
23
24 template <typename CharType>
25 static inline CharType* Strupr(CharType* Dest, SIZE_T DestCount)
26 {
27 for (CharType* Char = Dest; *Char && DestCount > 0; Char++, DestCount--)
28 {
30 }
31 return Dest;
32 }
33
34public:
35
39 CORE_API static WIDECHAR* Strcpy(WIDECHAR* Dest, const WIDECHAR* Src);
40 // This version was deprecated because Strcpy taking a size field does not match the CRT strcpy, and on some platforms the size field was being ignored.
41 // If the memzeroing causes a performance problem, request a new function StrcpyTruncate.
42 UE_DEPRECATED(5.6, "Use Strncpy instead. Note that Strncpy has a behavior difference from Strcpy: it memzeroes the entire DestCount-sized buffer after the end of string.")
43 static WIDECHAR* Strcpy(WIDECHAR* Dest, SIZE_T DestCount, const WIDECHAR* Src)
44 {
45 return Strcpy(Dest, Src);
46 }
47 CORE_API static WIDECHAR* Strncpy(WIDECHAR* Dest, const WIDECHAR* Src, SIZE_T MaxLen);
48 CORE_API static WIDECHAR* Strcat(WIDECHAR* Dest, const WIDECHAR* Src);
49 // This version was deprecated because Strcat taking a size field does not match the CRT strcat, and on some platforms the size field was being ignored.
50 UE_DEPRECATED(5.6, "Use Strncat instead. !!NOTE THAT STRNCAT takes SrcLen rather than DestCount. You must call Strncat(Dest, Src, DestCount - Strlen(Dest) - 1).")
51 static WIDECHAR* Strcat(WIDECHAR* Dest, SIZE_T DestCount, const WIDECHAR* Src)
52 {
53 SIZE_T DestLen = Strlen(Dest);
54 return Strncat(Dest, Src, DestLen + 1 <= DestCount ? DestCount - DestLen - 1 : 0);
55 }
61 CORE_API static WIDECHAR* Strncat(WIDECHAR* Dest, const WIDECHAR* Src, SIZE_T SrcLen);
62
63 static int32 Strcmp( const WIDECHAR* String1, const WIDECHAR* String2 )
64 {
65 // walk the strings, comparing them case sensitively
66 for (; *String1 || *String2; String1++, String2++)
67 {
68 WIDECHAR A = *String1, B = *String2;
69 if (A != B)
70 {
71 return A - B;
72 }
73 }
74 return 0;
75 }
76
77 static int32 Strlen( const WIDECHAR* String )
78 {
79 int32 Length = -1;
80
81 do
82 {
83 Length++;
84 }
85 while (*String++);
86
87 return Length;
88 }
89
90 static int32 Strnlen( const WIDECHAR* String, SIZE_T StringSize )
91 {
92 int32 Length = -1;
93
94 do
95 {
96 Length++;
97 }
98 while (StringSize-- > 0 && *String++);
99
100 return Length;
101 }
102
103#if PLATFORM_TCHAR_IS_CHAR16
104 static int32 Strlen( const wchar_t* String )
105 {
106 int32 Length = -1;
107
108 do
109 {
110 Length++;
111 }
112 while (*String++);
113
114 return Length;
115 }
116
117 static int32 Strnlen( const wchar_t* String, SIZE_T StringSize )
118 {
119 int32 Length = -1;
120
121 do
122 {
123 Length++;
124 }
125 while (StringSize-- > 0 && *String++);
126
127 return Length;
128 }
129#endif
130
131 static const WIDECHAR* Strstr( const WIDECHAR* String, const WIDECHAR* Find)
132 {
134 if ((Char1 = *Find++) != 0)
135 {
136 size_t Length = Strlen(Find);
137
138 do
139 {
140 do
141 {
142 if ((Char2 = *String++) == 0)
143 {
144 return nullptr;
145 }
146 }
147 while (Char1 != Char2);
148 }
149 while (Strncmp(String, Find, Length) != 0);
150
151 String--;
152 }
153
154 return String;
155 }
156
157 static const WIDECHAR* Strchr( const WIDECHAR* String, WIDECHAR C)
158 {
159 while (*String != C && *String != 0)
160 {
161 String++;
162 }
163
164 return (*String == C) ? String : nullptr;
165 }
166
167 static const WIDECHAR* Strrchr( const WIDECHAR* String, WIDECHAR C)
168 {
169 const WIDECHAR *Last = nullptr;
170
171 while (true)
172 {
173 if (*String == C)
174 {
175 Last = String;
176 }
177
178 if (*String == 0)
179 {
180 break;
181 }
182
183 String++;
184 }
185
186 return Last;
187 }
188
189 CORE_API static int32 Strtoi(const WIDECHAR* Start, WIDECHAR** End, int32 Base);
190 CORE_API static int64 Strtoi64(const WIDECHAR* Start, WIDECHAR** End, int32 Base);
191
192 CORE_API static uint64 Strtoui64( const WIDECHAR* Start, WIDECHAR** End, int32 Base );
193 CORE_API static float Atof(const WIDECHAR* String);
194 CORE_API static double Atod(const WIDECHAR* String);
195
196 static UE_FORCEINLINE_HINT int32 Atoi(const WIDECHAR* String)
197 {
198 return Strtoi( String, NULL, 10 );
199 }
200
201 static UE_FORCEINLINE_HINT int64 Atoi64(const WIDECHAR* String)
202 {
203 return Strtoi64( String, NULL, 10 );
204 }
205
206
207
208 CORE_API static WIDECHAR* Strtok( WIDECHAR* StrToken, const WIDECHAR* Delim, WIDECHAR** Context );
209
210 CORE_API static int32 GetVarArgs(WIDECHAR* Dest, SIZE_T DestSize, const WIDECHAR*& Fmt, va_list ArgPtr);
211
215 static inline ANSICHAR* Strcpy(ANSICHAR* Dest, const ANSICHAR* Src)
216 {
217// Skip suggestions about using strcpy_s instead.
219 return strcpy( Dest, Src );
221 }
222
223 // This version was deprecated because Strcpy taking a size field does not match the CRT strcpy, and on some platforms the size field was being ignored.
224 // If the memzeroing causes a performance problem, request a new function StrcpyTruncate.
225 UE_DEPRECATED(5.6, "Use Strncpy instead. Note that Strncpy has a behavior difference from Strcpy: it memzeroes the entire DestCount-sized buffer after the end of string.")
226 static UE_FORCEINLINE_HINT ANSICHAR* Strcpy(ANSICHAR* Dest, SIZE_T DestCount, const ANSICHAR* Src)
227 {
228 return Strcpy(Dest, Src);
229 }
230
231 static inline ANSICHAR* Strncpy(ANSICHAR* Dest, const ANSICHAR* Src, SIZE_T MaxLen)
232 {
233// Skip suggestions about using strncpy_s instead.
234PRAGMA_DISABLE_DEPRECATION_WARNINGS
235 ::strncpy(Dest, Src, MaxLen);
237 Dest[MaxLen-1]=0;
238 return Dest;
239 }
240
241 static inline ANSICHAR* Strcat(ANSICHAR* Dest, const ANSICHAR* Src)
242 {
243// Skip suggestions about using strcat_s instead.
245 return strcat( Dest, Src );
247 }
248
249 // This version was deprecated because Strcat taking a size field does not match the CRT strcat, and on some platforms the size field was being ignored.
250 UE_DEPRECATED(5.6, "Use Strncat instead. !!NOTE THAT STRNCAT takes SrcLen rather than DestCount. You must call Strncat(Dest, Src, DestCount - Strlen(Dest) - 1).")
251 static UE_FORCEINLINE_HINT ANSICHAR* Strcat(ANSICHAR* Dest, SIZE_T DestCount, const ANSICHAR* Src)
252 {
253 return Strcat(Dest, Src);
254 }
255
261 static inline ANSICHAR* Strncat(ANSICHAR* Dest, const ANSICHAR* Src, SIZE_T SrcLen)
262 {
263// Skip suggestions about using strcat_s instead.
265 return strncat(Dest, Src, SrcLen);
267 }
268
269 static UE_FORCEINLINE_HINT int32 Strcmp( const ANSICHAR* String1, const ANSICHAR* String2 )
270 {
271 return strcmp(String1, String2);
272 }
273
275 {
276 return strncmp( String1, String2, Count );
277 }
278
279 static UE_FORCEINLINE_HINT int32 Strlen( const ANSICHAR* String )
280 {
281 return (int32)strlen( String );
282 }
283
284 static UE_FORCEINLINE_HINT int32 Strnlen( const ANSICHAR* String, SIZE_T StringSize )
285 {
286 return (int32)strnlen( String, StringSize );
287 }
288
289 static UE_FORCEINLINE_HINT const ANSICHAR* Strstr( const ANSICHAR* String, const ANSICHAR* Find)
290 {
291 return strstr(String, Find);
292 }
293
294 static UE_FORCEINLINE_HINT const ANSICHAR* Strchr( const ANSICHAR* String, ANSICHAR C)
295 {
296 return strchr(String, C);
297 }
298
299 static UE_FORCEINLINE_HINT const ANSICHAR* Strrchr( const ANSICHAR* String, ANSICHAR C)
300 {
301 return strrchr(String, C);
302 }
303
304 static UE_FORCEINLINE_HINT int32 Atoi(const ANSICHAR* String)
305 {
306 return atoi( String );
307 }
308
309 static UE_FORCEINLINE_HINT int64 Atoi64(const ANSICHAR* String)
310 {
311 return strtoll( String, NULL, 10 );
312 }
313
314 static UE_FORCEINLINE_HINT float Atof(const ANSICHAR* String)
315 {
316 return (float)atof( String );
317 }
318
319 static UE_FORCEINLINE_HINT double Atod(const ANSICHAR* String)
320 {
321 return atof( String );
322 }
323
324 static UE_FORCEINLINE_HINT int32 Strtoi( const ANSICHAR* Start, ANSICHAR** End, int32 Base )
325 {
326 return (int32)strtol( Start, End, Base );
327 }
328
329 static UE_FORCEINLINE_HINT int64 Strtoi64( const ANSICHAR* Start, ANSICHAR** End, int32 Base )
330 {
331 return strtoll(Start, End, Base);
332 }
333
334 static UE_FORCEINLINE_HINT uint64 Strtoui64( const ANSICHAR* Start, ANSICHAR** End, int32 Base )
335 {
336 return strtoull(Start, End, Base);
337 }
338
339 static inline ANSICHAR* Strtok(ANSICHAR* StrToken, const ANSICHAR* Delim, ANSICHAR** Context)
340 {
341// Skip suggestions about using strtok_s instead.
343 return strtok(StrToken, Delim);
345 }
346
347 static int32 GetVarArgs( ANSICHAR* Dest, SIZE_T DestSize, const ANSICHAR*& Fmt, va_list ArgPtr )
348 {
349#if PLATFORM_USE_S_SPEC_FOR_NARROWCHAR_IN_VSPRINTF
350 // fix up the Fmt string, as fast as possible, without using an FAnsiString
351 ANSICHAR* NewFormat = (ANSICHAR*)alloca(Strlen(Fmt) + 1);
352
353 const ANSICHAR* From = Fmt;
355 for (;;)
356 {
357 ANSICHAR FromCh = *From++;
358 *To++ = FromCh;
359 if (FromCh != '%')
360 {
361 if (!FromCh)
362 {
363 break;
364 }
365
366 continue;
367 }
368
369 if (From[0] == 'h' && From[1] == 's')
370 {
371 // Skip the h and copy the s next time to give %s
372 ++From;
373 }
374 }
376#else
378#endif
379 return (Result != -1 && Result < (int32)DestSize) ? Result : -1;
380 }
381
385 static UE_FORCEINLINE_HINT UTF8CHAR* Strcpy(UTF8CHAR* Dest, const UTF8CHAR* Src)
386 {
387 return (UTF8CHAR*)Strcpy((ANSICHAR*)Dest, (const ANSICHAR*)Src);
388 }
389
390 // This version was deprecated because Strcpy taking a size field does not match the CRT strcpy, and on some platforms the size field was being ignored.
391 // If the memzeroing causes a performance problem, request a new function StrcpyTruncate.
392 UE_DEPRECATED(5.6, "Use Strncpy instead. Note that Strncpy has a behavior difference from Strcpy: it memzeroes the entire DestCount-sized buffer after the end of string.")
393 static UE_FORCEINLINE_HINT UTF8CHAR* Strcpy(UTF8CHAR* Dest, SIZE_T DestCount, const UTF8CHAR* Src)
394 {
395 return (UTF8CHAR*)Strcpy((ANSICHAR*)Dest, DestCount, (const ANSICHAR*)Src);
396 }
397
398 static UE_FORCEINLINE_HINT UTF8CHAR* Strncpy(UTF8CHAR* Dest, const UTF8CHAR* Src, SIZE_T MaxLen)
399 {
400 return (UTF8CHAR*)Strncpy((ANSICHAR*)Dest, (const ANSICHAR*)Src, MaxLen);
401 }
402
403 static UE_FORCEINLINE_HINT UTF8CHAR* Strcat(UTF8CHAR* Dest, const UTF8CHAR* Src)
404 {
405 return (UTF8CHAR*)Strcat((ANSICHAR*)Dest, (const ANSICHAR*)Src);
406 }
407
408 // This version was deprecated because Strcat taking a size field does not match the CRT strcat, and on some platforms the size field was being ignored.
409 UE_DEPRECATED(5.6, "Use Strncat instead. !!NOTE THAT STRNCAT takes SrcLen rather than DestCount. You must call Strncat(Dest, Src, DestCount - Strlen(Dest) - 1).")
410 static UE_FORCEINLINE_HINT UTF8CHAR* Strcat(UTF8CHAR* Dest, SIZE_T DestCount, const UTF8CHAR* Src)
411 {
412 return Strcat(Dest, Src);
413 }
414
420 static UE_FORCEINLINE_HINT UTF8CHAR* Strncat(UTF8CHAR* Dest, const UTF8CHAR* Src, SIZE_T SrcLen)
421 {
422 return (UTF8CHAR*)Strncat((ANSICHAR*)Dest, (const ANSICHAR*)Src, SrcLen);
423 }
424
425 static UE_FORCEINLINE_HINT int32 Strcmp(const UTF8CHAR* String1, const UTF8CHAR* String2)
426 {
427 return Strcmp((const ANSICHAR*)String1, (const ANSICHAR*)String2);
428 }
429
431 {
432 return Strncmp((const ANSICHAR*)String1, (const ANSICHAR*)String2, Count);
433 }
434
435 static UE_FORCEINLINE_HINT int32 Strlen(const UTF8CHAR* String)
436 {
437 return Strlen((const ANSICHAR*)String);
438 }
439
441 {
442 return Strnlen((const ANSICHAR*)String, StringSize);
443 }
444
445 static UE_FORCEINLINE_HINT const UTF8CHAR* Strstr(const UTF8CHAR* String, const UTF8CHAR* Find)
446 {
447 return (const UTF8CHAR*)Strstr((const ANSICHAR*)String, (const ANSICHAR*)Find);
448 }
449
450 static UE_FORCEINLINE_HINT const UTF8CHAR* Strchr(const UTF8CHAR* String, UTF8CHAR C)
451 {
452 return (const UTF8CHAR*)Strchr((const ANSICHAR*)String, (ANSICHAR)C);
453 }
454
455 static UE_FORCEINLINE_HINT const UTF8CHAR* Strrchr(const UTF8CHAR* String, UTF8CHAR C)
456 {
457 return (const UTF8CHAR*)Strrchr((const ANSICHAR*)String, (ANSICHAR)C);
458 }
459
460 static UE_FORCEINLINE_HINT int32 Atoi(const UTF8CHAR* String)
461 {
462 return Atoi((const ANSICHAR*)String);
463 }
464
465 static UE_FORCEINLINE_HINT int64 Atoi64(const UTF8CHAR* String)
466 {
467 return Atoi64((const ANSICHAR*)String);
468 }
469
470 static UE_FORCEINLINE_HINT float Atof(const UTF8CHAR* String)
471 {
472 return Atof((const ANSICHAR*)String);
473 }
474
475 static UE_FORCEINLINE_HINT double Atod(const UTF8CHAR* String)
476 {
477 return Atod((const ANSICHAR*)String);
478 }
479
480 static UE_FORCEINLINE_HINT int32 Strtoi(const UTF8CHAR* Start, UTF8CHAR** End, int32 Base)
481 {
482 return Strtoi((const ANSICHAR*)Start, (ANSICHAR**)End, Base);
483 }
484
485 static UE_FORCEINLINE_HINT int64 Strtoi64(const UTF8CHAR* Start, UTF8CHAR** End, int32 Base)
486 {
487 return Strtoi64((const ANSICHAR*)Start, (ANSICHAR**)End, Base);
488 }
489
490 static UE_FORCEINLINE_HINT uint64 Strtoui64(const UTF8CHAR* Start, UTF8CHAR** End, int32 Base)
491 {
492 return Strtoui64((const ANSICHAR*)Start, (ANSICHAR**)End, Base);
493 }
494
496 {
497 return (UTF8CHAR*)Strtok((ANSICHAR*)StrToken, (const ANSICHAR*)Delim, (ANSICHAR**)Context);
498 }
499
500 static UE_FORCEINLINE_HINT int32 GetVarArgs(UTF8CHAR* Dest, SIZE_T DestSize, const UTF8CHAR*& Fmt, va_list ArgPtr)
501 {
502 return GetVarArgs((ANSICHAR*)Dest, DestSize, *(const ANSICHAR**)&Fmt, ArgPtr);
503 }
504
509 static inline int32 Strlen( const UCS2CHAR* String )
510 {
511 int32 Result = 0;
512 while (*String++)
513 {
514 ++Result;
515 }
516
517 return Result;
518 }
519
520 static inline int32 Strnlen( const UCS2CHAR* String, SIZE_T StringSize )
521 {
522 int32 Result = 0;
523 while (StringSize-- > 0 && *String++)
524 {
525 ++Result;
526 }
527
528 return Result;
529 }
530};
531
532#endif
#define NULL
Definition oodle2base.h:134
ENGINE_API void StringSize(const UFont *Font, int32 &XL, int32 &YL, FStringView Text)
Definition Canvas.cpp:1181
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
FPlatformTypes::CHAR16 UCS2CHAR
A 16-bit character containing a UCS2 (Unicode, 16-bit, fixed-width) code unit, used for compatibility...
Definition Platform.h:1139
FPlatformTypes::SIZE_T SIZE_T
An unsigned integer the same size as a pointer, the same as UPTRINT.
Definition Platform.h:1150
FPlatformTypes::WIDECHAR WIDECHAR
A wide character. Normally a signed type.
Definition Platform.h:1133
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
FPlatformTypes::UTF8CHAR UTF8CHAR
An 8-bit character containing a UTF8 (Unicode, 8-bit, variable-width) code unit.
Definition Platform.h:1137
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
FPlatformTypes::ANSICHAR ANSICHAR
An ANSI character. Normally a signed type.
Definition Platform.h:1131
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define PRAGMA_ENABLE_DEPRECATION_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:12
#define PRAGMA_DISABLE_DEPRECATION_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:8
@ Char
Character type.
UE_STRING_CLASS Result(Forward< LhsType >(Lhs), RhsLen)
Definition String.cpp.inl:732
static CORE_API int32 Stricmp(const ANSICHAR *String1, const ANSICHAR *String2)
Definition GenericPlatformStricmp.cpp:93
static CORE_API int32 Strnicmp(const ANSICHAR *String1, const ANSICHAR *String2, SIZE_T Count)
Definition GenericPlatformStricmp.cpp:107
Definition GenericPlatformString.h:61
static CORE_API int32 Strncmp(const ANSICHAR *String1, const ANSICHAR *String2, SIZE_T Count)
Definition GenericPlatformString.cpp:719
static CharType ToUpper(CharType Char)
Definition Char.h:80