Ark Server API (ASA) - Wiki
Loading...
Searching...
No Matches
GenericPlatformString.cpp
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#include "GenericPlatform/GenericPlatformString.h"
4#include "HAL/UnrealMemory.h"
5#include "Misc/Char.h"
6#include "Containers/UnrealString.h"
7//#include "Logging/LogMacros.h"
8
9
10//DEFINE_LOG_CATEGORY_STATIC(LogGenericPlatformString, Log, All);
11
12template <> const TCHAR* FGenericPlatformString::GetEncodingTypeName<ANSICHAR>() { return TEXT("ANSICHAR"); }
13template <> const TCHAR* FGenericPlatformString::GetEncodingTypeName<WIDECHAR>() { return TEXT("WIDECHAR"); }
14template <> const TCHAR* FGenericPlatformString::GetEncodingTypeName<UCS2CHAR>() { return TEXT("UCS2CHAR"); }
15template <> const TCHAR* FGenericPlatformString::GetEncodingTypeName<UTF8CHAR>() { return TEXT("UTF8CHAR"); }
17template <> const TCHAR* FGenericPlatformString::GetEncodingTypeName<wchar_t>() { return TEXT("WCHAR_T"); }
18#endif
19
20void* FGenericPlatformString::Memcpy(void* Dest, const void* Src, SIZE_T Count)
21{
22 return FMemory::Memcpy(Dest, Src, Count);
23}
24
25namespace
26{
27 void TrimStringAndLogBogusCharsError(FString& SrcStr, const TCHAR* SourceCharName, const TCHAR* DestCharName)
28 {
30 // @todo: Put this back in once GLog becomes a #define, or is replaced with GLog::GetLog()
31 //UE_LOG(LogGenericPlatformString, Warning, TEXT("Bad chars found when trying to convert \"%s\" from %s to %s"), *SrcStr, SourceCharName, DestCharName);
32 }
33}
34
35namespace UE::Core::Private
36{
37 /**
38 * This is a basic object which counts how many times it has been incremented
39 */
40 template <typename DestType>
42 {
44 : Counter(0)
45 {
46 }
47
48 const TCountingOutputIterator& operator* () const { return *this; }
49 const TCountingOutputIterator& operator++() { ++Counter; return *this; }
50 const TCountingOutputIterator& operator++(int) { ++Counter; return *this; }
51 const TCountingOutputIterator& operator+=(const int32 Amount) { Counter += Amount; return *this; }
52
53 const DestType& operator=(const DestType& Val) const
54 {
55 return Val;
56 }
57
59 {
60 return Lhs.Counter - Rhs.Counter;
61 }
62
63 int32 GetCount() const { return Counter; }
64
65 private:
66 int32 Counter;
67 };
68
69 /** Is the provided Codepoint within the range of valid codepoints? */
70 FORCEINLINE bool IsValidCodepoint(const uint32 Codepoint)
71 {
72 if ((Codepoint > 0x10FFFF) || // No Unicode codepoints above 10FFFFh, (for now!)
73 (Codepoint == 0xFFFE) || (Codepoint == 0xFFFF)) // illegal values.
74 {
75 return false;
76 }
77 return true;
78 }
79
80 /** Is the provided Codepoint within the range of the high-or low surrogates? */
81 static FORCEINLINE bool IsSurrogate(const uint32 Codepoint)
82 {
83 return (Codepoint & 0xFFFFF800) == 0xD800;
84 }
85
86 /** Is the provided Codepoint within the range of the high-surrogates? */
87 static FORCEINLINE bool IsHighSurrogate(const uint32 Codepoint)
88 {
89 return (Codepoint & 0xFFFFFC00) == 0xD800;
90 }
91
92 /** Is the provided Codepoint within the range of the low-surrogates? */
93 static FORCEINLINE bool IsLowSurrogate(const uint32 Codepoint)
94 {
95 return (Codepoint & 0xFFFFFC00) == 0xDC00;
96 }
97
98 static FORCEINLINE uint32 EncodeSurrogate(const uint16 HighSurrogate, const uint16 LowSurrogate)
99 {
100 return ((HighSurrogate - HIGH_SURROGATE_START_CODEPOINT) << 10) + (LowSurrogate - LOW_SURROGATE_START_CODEPOINT) + 0x10000;
101 }
102
103 static FORCEINLINE void DecodeSurrogate(const uint32 Codepoint, uint16& OutHighSurrogate, uint16& OutLowSurrogate)
104 {
105 const uint32 TmpCodepoint = Codepoint - 0x10000;
106 OutHighSurrogate = (uint16)((TmpCodepoint >> 10) + HIGH_SURROGATE_START_CODEPOINT);
107 OutLowSurrogate = (TmpCodepoint & 0x3FF) + LOW_SURROGATE_START_CODEPOINT;
108 }
109
110 /** Is the provided Codepoint outside of the range of the basic multilingual plane, but within the valid range of UTF8/16? */
111 static FORCEINLINE bool IsEncodedSurrogate(const uint32 Codepoint)
112 {
113 return Codepoint >= ENCODED_SURROGATE_START_CODEPOINT && Codepoint <= ENCODED_SURROGATE_END_CODEPOINT;
114 }
115
116 /**
117 * Convert TCHAR Codepoint into UTF-8 characters.
118 *
119 * @param Codepoint Codepoint to expand into UTF-8 bytes
120 * @param OutputIterator Output iterator to write UTF-8 bytes into
121 * @param OutputIteratorByteSizeRemaining Maximum number of ANSI characters that can be written to OutputIterator
122 * @return true if some data was written, false otherwise.
123 */
124 template <typename BufferType>
125 static bool WriteCodepointToBuffer(uint32 Codepoint, BufferType& OutputIterator, int32& OutputIteratorByteSizeRemaining)
126 {
127 // Ensure we have at least one character in size to write
129 {
130 return false;
131 }
132
134 {
136 }
137 else if (IsSurrogate(Codepoint)) // UTF-8 Characters are not allowed to encode codepoints in the surrogate pair range
138 {
140 }
141
142 // Do the encoding...
143 if (Codepoint < 0x80)
144 {
146
148 }
149 else if (Codepoint < 0x800)
150 {
152 {
153 return false;
154 }
155
156 *OutputIterator++ = (UTF8CHAR)((Codepoint >> 6) | 128 | 64);
157 *OutputIterator++ = (UTF8CHAR)((Codepoint & 0x3F) | 128);
158
160 }
161 else if (Codepoint < 0x10000)
162 {
164 {
165 return false;
166 }
167
168 *OutputIterator++ = (UTF8CHAR)( (Codepoint >> 12) | 128 | 64 | 32);
169 *OutputIterator++ = (UTF8CHAR)(((Codepoint >> 6) & 0x3F) | 128);
170 *OutputIterator++ = (UTF8CHAR)( (Codepoint & 0x3F) | 128);
171
173 }
174 else
175 {
177 {
178 return false;
179 }
180
181 *OutputIterator++ = (UTF8CHAR)( (Codepoint >> 18) | 128 | 64 | 32 | 16);
182 *OutputIterator++ = (UTF8CHAR)(((Codepoint >> 12) & 0x3F) | 128);
183 *OutputIterator++ = (UTF8CHAR)(((Codepoint >> 6 ) & 0x3F) | 128);
184 *OutputIterator++ = (UTF8CHAR)( (Codepoint & 0x3F) | 128);
185
187 }
188
189 return true;
190 }
191
193 {
194 explicit FNullTerminal() = default;
195 };
196
197 template <typename Pointer>
198 bool IsRangeEmpty(Pointer& Ptr, int32& Len)
199 {
200 return Len <= 0;
201 }
202
203 template <typename Pointer>
204 bool IsRangeEmpty(Pointer& Ptr, FNullTerminal)
205 {
206 return *Ptr == '\0';
207 }
208
209 template <typename Pointer>
210 void PopFront(Pointer& Ptr, int32& Len)
211 {
212 checkfSlow(Len > 0, TEXT("Trying to pop past end end of the range"));
213 ++Ptr;
214 --Len;
215 }
216
217 template <typename Pointer>
218 void PopFront(Pointer& Ptr, FNullTerminal)
219 {
220 checkfSlow(*Ptr != '\0', TEXT("Trying to pop the null terminator of the string"));
221 ++Ptr;
222 }
223
224 template <typename DestBufferType, typename FromType, typename SourceEndType>
225 static int32 ConvertToUTF8(DestBufferType& Dest, int32 DestLen, const FromType* Source, SourceEndType SourceEnd)
226 {
228
229 if constexpr (sizeof(FromType) == 4)
230 {
232
233 for (;;)
234 {
236 {
238 }
239
242 {
243 // Could not write data, bail out
244 return -1;
245 }
246
248 }
249 }
250 else
251 {
253
254 for (;;)
255 {
257 {
259 }
260
263
264 // Check if this character is a high-surrogate
266 {
268 {
269 // String ends with lone high-surrogate - write it out (will be converted into bogus character)
271 {
272 // Could not write data, bail out
273 return -1;
274 }
275
277 }
278
279 // Read next codepoint
281
282 // If it's a low surrogate, combine it with the current high surrogate,
283 // otherwise just leave the high surrogate to be written out by itself (as a bogus character)
285 {
288 }
289 }
290
292 {
293 // Could not write data, bail out
294 return -1;
295 }
296 }
297 }
298 }
299
300 template <typename SourceEndType>
301 static bool ReadTrailingOctet(uint32& OutOctet, const UTF8CHAR*& Ptr, SourceEndType& SourceEnd)
302 {
303 // Ensure our string has enough characters to read from
305 {
306 return false;
307 }
308
311
312 // Format isn't 10xxxxxx?
313 if ((Octet & 192) != 128)
314 {
315 return false;
316 }
317
318 OutOctet = Octet;
319 return true;
320 };
321
322 template <typename SourceEndType>
323 static uint32 CodepointFromUtf8(const UTF8CHAR*& SourceString, SourceEndType& SourceEnd)
324 {
326
329
330 if (Octet < 128) // one octet char: 0 to 127
331 {
332 return Octet;
333 }
334
335 if (Octet < 192) // bad (starts with 10xxxxxx).
336 {
337 // Apparently each of these is supposed to be flagged as a bogus
338 // char, instead of just resyncing to the next valid codepoint.
339
340 // Sequence was not valid UTF-8. Skip the first byte and continue.
342 }
343
346 {
348 }
349
350 if (Octet < 224) // two octets
351 {
352 uint32 Codepoint = ((Octet - 192) << 6) | (Octet2 - 128);
353 if (Codepoint < 0x80 || Codepoint > 0x7FF)
354 {
356 }
357
358 // Should only reach here after parsing a legal codepoint
359 return Codepoint;
360 }
361
364 {
366 }
367
368 if (Octet < 240) // three octets
369 {
370 uint32 Codepoint = ((Octet - 224) << 12) | ((Octet2 - 128) << 6) | (Octet3 - 128);
371
372 // UTF-8 characters cannot be in the UTF-16 surrogates range. 0xFFFE and 0xFFFF are illegal, too, so we check them at the edge.
373 if (Codepoint < 0x800 || Codepoint > 0xFFFD || IsSurrogate(Codepoint))
374 {
376 }
377
378 // Should only reach here after parsing a legal codepoint
379 return Codepoint;
380 }
381
384 {
386 }
387
388 if (Octet < 248) // four octets
389 {
390 Octet -= (128+64+32+16);
391
392 uint32 Codepoint = (Octet << 18) | ((Octet2 - 128) << 12) | ((Octet3 - 128) << 6) | (Octet4 - 128);
393 if (Codepoint < 0x10000 || Codepoint > 0x10FFFF)
398 // Should only reach here after parsing a legal codepoint
399 return Codepoint;
404 {
406 }
407
408 // Five and six octet sequences became illegal in rfc3629.
409 // We throw the codepoint away, but parse them to make sure we move
410 // ahead the right number of bytes and don't overflow the buffer.
411
412 if (Octet < 252) // five octets
413 {
414 // Skip to end and write out a single char (we always have room for at least 1 char)
416 }
417
418 // six octets
419
422 {
424 }
425
427 }
428
429 /**
430 * Read Source string, converting the data from UTF-8 into UTF-16, and placing these in the Destination
431 */
432 template <typename DestType, typename DestBufferType, typename SourceEndType>
433 static int32 ConvertFromUTF8(DestBufferType& ConvertedBuffer, int32 DestLen, const UTF8CHAR* Source, SourceEndType SourceEnd)
434 {
436
437 const uint64 ExtendedCharMask = 0x8080808080808080;
438 while (!IsRangeEmpty(Source, SourceEnd))
439 {
440 if (DestLen == 0)
441 {
442 return -1;
443 }
444
445 // In case we're given an unaligned pointer, we'll
446 // fallback to the slow path until properly aligned.
447 // But we can only do that if we know how much buffer we have left.
448 if constexpr (std::is_integral_v<SourceEndType>)
449 {
450 if (IsAligned(Source, 8))
451 {
452 // Fast path for most common case
453 while (SourceEnd >= 8 && DestLen >= 8)
454 {
455 // Detect any extended characters 8 chars at a time
456 if ((*(const uint64*)Source) & ExtendedCharMask)
457 {
458 // Move to slow path since we got extended characters to process
459 break;
460 }
461
462 // This should get unrolled on most compiler
463 // ROI of diminished return to vectorize this as we
464 // would have to deal with alignment, endianness and
465 // rewrite the iterators to support bulk writes
466 for (int32 Index = 0; Index < 8; ++Index)
467 {
468 *(ConvertedBuffer++) = (DestType)(uint8)*(Source++);
469 }
470 SourceEnd -= 8;
471 DestLen -= 8;
472 }
473 }
474 }
475
476 // Slow path for extended characters
477 while (!IsRangeEmpty(Source, SourceEnd) && DestLen > 0)
478 {
479 // Read our codepoint, advancing the source pointer
481
482 if constexpr (sizeof(DestType) != 4)
483 {
484 // We want to write out two chars
486 {
487 // We need two characters to write the surrogate pair
488 if (DestLen >= 2)
489 {
493
496 DestLen -= 2;
497 continue;
498 }
499
500 // If we don't have space, write a bogus character instead (we should have space for it)
502 }
504 {
505 // Ignore values higher than the supplementary plane range
507 }
508 }
509
511 --DestLen;
512
513 if constexpr (std::is_integral_v<SourceEndType>)
514 {
515 // Return to the fast path once aligned and back to simple ASCII chars
516 if (Codepoint < 128 && IsAligned(Source, 8))
517 {
518 break;
519 }
520 }
521 }
522 }
523
525 }
526
527 /**
528 * Determines the length of the converted string.
529 *
530 * @return The length of the string in UTF-16 code units.
531 */
532 ARK_API int32 GetConvertedLength(const UTF8CHAR*, const WIDECHAR* Source)
533 {
534 TCountingOutputIterator<UTF8CHAR> Dest;
535 int32 Result = ConvertToUTF8(Dest, INT32_MAX, Source, FNullTerminal{});
536 return Result;
537 }
538 ARK_API int32 GetConvertedLength(const UTF8CHAR*, const WIDECHAR* Source, int32 SourceLen)
539 {
540 TCountingOutputIterator<UTF8CHAR> Dest;
541 int32 Result = ConvertToUTF8(Dest, INT32_MAX, Source, SourceLen);
542 return Result;
543 }
544 ARK_API int32 GetConvertedLength(const UTF8CHAR*, const UCS2CHAR* Source)
545 {
546 TCountingOutputIterator<UTF8CHAR> Dest;
547 int32 Result = ConvertToUTF8(Dest, INT32_MAX, Source, FNullTerminal{});
548 return Result;
549 }
550 ARK_API int32 GetConvertedLength(const UTF8CHAR*, const UCS2CHAR* Source, int32 SourceLen)
551 {
552 TCountingOutputIterator<UTF8CHAR> Dest;
553 int32 Result = ConvertToUTF8(Dest, INT32_MAX, Source, SourceLen);
554 return Result;
555 }
556 ARK_API int32 GetConvertedLength(const UTF8CHAR*, const UTF32CHAR* Source)
557 {
558 TCountingOutputIterator<UTF8CHAR> Dest;
559 int32 Result = ConvertToUTF8(Dest, INT32_MAX, Source, FNullTerminal{});
560 return Result;
561 }
562 ARK_API int32 GetConvertedLength(const UTF8CHAR*, const UTF32CHAR* Source, int32 SourceLen)
563 {
564 TCountingOutputIterator<UTF8CHAR> Dest;
565 int32 Result = ConvertToUTF8(Dest, INT32_MAX, Source, SourceLen);
566 return Result;
567 }
568 ARK_API int32 GetConvertedLength(const ANSICHAR*, const UTF8CHAR* Source)
569 {
570 TCountingOutputIterator<ANSICHAR> Dest;
571 int32 Result = ConvertFromUTF8<ANSICHAR>(Dest, INT32_MAX, Source, FNullTerminal{});
572 return Result;
573 }
574 ARK_API int32 GetConvertedLength(const ANSICHAR*, const UTF8CHAR* Source, int32 SourceLen)
575 {
576 TCountingOutputIterator<ANSICHAR> Dest;
577 int32 Result = ConvertFromUTF8<ANSICHAR>(Dest, INT32_MAX, Source, SourceLen);
578 return Result;
579 }
580 ARK_API int32 GetConvertedLength(const WIDECHAR*, const UTF8CHAR* Source)
581 {
582 TCountingOutputIterator<WIDECHAR> Dest;
583 int32 Result = ConvertFromUTF8<WIDECHAR>(Dest, INT32_MAX, Source, FNullTerminal{});
584 return Result;
585 }
586 ARK_API int32 GetConvertedLength(const WIDECHAR*, const UTF8CHAR* Source, int32 SourceLen)
587 {
588 TCountingOutputIterator<WIDECHAR> Dest;
589 int32 Result = ConvertFromUTF8<WIDECHAR>(Dest, INT32_MAX, Source, SourceLen);
590 return Result;
591 }
592 ARK_API int32 GetConvertedLength(const UCS2CHAR*, const UTF8CHAR* Source)
593 {
595 int32 Result = ConvertFromUTF8<UCS2CHAR>(Dest, INT32_MAX, Source, FNullTerminal{});
596 return Result;
597 }
598 ARK_API int32 GetConvertedLength(const UCS2CHAR*, const UTF8CHAR* Source, int32 SourceLen)
599 {
601 int32 Result = ConvertFromUTF8<UCS2CHAR>(Dest, INT32_MAX, Source, SourceLen);
602 return Result;
603 }
604
605 ARK_API UTF8CHAR* Convert(UTF8CHAR* Dest, int32 DestLen, const WIDECHAR* Src)
606 {
607 if (ConvertToUTF8(Dest, DestLen, Src, FNullTerminal{}) == -1)
608 {
609 return nullptr;
610 }
611 return Dest;
612 }
613 ARK_API UTF8CHAR* Convert(UTF8CHAR* Dest, int32 DestLen, const WIDECHAR* Src, int32 SrcLen)
614 {
615 if (ConvertToUTF8(Dest, DestLen, Src, SrcLen) == -1)
616 {
617 return nullptr;
618 }
619 return Dest;
620 }
621 ARK_API UTF8CHAR* Convert(UTF8CHAR* Dest, int32 DestLen, const UCS2CHAR* Src)
622 {
623 if (ConvertToUTF8(Dest, DestLen, Src, FNullTerminal{}) == -1)
624 {
625 return nullptr;
626 }
627 return Dest;
628 }
629 ARK_API UTF8CHAR* Convert(UTF8CHAR* Dest, int32 DestLen, const UCS2CHAR* Src, int32 SrcLen)
630 {
631 if (ConvertToUTF8(Dest, DestLen, Src, SrcLen) == -1)
632 {
633 return nullptr;
634 }
635 return Dest;
636 }
637 ARK_API UTF8CHAR* Convert(UTF8CHAR* Dest, int32 DestLen, const UTF32CHAR* Src)
638 {
639 if (ConvertToUTF8(Dest, DestLen, Src, FNullTerminal{}) == -1)
640 {
641 return nullptr;
642 }
643 return Dest;
644 }
645 ARK_API UTF8CHAR* Convert(UTF8CHAR* Dest, int32 DestLen, const UTF32CHAR* Src, int32 SrcLen)
646 {
647 if (ConvertToUTF8(Dest, DestLen, Src, SrcLen) == -1)
648 {
649 return nullptr;
650 }
651 return Dest;
652 }
653 ARK_API ANSICHAR* Convert(ANSICHAR* Dest, int32 DestLen, const UTF8CHAR* Src)
654 {
655 if (ConvertFromUTF8<ANSICHAR>(Dest, DestLen, Src, FNullTerminal{}) == -1)
656 {
657 return nullptr;
658 }
659 return Dest;
660 }
661 ARK_API ANSICHAR* Convert(ANSICHAR* Dest, int32 DestLen, const UTF8CHAR* Src, int32 SrcLen)
662 {
663 if (ConvertFromUTF8<ANSICHAR>(Dest, DestLen, Src, SrcLen) == -1)
664 {
665 return nullptr;
666 }
667 return Dest;
668 }
669 ARK_API WIDECHAR* Convert(WIDECHAR* Dest, int32 DestLen, const UTF8CHAR* Src)
670 {
671 if (ConvertFromUTF8<WIDECHAR>(Dest, DestLen, Src, FNullTerminal{}) == -1)
672 {
673 return nullptr;
674 }
675 return Dest;
676 }
677 ARK_API WIDECHAR* Convert(WIDECHAR* Dest, int32 DestLen, const UTF8CHAR* Src, int32 SrcLen)
678 {
679 if (ConvertFromUTF8<WIDECHAR>(Dest, DestLen, Src, SrcLen) == -1)
680 {
681 return nullptr;
682 }
683 return Dest;
684 }
685 ARK_API UCS2CHAR* Convert(UCS2CHAR* Dest, int32 DestLen, const UTF8CHAR* Src)
686 {
687 if (ConvertFromUTF8<UCS2CHAR>(Dest, DestLen, Src, FNullTerminal{}) == -1)
688 {
689 return nullptr;
690 }
691 return Dest;
692 }
693 ARK_API UCS2CHAR* Convert(UCS2CHAR* Dest, int32 DestLen, const UTF8CHAR* Src, int32 SrcLen)
694 {
695 if (ConvertFromUTF8<UCS2CHAR>(Dest, DestLen, Src, SrcLen) == -1)
696 {
697 return nullptr;
698 }
699 return Dest;
700 }
701
702 template <typename DestEncoding, typename SourceEncoding, typename SourceEndType>
703 void LogBogusCharsImpl(const SourceEncoding* Src, SourceEndType SourceEnd)
704 {
705 static_assert(TIsFixedWidthCharEncoding_V<SourceEncoding>, "Currently unimplemented for non-fixed-width source conversions");
706
708 bool bFoundBogusChars = false;
710 {
713 {
714 SrcStr += FString::Printf(TEXT("[0x%X]"), (int32)SrcCh);
715 bFoundBogusChars = true;
716 }
718 {
720 {
722 {
724 bFoundBogusChars = false;
725 }
726 SrcStr.Empty();
727 }
728 else
729 {
731 }
732 }
733 else
734 {
735 SrcStr.AppendChar((TCHAR)'?');
736 }
737 }
738
740 {
742 }
743 }
744}
745
746/*template <typename DestEncoding, typename SourceEncoding>
747void FGenericPlatformString::LogBogusChars(const SourceEncoding* Src)
748{
749 UE::Core::Private::LogBogusCharsImpl<DestEncoding>(Src, UE::Core::Private::FNullTerminal{});
750}
751
752template <typename DestEncoding, typename SourceEncoding>
753void FGenericPlatformString::LogBogusChars(const SourceEncoding* Src, int32 SrcSize)
754{
755 UE::Core::Private::LogBogusCharsImpl<DestEncoding>(Src, SrcSize);
756}*/
758{
759
760template<typename CharType1, typename CharType2>
761int32 StrncmpImpl(const CharType1* String1, const CharType2* String2, SIZE_T Count)
762{
763 for (; Count > 0; --Count)
764 {
765 CharType1 C1 = *String1++;
766 CharType2 C2 = *String2++;
767
768 if (C1 != C2)
769 {
771 }
772 if (C1 == 0)
773 {
774 return 0;
775 }
776 }
777
778 return 0;
779}
780
781}
782
783int32 FGenericPlatformString::Strncmp(const ANSICHAR* Str1, const ANSICHAR* Str2, SIZE_T Count) { return GenericPlatformStringPrivate::StrncmpImpl(Str1, Str2, Count); }
784int32 FGenericPlatformString::Strncmp(const WIDECHAR* Str1, const ANSICHAR* Str2, SIZE_T Count) { return GenericPlatformStringPrivate::StrncmpImpl(Str1, Str2, Count); }
785int32 FGenericPlatformString::Strncmp(const UTF8CHAR* Str1, const ANSICHAR* Str2, SIZE_T Count) { return GenericPlatformStringPrivate::StrncmpImpl(Str1, Str2, Count); }
786int32 FGenericPlatformString::Strncmp(const ANSICHAR* Str1, const WIDECHAR* Str2, SIZE_T Count) { return GenericPlatformStringPrivate::StrncmpImpl(Str1, Str2, Count); }
787int32 FGenericPlatformString::Strncmp(const WIDECHAR* Str1, const WIDECHAR* Str2, SIZE_T Count) { return GenericPlatformStringPrivate::StrncmpImpl(Str1, Str2, Count); }
788int32 FGenericPlatformString::Strncmp(const UTF8CHAR* Str1, const WIDECHAR* Str2, SIZE_T Count) { return GenericPlatformStringPrivate::StrncmpImpl(Str1, Str2, Count); }
789int32 FGenericPlatformString::Strncmp(const ANSICHAR* Str1, const UTF8CHAR* Str2, SIZE_T Count) { return GenericPlatformStringPrivate::StrncmpImpl(Str1, Str2, Count); }
790int32 FGenericPlatformString::Strncmp(const WIDECHAR* Str1, const UTF8CHAR* Str2, SIZE_T Count) { return GenericPlatformStringPrivate::StrncmpImpl(Str1, Str2, Count); }
791int32 FGenericPlatformString::Strncmp(const UTF8CHAR* Str1, const UTF8CHAR* Str2, SIZE_T Count) { return GenericPlatformStringPrivate::StrncmpImpl(Str1, Str2, Count); }
792
793#if !UE_BUILD_DOCS
794template void FGenericPlatformString::LogBogusChars<ANSICHAR, WIDECHAR>(const WIDECHAR* Src);
795template void FGenericPlatformString::LogBogusChars<ANSICHAR, WIDECHAR>(const WIDECHAR* Src, int32 SrcSize);
796template void FGenericPlatformString::LogBogusChars<ANSICHAR, UCS2CHAR>(const UCS2CHAR* Src);
797template void FGenericPlatformString::LogBogusChars<ANSICHAR, UCS2CHAR>(const UCS2CHAR* Src, int32 SrcSize);
798template void FGenericPlatformString::LogBogusChars<WIDECHAR, ANSICHAR>(const ANSICHAR* Src);
799template void FGenericPlatformString::LogBogusChars<WIDECHAR, ANSICHAR>(const ANSICHAR* Src, int32 SrcSize);
800template void FGenericPlatformString::LogBogusChars<WIDECHAR, UCS2CHAR>(const UCS2CHAR* Src);
801template void FGenericPlatformString::LogBogusChars<WIDECHAR, UCS2CHAR>(const UCS2CHAR* Src, int32 SrcSize);
802template void FGenericPlatformString::LogBogusChars<UCS2CHAR, ANSICHAR>(const ANSICHAR* Src);
803template void FGenericPlatformString::LogBogusChars<UCS2CHAR, ANSICHAR>(const ANSICHAR* Src, int32 SrcSize);
804template void FGenericPlatformString::LogBogusChars<UCS2CHAR, WIDECHAR>(const WIDECHAR* Src);
805template void FGenericPlatformString::LogBogusChars<UCS2CHAR, WIDECHAR>(const WIDECHAR* Src, int32 SrcSize);
806template void FGenericPlatformString::LogBogusChars<UTF8CHAR, ANSICHAR>(const ANSICHAR* Src);
807template void FGenericPlatformString::LogBogusChars<UTF8CHAR, ANSICHAR>(const ANSICHAR* Src, int32 SrcSize);
808template void FGenericPlatformString::LogBogusChars<UTF8CHAR, WIDECHAR>(const WIDECHAR* Src);
809template void FGenericPlatformString::LogBogusChars<UTF8CHAR, WIDECHAR>(const WIDECHAR* Src, int32 SrcSize);
810template void FGenericPlatformString::LogBogusChars<UTF8CHAR, UCS2CHAR>(const UCS2CHAR* Src);
811template void FGenericPlatformString::LogBogusChars<UTF8CHAR, UCS2CHAR>(const UCS2CHAR* Src, int32 SrcSize);
813template void FGenericPlatformString::LogBogusChars<wchar_t, char16_t>(const char16_t* Src);
814template void FGenericPlatformString::LogBogusChars<wchar_t, char16_t>(const char16_t* Src, int32 SrcSize);
815template void FGenericPlatformString::LogBogusChars<char16_t, wchar_t>(const wchar_t* Src);
816template void FGenericPlatformString::LogBogusChars<char16_t, wchar_t>(const wchar_t* Src, int32 SrcSize);
817#endif
818#endif
#define ARK_API
Definition Ark.h:16
#define checkSlow(expr)
#define checkfSlow(expr, format,...)
#define UE_BUILD_DOCS
Definition Build.h:38
#define UE_PTRDIFF_TO_INT32(argument)
#define HIGH_SURROGATE_START_CODEPOINT
#define LOW_SURROGATE_START_CODEPOINT
#define ENCODED_SURROGATE_START_CODEPOINT
#define UNICODE_BOGUS_CHAR_CODEPOINT
#define ENCODED_SURROGATE_END_CODEPOINT
FPlatformTypes::CHAR16 UCS2CHAR
A 16-bit character containing a UCS2 (Unicode, 16-bit, fixed-width) code unit, used for compatibility...
Definition Platform.h:975
#define TEXT(x)
Definition Platform.h:1108
#define PLATFORM_TCHAR_IS_CHAR16
Definition Platform.h:260
#define FORCEINLINE
Definition Platform.h:644
FPlatformTypes::CHAR32 UTF32CHAR
A 32-bit character containing a UTF32 (Unicode, 32-bit, fixed-width) code unit.
Definition Platform.h:979
void TrimStartInline()
Definition String.cpp:692
int32 StrncmpImpl(const CharType1 *String1, const CharType2 *String2, SIZE_T Count)
ARK_API UTF8CHAR * Convert(UTF8CHAR *Dest, int32 DestLen, const UTF32CHAR *Src, int32 SrcLen)
ARK_API int32 GetConvertedLength(const UTF8CHAR *, const UTF32CHAR *Source, int32 SourceLen)
ARK_API UTF8CHAR * Convert(UTF8CHAR *Dest, int32 DestLen, const WIDECHAR *Src)
ARK_API int32 GetConvertedLength(const WIDECHAR *, const UTF8CHAR *Source)
static FORCEINLINE bool IsEncodedSurrogate(const uint32 Codepoint)
ARK_API ANSICHAR * Convert(ANSICHAR *Dest, int32 DestLen, const UTF8CHAR *Src, int32 SrcLen)
ARK_API int32 GetConvertedLength(const UTF8CHAR *, const UCS2CHAR *Source)
ARK_API WIDECHAR * Convert(WIDECHAR *Dest, int32 DestLen, const UTF8CHAR *Src)
ARK_API int32 GetConvertedLength(const UTF8CHAR *, const UTF32CHAR *Source)
static FORCEINLINE bool IsHighSurrogate(const uint32 Codepoint)
ARK_API UTF8CHAR * Convert(UTF8CHAR *Dest, int32 DestLen, const WIDECHAR *Src, int32 SrcLen)
ARK_API int32 GetConvertedLength(const UCS2CHAR *, const UTF8CHAR *Source)
static int32 ConvertFromUTF8(DestBufferType &ConvertedBuffer, int32 DestLen, const UTF8CHAR *Source, SourceEndType SourceEnd)
ARK_API int32 GetConvertedLength(const UTF8CHAR *, const UCS2CHAR *Source, int32 SourceLen)
ARK_API UCS2CHAR * Convert(UCS2CHAR *Dest, int32 DestLen, const UTF8CHAR *Src, int32 SrcLen)
ARK_API int32 GetConvertedLength(const ANSICHAR *, const UTF8CHAR *Source)
static FORCEINLINE bool IsLowSurrogate(const uint32 Codepoint)
static bool ReadTrailingOctet(uint32 &OutOctet, const UTF8CHAR *&Ptr, SourceEndType &SourceEnd)
ARK_API int32 GetConvertedLength(const UTF8CHAR *, const WIDECHAR *Source, int32 SourceLen)
void PopFront(Pointer &Ptr, int32 &Len)
ARK_API int32 GetConvertedLength(const UCS2CHAR *, const UTF8CHAR *Source, int32 SourceLen)
FORCEINLINE bool IsValidCodepoint(const uint32 Codepoint)
ARK_API WIDECHAR * Convert(WIDECHAR *Dest, int32 DestLen, const UTF8CHAR *Src, int32 SrcLen)
bool IsRangeEmpty(Pointer &Ptr, FNullTerminal)
ARK_API ANSICHAR * Convert(ANSICHAR *Dest, int32 DestLen, const UTF8CHAR *Src)
static FORCEINLINE bool IsSurrogate(const uint32 Codepoint)
bool IsRangeEmpty(Pointer &Ptr, int32 &Len)
ARK_API UTF8CHAR * Convert(UTF8CHAR *Dest, int32 DestLen, const UCS2CHAR *Src)
ARK_API int32 GetConvertedLength(const WIDECHAR *, const UTF8CHAR *Source, int32 SourceLen)
ARK_API UCS2CHAR * Convert(UCS2CHAR *Dest, int32 DestLen, const UTF8CHAR *Src)
ARK_API UTF8CHAR * Convert(UTF8CHAR *Dest, int32 DestLen, const UTF32CHAR *Src)
static FORCEINLINE void DecodeSurrogate(const uint32 Codepoint, uint16 &OutHighSurrogate, uint16 &OutLowSurrogate)
static bool WriteCodepointToBuffer(uint32 Codepoint, BufferType &OutputIterator, int32 &OutputIteratorByteSizeRemaining)
static uint32 CodepointFromUtf8(const UTF8CHAR *&SourceString, SourceEndType &SourceEnd)
void PopFront(Pointer &Ptr, FNullTerminal)
ARK_API UTF8CHAR * Convert(UTF8CHAR *Dest, int32 DestLen, const UCS2CHAR *Src, int32 SrcLen)
ARK_API int32 GetConvertedLength(const UTF8CHAR *, const WIDECHAR *Source)
static FORCEINLINE uint32 EncodeSurrogate(const uint16 HighSurrogate, const uint16 LowSurrogate)
void LogBogusCharsImpl(const SourceEncoding *Src, SourceEndType SourceEnd)
ARK_API int32 GetConvertedLength(const ANSICHAR *, const UTF8CHAR *Source, int32 SourceLen)
static int32 ConvertToUTF8(DestBufferType &Dest, int32 DestLen, const FromType *Source, SourceEndType SourceEnd)
Definition Vector.h:40
void TrimStringAndLogBogusCharsError(FString &SrcStr, const TCHAR *SourceCharName, const TCHAR *DestCharName)
static int32 Strncmp(const WIDECHAR *String1, const UTF8CHAR *String2, SIZE_T Count)
static int32 Strncmp(const ANSICHAR *String1, const UTF8CHAR *String2, SIZE_T Count)
static int32 Strncmp(const ANSICHAR *String1, const WIDECHAR *String2, SIZE_T Count)
static int32 Strncmp(const WIDECHAR *String1, const ANSICHAR *String2, SIZE_T Count)
static int32 Strncmp(const ANSICHAR *String1, const ANSICHAR *String2, SIZE_T Count)
static int32 Strncmp(const UTF8CHAR *String1, const UTF8CHAR *String2, SIZE_T Count)
static int32 Strncmp(const UTF8CHAR *String1, const ANSICHAR *String2, SIZE_T Count)
static int32 Strncmp(const UTF8CHAR *String1, const WIDECHAR *String2, SIZE_T Count)
static int32 Strncmp(const WIDECHAR *String1, const WIDECHAR *String2, SIZE_T Count)
static void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
static FORCEINLINE void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
friend int32 operator-(TCountingOutputIterator Lhs, TCountingOutputIterator Rhs)
const DestType & operator=(const DestType &Val) const
const TCountingOutputIterator & operator+=(const int32 Amount)
const TCountingOutputIterator & operator++()
const TCountingOutputIterator & operator*() const
const TCountingOutputIterator & operator++(int)