Files
UnrealEngine/Engine/Source/Runtime/UniversalObjectLocator/Private/UniversalObjectLocatorStringUtils.cpp
2025-05-18 13:04:45 +08:00

67 lines
1.3 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "UniversalObjectLocatorStringUtils.h"
#include "Containers/StringView.h"
#include "Misc/Char.h"
namespace UE::UniversalObjectLocator
{
bool ParseUnsignedInteger(FStringView InString, uint32& OutResult, int32* OutNumCharsParsed)
{
if (InString.Len() == 0)
{
return false;
}
uint32 Parsed = 0;
uint32 Factor = 1;
int32 Index = 0;
for (; Index < InString.Len(); ++Index)
{
// Skip leading zeros
const TCHAR Current = InString[Index];
if (!FChar::IsDigit(Current))
{
break;
}
const uint32 ThisNumber = (Current - '0');
// Skip leading zeros
if (Parsed == 0 && ThisNumber == 0)
{
continue;
}
auto IsValidOperation = [](uint32 Start, uint32 Now) { return Now >= Start && Now < static_cast<uint32>(std::numeric_limits<int32>::max()); };
// Multiply by 10 using bit-shift trick (x*10 === x*2 + x*8 === x<<1 + x<<3) and check for overflow
const uint32 Value = ThisNumber * Factor;
const uint32 Shifted = Parsed * 10;
Factor *= 10;
if (Shifted < Parsed || Shifted+Value < Parsed)
{
// Overflow - can't be a uint
return false;
}
Parsed = Shifted+Value;
}
if (Index != 0)
{
OutResult = Parsed;
if (OutNumCharsParsed)
{
*OutNumCharsParsed = Index;
}
}
return Index != 0;
}
} // namespace UE::UniversalObjectLocator