3#include "Containers/Array.h"
4#include "Containers/StringConv.h"
5#include "Containers/UnrealString.h"
8#include "HAL/PlatformString.h"
9#include "HAL/UnrealMemory.h"
12#include "Math/NumericLimits.h"
13#include "Math/UnrealMathUtility.h"
14#include "Misc/AssertionMacros.h"
15#include "Misc/ByteSwap.h"
16#include "Misc/CString.h"
18#include "Misc/VarArgs.h"
19#include "Serialization/Archive.h"
20#include "String/HexToBytes.h"
21#include "Templates/MemoryOps.h"
22#include "Templates/RemoveReference.h"
23#include "Templates/UnrealTemplate.h"
24#include "UObject/NameTypes.h"
25#include "API/Fields.h"
28
44 return FChar::ToLower(Lhs) == FChar::ToLower(Rhs);
48 template <
typename CompareType>
131template<
typename CharType>
143 int32 OldEnd = Out.Num();
147 Out.AddUninitialized(Count + (OldEnd ? 0 : 1));
148 OldEnd -= OldEnd ? 1 : 0;
150 TCHAR* Dest = Out.GetData() + OldEnd;
153 TCHAR* NewEnd = FPlatformString::Convert(Dest, Count, Str, Count);
158 int32 Length = FPlatformString::ConvertedLength<TCHAR>(Str, Count);
161 Out.AddUninitialized(Length - Count);
164 Dest = Out.GetData() + OldEnd;
166 NewEnd = FPlatformString::Convert(Dest, Length, Str, Count);
171 int32 NewEndIndex = (int32)(NewEnd - Dest);
172 if (NewEndIndex < Count)
174 Out.SetNumUninitialized(OldEnd + NewEndIndex + 1,
false);
185template<
typename CharType>
199template<
typename CharType>
216template<
typename CharType>
237
238
239
240
241
242
243
244
245
246
247
249FString::
FString(
const ANSICHAR* Str) { NativeCall<
void,
const ANSICHAR*>(
this,
"FString.FString(char*)", Str); }
250FString::
FString(
const WIDECHAR* Str) { NativeCall<
void,
const WIDECHAR*>(
this,
"FString.FString(wchar_t*)", Str); }
251FString::
FString(
const UTF8CHAR* Str) { UE::String::Private::ConstructFromCString(Data, Str); }
253FString::
FString(int32 Len,
const ANSICHAR* Str) { UE::String::Private::ConstructWithLength(Data, Len, Str); }
254FString::
FString(int32 Len,
const WIDECHAR* Str) { UE::String::Private::ConstructWithLength(Data, Len, Str); }
255FString::
FString(int32 Len,
const UTF8CHAR* Str) { UE::String::Private::ConstructWithLength(Data, Len, Str); }
257FString::
FString(
const ANSICHAR* Str, int32 ExtraSlack) { UE::String::Private::ConstructWithSlack(Data, Str, ExtraSlack); }
258FString::
FString(
const WIDECHAR* Str, int32 ExtraSlack) { UE::String::Private::ConstructWithSlack(Data, Str, ExtraSlack); }
259FString::
FString(
const UTF8CHAR* Str, int32 ExtraSlack) { UE::String::Private::ConstructWithSlack(Data, Str, ExtraSlack); }
260FString::
FString(
const UCS2CHAR* Str, int32 ExtraSlack) { UE::String::Private::ConstructWithSlack(Data, Str, ExtraSlack); }
264 if (Data.GetData() != Other)
266 int32 Len = (Other && *Other) ? FCString::Strlen(Other)+1 : 0;
268 Data.AddUninitialized(Len);
272 FMemory::Memcpy( Data.GetData(), Other, Len *
sizeof(TCHAR) );
287 const int32 ThisLen =
Len();
288 if (OtherLen <= ThisLen)
291 TCHAR* DataPtr = Data.GetData();
293 DataPtr[OtherLen] =
TEXT(
'\0');
294 Data.RemoveAt(OtherLen + 1, ThisLen - OtherLen);
298 Data.Empty(OtherLen + 1);
299 Data.AddUninitialized(OtherLen + 1);
300 TCHAR* DataPtr = Data.GetData();
302 DataPtr[OtherLen] =
TEXT(
'\0');
310 if (CharacterCount > 0)
312 Data.Reserve(CharacterCount + 1);
318 Data.Empty(Slack ? Slack + 1 : 0);
334NSString* FString::GetNSString()
const
336#if PLATFORM_TCHAR_IS_4_BYTES
337 return [[[NSString alloc] initWithBytes:Data.GetData() length:Len() *
sizeof(TCHAR) encoding:NSUTF32LittleEndianStringEncoding] autorelease];
339 return [[[NSString alloc] initWithBytes:Data.GetData() length:Len() *
sizeof(TCHAR) encoding:NSUTF16LittleEndianStringEncoding] autorelease];
348 AppendCharacters(Data, Str, Count);
354 AppendCharacters(Data, Str, Count);
360 AppendCharacters(Data, Str, Count);
366 AppendCharacters(Data, Str, Count);
373 int32 DataLen = FCString::Strlen(Data.GetData());
374 check(DataLen == 0 || DataLen < Data.Num());
375 int32 Len = DataLen > 0 ? DataLen+1 : 0;
377 check(Len <= Data.Num());
378 Data.RemoveAt(Len, Data.Num()-Len);
386 check(LeftS != RightS || LeftS ==
nullptr);
388 int32 InPos =
Find(InS
, SearchCase
, SearchDir
);
390 if (InPos < 0) {
return false; }
427 const int32 StringLength =
Len();
428 if (StringLength == 0)
433 TCHAR* RawData = Data.GetData();
434 int32 CopyToIndex = 0;
435 for (int32 CopyFromIndex = 0; CopyFromIndex < StringLength; ++CopyFromIndex)
437 if (RawData[CopyFromIndex] !=
' ')
439 RawData[CopyToIndex] = RawData[CopyFromIndex];
445 if (CopyToIndex <= StringLength)
447 RawData[CopyToIndex] =
TEXT(
'\0');
448 Data.SetNum(CopyToIndex + 1,
false);
454void FString::InsertAt(int32 Index, TCHAR Character)
464 Data.Insert(Character, Index);
479 Data.Insert(Characters.Data.GetData(), Characters.Len(), Index);
486 Data.RemoveAt(Index, FMath::Clamp(Count, 0, Len()-Index), bAllowShrinking);
491 if (InPrefixLen == 0 )
496 if (StartsWith(InPrefix, InPrefixLen, SearchCase ))
507 if (InSuffixLen == 0)
512 if (EndsWith(InSuffix, InSuffixLen, SearchCase))
524template <
typename LhsType,
typename RhsType>
543template <
typename RhsType>
570template <
typename LhsType>
586template <
typename RhsType>
598template <
typename LhsType>
625
626
627
628
629
630void FString::PathAppend(
const TCHAR* Str, int32 StrLength)
632 int32 DataNum = Data.Num();
635 if (DataNum > 1 && Data[DataNum - 2] !=
TEXT(
'/') && Data[DataNum - 2] !=
TEXT(
'\\'))
637 Data[DataNum - 1] =
TEXT(
'/');
638 Data.Add(
TEXT(
'\0'));
645 if (DataNum > 1 && Data[DataNum - 2] !=
TEXT(
'/') && Data[DataNum - 2] !=
TEXT(
'\\') && *Str !=
TEXT(
'/'))
647 Data[DataNum - 1] =
TEXT(
'/');
657 Data.Append(Str, StrLength);
658 Data.Add(
TEXT(
'\0'));
665void FString::ReplaceCharInlineCaseSensitive(
const TCHAR SearchChar,
const TCHAR ReplacementChar)
667 for (TCHAR& Character : Data)
669 Character = Character == SearchChar ? ReplacementChar : Character;
673void FString::ReplaceCharInlineIgnoreCase(
const TCHAR SearchChar,
const TCHAR ReplacementChar)
675 TCHAR OtherCaseSearchChar = TChar<TCHAR>::IsUpper(SearchChar) ? TChar<TCHAR>::ToLower(SearchChar) : TChar<TCHAR>::ToUpper(SearchChar);
676 ReplaceCharInlineCaseSensitive(OtherCaseSearchChar, ReplacementChar);
677 ReplaceCharInlineCaseSensitive(SearchChar, ReplacementChar);
689 return MoveTemp(*
this);
695 while(Pos < Len() && FChar::IsWhitespace((*
this)[Pos]))
712 return MoveTemp(*
this);
718 while(End > 0 && FChar::IsWhitespace((*
this)[End - 1]))
735 return MoveTemp(*
this);
738void FString::TrimCharInline(
const TCHAR CharacterToTrim,
bool* bCharRemoved)
740 bool bQuotesWereRemoved=
false;
741 int32 Start = 0, Count =
Len();
744 if ( (*
this)
[0
] == CharacterToTrim )
748 bQuotesWereRemoved=
true;
754 bQuotesWereRemoved=
true;
758 if ( bCharRemoved !=
nullptr )
760 *bCharRemoved = bQuotesWereRemoved;
767 TrimCharInline(TCHAR(
'"'), bQuotesRemoved);
780 return MoveTemp(*
this);
783FString FString::TrimChar(
const TCHAR CharacterToTrim,
bool* bCharRemoved)
const &
786 Result.TrimCharInline(CharacterToTrim, bCharRemoved);
792 TrimCharInline(CharacterToTrim, bCharRemoved);
793 return MoveTemp(*
this);
796int32
FString::CullArray( TArray<FString>* InArray )
800 InArray->Remove(Empty);
801 return InArray->Num();
814 return MoveTemp(*
this);
821 TCHAR* StartChar = &(*
this)
[0
];
822 TCHAR* EndChar = &(*
this)
[Len()-1
];
826 TempChar = *StartChar;
827 *StartChar = *EndChar;
833 }
while( StartChar < EndChar );
842 for( int32 x = Number
.Len()-1 ; x > -1 ; --x )
847 if( dec == 3 && x > 0 )
858
859
860
861
862
863
866 int32 Length = FMath::Max( Len(), MinCharacters );
869 for( int32 CharIndex=0; CharIndex<
Len(); CharIndex++ )
871 ANSICHAR AnsiChar = CharCast<ANSICHAR>( (*
this)
[CharIndex
] );
876 for( int32 i=
Len(); i<Length; i++ )
878 ANSICHAR NullChar = 0;
889 for (uint32 Count = 0; Count < SrcSize; Count++)
891 Result +=
FString::Printf(
TEXT(
"%03d"),(uint8)SrcBuffer[Count]);
900 if (DestSize >= (uint32)(Source
.Len() / 3) &&
904 ConvBuffer[3] =
TEXT(
'\0');
905 int32 WriteIndex = 0;
907 for (int32 Index = 0; Index < Source
.Len(); Index += 3, WriteIndex++)
909 ConvBuffer[0] = Source
[Index
];
910 ConvBuffer[1] = Source
[Index + 1
];
911 ConvBuffer[2] = Source
[Index + 2
];
912 DestBuffer[WriteIndex] = (uint8)FCString::Atoi(ConvBuffer);
924 for (uint32 Count = 0; Count < SrcSize; Count++)
926 Result +=
FString::Printf(
TEXT(
"%02X" ), (uint8)SrcBuffer[Count] );
935 if (DestSize >= (uint32)(Source
.Len() / 2) &&
939 ConvBuffer[2] =
TEXT(
'\0' );
940 int32 WriteIndex = 0;
942 TCHAR* End =
nullptr;
943 for (int32 Index = 0; Index < Source
.Len(); Index += 2, WriteIndex++)
945 ConvBuffer[0] = Source
[Index
];
946 ConvBuffer[1] = Source
[Index + 1
];
947 DestBuffer[WriteIndex] = (uint8)FCString::Strtoi( ConvBuffer, &End, 16 );
980 for (int32 CharIndex = TempString
.Len() - 1; CharIndex >= 0; --CharIndex)
982 const TCHAR Char = TempString
[CharIndex
];
983 if (Char ==
TEXT(
'.'))
985 DecimalSeparatorIndex = CharIndex;
986 TrimIndex = FMath::Max(TrimIndex, DecimalSeparatorIndex);
991 TrimIndex = CharIndex + 1;
994 check(TrimIndex != INDEX_NONE && DecimalSeparatorIndex != INDEX_NONE);
998 if (InMinFractionalDigits > 0)
1000 if (TrimIndex == DecimalSeparatorIndex)
1003 TempString.AppendChar(
TEXT(
'.'));
1006 const int32 NumFractionalDigits = (TempString
.Len() - DecimalSeparatorIndex) - 1;
1007 const int32 FractionalDigitsToPad = InMinFractionalDigits - NumFractionalDigits;
1008 if (FractionalDigitsToPad > 0)
1011 for (int32 Cx = 0; Cx < FractionalDigitsToPad; ++Cx)
1013 TempString.AppendChar(
TEXT(
'0'));
1023 TCHAR Temp[2]= { Ch,
TEXT(
'\0') };
1030 check( NumCharacters >= 0 );
1033 Temp.Data.AddUninitialized(NumCharacters+1);
1034 for( int32 Cx = 0; Cx < NumCharacters; ++Cx )
1038 Temp.Data[NumCharacters] =
TEXT(
'\0');
1044 int32 Pad = ChCount -
Len();
1048 return ChrN(Pad,
TEXT(
' '))
+ *
this;
1057 int32 Pad = ChCount -
Len();
1061 return *
this + ChrN(Pad,
TEXT(
' '));
1072
1073
1074
1075
1076
1077
1078
1079
1080ARK_API int32
FString::ParseIntoArray( TArray<FString>& OutArray,
const TCHAR* pchDelim,
const bool InCullEmpty )
const
1085 const TCHAR *Start =
**
this;
1086 const int32 DelimLength = FCString::Strlen(pchDelim);
1087 if (Start && *Start !=
TEXT(
'\0') && DelimLength)
1089 while(
const TCHAR *At = FCString::Strstr(Start,pchDelim) )
1091 if (!InCullEmpty || At-Start)
1095 Start = At + DelimLength;
1097 if (!InCullEmpty || *Start)
1099 OutArray.Emplace(Start);
1103 return OutArray.Num();
1108 const TCHAR* Target =
**
this;
1109 int32 TargetLength =
Len();
1123ARK_API int32
FString::ParseIntoArrayWS( TArray<FString>& OutArray,
const TCHAR* pchExtraDelim,
bool InCullEmpty )
const
1127 const TCHAR* WhiteSpace[] =
1139 if (pchExtraDelim && *pchExtraDelim)
1141 WhiteSpace[NumWhiteSpaces++] = pchExtraDelim;
1144 return ParseIntoArray(OutArray, WhiteSpace, NumWhiteSpaces, InCullEmpty);
1150 static const TCHAR* LineEndings[] =
1159 return ParseIntoArray(OutArray, LineEndings, NumLineEndings, InCullEmpty);
1162ARK_API int32
FString::ParseIntoArray(TArray<FString>& OutArray,
const TCHAR*
const * DelimArray, int32 NumDelims,
bool InCullEmpty)
const
1167 const TCHAR *Start = Data.GetData();
1168 const int32 Length =
Len();
1171 int32 SubstringBeginIndex = 0;
1174 for(int32 i = 0; i <
Len();)
1177 int32 DelimiterLength = 0;
1180 for(int32 DelimIndex = 0; DelimIndex < NumDelims; ++DelimIndex)
1182 DelimiterLength = FCString::Strlen(DelimArray[DelimIndex]);
1185 if (FCString::Strncmp(Start + i, DelimArray[DelimIndex], DelimiterLength) == 0)
1188 SubstringEndIndex = i;
1195 const int32 SubstringLength = SubstringEndIndex - SubstringBeginIndex;
1197 if(!InCullEmpty || SubstringLength != 0)
1200 new (OutArray) FString(SubstringEndIndex - SubstringBeginIndex, Start + SubstringBeginIndex);
1203 SubstringBeginIndex = SubstringEndIndex + DelimiterLength;
1204 i = SubstringBeginIndex;
1213 const int32 SubstringLength = Length - SubstringBeginIndex;
1215 if(!InCullEmpty || SubstringLength != 0)
1218 new (OutArray) FString(Start + SubstringBeginIndex);
1222 return OutArray.Num();
1230
1231
1236 FString Copy(MoveTemp(*
this));
1238 const TCHAR* pChar =
*Copy;
1240 bool bEscaped =
false;
1241 while ( *pChar != 0 )
1247 else if ( *pChar == TCHAR(
'\\') )
1251 else if ( *pChar == TCHAR(
'"') )
1253 *
this += TCHAR(
'\\');
1260 return MoveTemp(*
this);
1278 if ( Len() > 0 && (Chars ==
nullptr || Chars->Num() > 0) )
1283 if ( Chars ==
nullptr || Chars->Contains(*(CharToEscapeSeqMap[ChIdx][0])) )
1293
1294
1295
1299 check(InSpacesPerTab > 0);
1313 const int32 CharactersOnLine = (
Len()-LineBegin);
1315 int32 NumSpacesForTab = InSpacesPerTab - (CharactersOnLine % InSpacesPerTab);
1316 for (int32 i = 0; i < NumSpacesForTab; ++i)
1318 AppendChar(
TEXT(
' '));
1325#define STARTING_BUFFER_SIZE 512
1333 TCHAR* Buffer = StartingBuffer;
1343 while (Result == -1)
1351 Buffer[Result] =
TEXT(
'\0');
1353 AppendToMe += Buffer;
1361static_assert(
PLATFORM_LITTLE_ENDIAN,
"FString serialization needs updating to support big-endian platforms!");
1366 static_assert(
sizeof(
UTF16CHAR) ==
sizeof(
UCS2CHAR),
"UTF16CHAR and UCS2CHAR are assumed to be the same size!");
1373 bool bLoadUnicodeChar = SaveNum < 0;
1374 if (bLoadUnicodeChar)
1389 if ((MaxSerializeSize > 0) && (SaveNum > MaxSerializeSize))
1397 A.Data.Empty (SaveNum);
1398 A.Data.AddUninitialized(SaveNum);
1402 if (bLoadUnicodeChar)
1405 auto Passthru = StringMemoryPassthru<
UCS2CHAR>(A.Data.GetData(), SaveNum, SaveNum);
1406 Ar.Serialize(Passthru.Get(), SaveNum *
sizeof(UCS2CHAR));
1409 for (int32 CharIndex = 0; CharIndex < SaveNum; ++CharIndex)
1411 Passthru.Get()[CharIndex] = ByteSwap(Passthru.Get()[CharIndex]);
1415 Passthru.Get()[SaveNum-1] =
'\0';
1425 if(A.FindChar(0xffff, Index))
1433 auto Passthru = StringMemoryPassthru<ANSICHAR>(A.Data.GetData(), SaveNum, SaveNum);
1434 Ar.Serialize(Passthru.Get(), SaveNum *
sizeof(ANSICHAR));
1436 Passthru.Get()[SaveNum-1] =
'\0';
1449 A.Data.CountBytes(Ar);
1451 const bool bSaveUnicodeChar = Ar.IsForcingUnicode() || !FCString::IsPureAnsi(*A);
1452 if (bSaveUnicodeChar)
1456 int32 Num = UTF16String.Length() + 1;
1458 int32 SaveNum = -Num;
1465 Ar.Serialize((
void*)UTF16String.Get(),
sizeof(UTF16CHAR) * Num);
1469 TArray<UTF16CHAR> Swapped(UTF16String.Get(), Num);
1470 for (int32 CharIndex = 0; CharIndex < Num; ++CharIndex)
1472 Swapped[CharIndex] = ByteSwap(Swapped[CharIndex]);
1474 Ar.Serialize((
void*)Swapped.GetData(),
sizeof(UTF16CHAR) * Num);
1480 int32 Num = A.Data.Num();
1485 Ar
.Serialize((
void*)StringCast<ANSICHAR>(A.Data.GetData(), Num).Get()
, sizeof(ANSICHAR) * Num
);
1492template <
typename CharType>
1495 FWideStringView Hex(HexString);
1496 const int32 HexCount = Hex.Len();
1497 const CharType* HexPos = Hex.GetData();
1498 const CharType* HexEnd = HexPos + HexCount;
1499 uint8* OutPos = OutBytes;
1500 if (
const bool bPadNibble = (HexCount % 2) == 1)
1502 *OutPos++ = TCharToNibble(*HexPos++);
1504 while (HexPos != HexEnd)
1506 const uint8 HiNibble = uint8(TCharToNibble(*HexPos++) << 4);
1507 *OutPos++ = HiNibble | TCharToNibble(*HexPos++);
1509 return static_cast<int32>(OutPos - OutBytes);
1514 check(StartSearch >= 0 && StartSearch <= TargetString.Len());
1516 const TCHAR*
const StartPosition = (
*TargetString) + StartSearch;
1517 const TCHAR* CurrPosition = StartPosition;
1518 int32 ParenthesisCount = 0;
1521 while (*CurrPosition != 0 && *CurrPosition !=
TEXT(
'('))
1527 if (*CurrPosition ==
TEXT(
'('))
1532 while (*CurrPosition != 0 && ParenthesisCount > 0)
1534 if (*CurrPosition ==
TEXT(
'('))
1538 else if (*CurrPosition ==
TEXT(
')'))
1546 if (ParenthesisCount == 0 && *(CurrPosition - 1) ==
TEXT(
')'))
1557 FString GeneratedName = DisplayString;
1562 for (int32 BadCharacterIndex = 0; BadCharacterIndex <
UE_ARRAY_COUNT(
TEXT(
"\"' ,/.:|&!~\n\r\t@#(){}[]=;^%$`")) - 1; ++BadCharacterIndex)
1564 const TCHAR TestChar[2] = {
TEXT(
"\"' ,/.:|&!~\n\r\t@#(){}[]=;^%$`")[BadCharacterIndex],
TEXT(
'\0') };
1565 const int32 NumReplacedChars = GeneratedName.ReplaceInline(TestChar, ReplaceWith);
1569 return GeneratedName;
1574 int32 LineBeginIndex = 0;
1577 const TCHAR*
const InputStart =
*Input;
1578 for (
const TCHAR* CurrentChar = InputStart; CurrentChar && *CurrentChar; ++CurrentChar)
1581 const bool bIsWindowsNewLine = (*CurrentChar ==
'\r' && *(CurrentChar + 1) ==
'\n');
1582 if (bIsWindowsNewLine || FChar::IsLinebreak(*CurrentChar))
1585 check(LineEndIndex >= LineBeginIndex);
1586 LineRanges.Emplace(FTextRange(LineBeginIndex, LineEndIndex));
1588 if (bIsWindowsNewLine)
1597 if (LineBeginIndex <= Input
.Len())
1599 LineRanges.Emplace(FTextRange(LineBeginIndex, Input.Len()));
#define UE_PTRDIFF_TO_INT32(argument)
#define UE_DISABLE_OPTIMIZATION_SHIP
#define UE_ENABLE_OPTIMIZATION_SHIP
int32 HexToBytes(const FString &HexString, uint8 *OutBytes)
static const uint32 MaxSupportedEscapeChars
static const TCHAR * CharToEscapeSeqMap[][2]
UE_DISABLE_OPTIMIZATION_SHIP void StripNegativeZero(double &InFloat)
#define STARTING_BUFFER_SIZE
FString SlugStringForValidName(const FString &DisplayString, const TCHAR *ReplaceWith)
void AppendCharacters(TArray< TCHAR > &Out, const CharType *Str, int32 Count)
TStringPointer< TCHAR, UTF16CHAR > FTCHARToUTF16
int32 FindMatchingClosingParenthesis(const FString &TargetString, const int32 StartSearch=0)
#define UE_ARRAY_COUNT(array)
#define GET_VARARGS_RESULT(msg, msgsize, len, lastarg, fmt, result)
virtual void Serialize(void *V, int64 Length)
ARK_API void AppendChars(const UCS2CHAR *Str, int32 Count)
ARK_API FString(const UTF8CHAR *Str)
FORCEINLINE const TCHAR & operator[](int32 Index) const UE_LIFETIMEBOUND
FORCEINLINE void MidInline(int32 Start, int32 Count=MAX_int32, bool bAllowShrinking=true)
UE_NODISCARD FString Reverse() const &
UE_NODISCARD FString TrimStart() const &
UE_NODISCARD FORCEINLINE FString Mid(int32 Start) const &
ARK_API void AppendChars(const ANSICHAR *Str, int32 Count)
UE_NODISCARD static ARK_API FString ConcatFF(const FString &Lhs, const FString &Rhs)
static UE_NODISCARD FString FromHexBlob(const uint8 *SrcBuffer, const uint32 SrcSize)
FORCEINLINE TCHAR & operator[](int32 Index) UE_LIFETIMEBOUND
UE_NODISCARD FString TrimEnd() const &
UE_NODISCARD static ARK_API FString ConcatFF(FString &&Lhs, FString &&Rhs)
ARK_API FString(int32 Len, const WIDECHAR *Str)
ARK_API void AppendChars(const UTF8CHAR *Str, int32 Count)
UE_NODISCARD FString TrimStart() &&
UE_NODISCARD static ARK_API FString ConcatFF(FString &&Lhs, const FString &Rhs)
UE_NODISCARD FString TrimStartAndEnd() &&
UE_NODISCARD FString TrimQuotes(bool *bQuotesRemoved=nullptr) const &
static UE_NODISCARD FORCEINLINE FString FromInt(int32 Num)
FString & operator=(FString &&)=default
ARK_API void RemoveAt(int32 Index, int32 Count=1, bool bAllowShrinking=true)
UE_NODISCARD FString Mid(int32 Start, int32 Count) const &
static bool ToHexBlob(const FString &Source, uint8 *DestBuffer, const uint32 DestSize)
void ConvertTabsToSpacesInline(const int32 InSpacesPerTab)
ARK_API int32 ParseIntoArrayLines(TArray< FString > &OutArray, bool InCullEmpty=true) const
UE_NODISCARD FString RightPad(int32 ChCount) const
UE_NODISCARD FORCEINLINE int32 Len() const
void TrimQuotesInline(bool *bQuotesRemoved=nullptr)
UE_NODISCARD FORCEINLINE friend FString operator+(const FString &Lhs, FString &&Rhs)
UE_NODISCARD FString TrimEnd() &&
bool Split(const FString &InS, FString *LeftS, FString *RightS, ESearchCase::Type SearchCase, ESearchDir::Type SearchDir=ESearchDir::FromStart) const
static UE_NODISCARD FString FromBlob(const uint8 *SrcBuffer, const uint32 SrcSize)
ARK_API void AppendChars(const WIDECHAR *Str, int32 Count)
ARK_API FString(const ANSICHAR *Str, int32 ExtraSlack)
UE_NODISCARD bool IsNumeric() const
ARK_API FString(const UCS2CHAR *Str, int32 ExtraSlack)
FString(const FString &)=default
static UE_NODISCARD FString FormatAsNumber(int32 InNumber)
UE_NODISCARD FORCEINLINE const TCHAR * operator*() const UE_LIFETIMEBOUND
UE_NODISCARD FString TrimQuotes(bool *bQuotesRemoved=nullptr) &&
ARK_API FString(const WIDECHAR *Str)
void TrimStartAndEndInline()
ARK_API FString(const UCS2CHAR *Str)
void SerializeAsANSICharArray(FArchive &Ar, int32 MinCharacters=0) const
UE_NODISCARD static ARK_API FString ConcatFF(const FString &Lhs, FString &&Rhs)
UE_NODISCARD int32 Find(const FString &SubStr, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase, ESearchDir::Type SearchDir=ESearchDir::FromStart, int32 StartPosition=INDEX_NONE) const
static bool ToBlob(const FString &Source, uint8 *DestBuffer, const uint32 DestSize)
void RemoveSpacesInline()
void InsertAt(int32 Index, const FString &Characters)
ARK_API FString(const WIDECHAR *Str, int32 ExtraSlack)
UE_NODISCARD FORCEINLINE bool Contains(const FString &SubStr, ESearchCase::Type SearchCase=ESearchCase::IgnoreCase, ESearchDir::Type SearchDir=ESearchDir::FromStart) const
bool Split(const FString &InS, FString *LeftS, FString *RightS) const
ARK_API FString(int32 Len, const UCS2CHAR *Str)
ARK_API FString(const ANSICHAR *Str)
ARK_API FString(const UTF8CHAR *Str, int32 ExtraSlack)
ARK_API FString(int32 Len, const ANSICHAR *Str)
void Reserve(int32 CharacterCount)
static UE_NODISCARD FString SanitizeFloat(double InFloat, const int32 InMinFractionalDigits=1)
UE_NODISCARD FString ReplaceQuotesWithEscapedQuotes() &&
ARK_API void Empty(int32 Slack)
UE_NODISCARD FString LeftPad(int32 ChCount) const
UE_NODISCARD FORCEINLINE friend FString operator+(FString &&Lhs, const FString &Rhs)
UE_NODISCARD FString Reverse() &&
UE_NODISCARD FORCEINLINE DataType & GetCharArray() UE_LIFETIMEBOUND
ARK_API FString(int32 Len, const UTF8CHAR *Str)
void TrimToNullTerminator()
UE_NODISCARD FORCEINLINE FString Left(int32 Count) const &
FORCEINLINE void CheckInvariants() const
FORCEINLINE void LeftInline(int32 Count, bool bAllowShrinking=true)
FString & operator=(const FString &)=default
void ReplaceEscapedCharWithCharInline(const TArray< TCHAR > *Chars=nullptr)
void InlineCombineSurrogates(FString &Str)
bool MatchesWildcardRecursive(const TCHAR *Target, int32 TargetLength, const TCHAR *Wildcard, int32 WildcardLength)
FORCEINLINE void ConstructWithSlack(TArray< TCHAR > &Data, const CharType *Src, int32 ExtraSlack)
UE_NODISCARD FORCEINLINE FString ConcatFStringRange(LhsType &&Lhs, const TCHAR *Rhs, int32 RhsLen)
UE_NODISCARD FORCEINLINE FString ConcatFStrings(LhsType &&Lhs, RhsType &&Rhs)
UE_NODISCARD FORCEINLINE FString ConcatRangeFString(const TCHAR *Lhs, int32 LhsLen, RhsType &&Rhs)
UE_NODISCARD FORCEINLINE FString ConcatCStringFString(const TCHAR *Lhs, RhsType &&Rhs)
UE_NODISCARD FORCEINLINE FString ConcatFStringCString(LhsType &&Lhs, const TCHAR *Rhs)
FORCEINLINE void ConstructFromCString(TArray< TCHAR > &Data, const CharType *Src)
FORCEINLINE void ConstructWithLength(TArray< TCHAR > &Data, int32 InCount, const CharType *InSrc)
FORCEINLINE bool IsByteSwapping()
FORCEINLINE int64 GetMaxSerializeSize() const
FORCEINLINE bool IsLoading() const
static void Free(void *Original)
static FORCEINLINE void * Memmove(void *Dest, const void *Src, SIZE_T Count)
static void * Realloc(void *Original, SIZE_T Size, uint32 Alignment=DEFAULT_ALIGNMENT)
static FORCEINLINE void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
static FORCEINLINE bool Compare(TCHAR Lhs, TCHAR Rhs)
static FORCEINLINE bool Compare(TCHAR Lhs, TCHAR Rhs)