Files
UnrealEngineUWP/Engine/Source/Programs/UnrealHeaderTool/Private/StringUtils.cpp
michael noland 117f6b5a54 UnrealHeaderTool: Fixes for various unsafe implicit type conversion warnings (includes a few CoreUObject fixes as well, but that module is not enabled yet)
#jira UE-86949
[CODEREVIEW] marc.audy


#ROBOMERGE-SOURCE: CL 11053498 via CL 11053503 via CL 11053525
#ROBOMERGE-BOT: (v637-11041722)

[CL 11053536 by michael noland in Main branch]
2020-01-17 14:20:38 -05:00

128 lines
2.9 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "StringUtils.h"
#include "UnrealHeaderTool.h"
#include "Containers/UnrealString.h"
#include "Hash/CityHash.h"
FString GetClassNameWithPrefixRemoved(const FString& InClassName)
{
FString Result;
const FString ClassPrefix = GetClassPrefix( InClassName );
if( !ClassPrefix.IsEmpty() )
{
Result = InClassName.Right(InClassName.Len() - ClassPrefix.Len());
}
return Result;
}
FString GetClassNameWithoutPrefix(FString InClassNameOrFilename)
{
FString ClassNameWithoutPrefix = MoveTemp(InClassNameOrFilename);
// Check for header names (they don't come with a full path so we only search for the first dot)
int32 DotIndex;
if (ClassNameWithoutPrefix.FindChar(TEXT('.'), DotIndex))
{
ClassNameWithoutPrefix.MidInline(0, DotIndex, false);
}
else
{
const FString ClassPrefix = GetClassPrefix(ClassNameWithoutPrefix);
ClassNameWithoutPrefix.RightInline(ClassNameWithoutPrefix.Len() - ClassPrefix.Len(), false);
}
return ClassNameWithoutPrefix;
}
FString GetClassPrefix( const FString& InClassName )
{
bool bIsLabledDeprecated;
return GetClassPrefix(InClassName, /*out*/ bIsLabledDeprecated);
}
FString GetClassPrefix(const FString& InClassName, bool& bIsLabeledDeprecated )
{
FString ClassPrefix = InClassName.Left(1);
bIsLabeledDeprecated = false;
if (!ClassPrefix.IsEmpty())
{
const TCHAR ClassPrefixChar = ClassPrefix[0];
switch (ClassPrefixChar)
{
case TEXT('I'):
case TEXT('A'):
case TEXT('U'):
// If it is a class prefix, check for deprecated class prefix also
if (InClassName.Len() > 12 && FCString::Strncmp(&(InClassName[1]), TEXT("DEPRECATED_"), 11) == 0)
{
bIsLabeledDeprecated = true;
ClassPrefix = InClassName.Left(12);
}
break;
case TEXT('F'):
case TEXT('T'):
// Struct prefixes are also fine.
break;
default:
// If it's not a class or struct prefix, it's invalid
ClassPrefix.Reset();
break;
}
}
return ClassPrefix;
}
// Returns zero only for '\r' and '\0'
FORCEINLINE uint64 FindCrOrNulHelper(TCHAR C)
{
uint64 LoPassMask = ~((uint64(1) << '\0') | (uint64(1) << '\r'));
uint64 LoBit = uint64(1) << (C & 63);
uint64 LoPass = LoBit & LoPassMask;
uint64 HiPass = C & ~63;
return LoPass | HiPass;
}
// Finds next CR or null term with a single branch
// to help treat CR-LF and LF line endings identically
FORCEINLINE const TCHAR* FindCrOrNul(const TCHAR* Str)
{
while (FindCrOrNulHelper(*Str))
{
++Str;
}
return Str;
}
FORCEINLINE uint64 GenerateTextHash64(const TCHAR* Str)
{
uint64 Hash = 0;
while (true)
{
const TCHAR* End = FindCrOrNul(Str);
if (int32 Len = UE_PTRDIFF_TO_INT32(End - Str))
{
Hash = CityHash64WithSeed(reinterpret_cast<const char*>(Str), Len * sizeof(TCHAR), Hash);
}
if (*End == '\0')
{
return Hash;
}
Str = End + 1;
}
}
uint32 GenerateTextHash(const TCHAR* Data)
{
uint64 Hash = GenerateTextHash64(Data);
return static_cast<uint32>(Hash) + static_cast<uint32>(Hash >> 32);
}