From cf8c9f0982fb5d384503f28f05f87fe2b156ed90 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 30 Sep 2024 12:20:34 +0200 Subject: [PATCH] Add basic Variant parsing from text --- Source/Engine/Core/Types/StringView.cpp | 2 +- Source/Engine/Core/Types/Variant.cpp | 67 ++++++++++++++++++++++++- Source/Engine/Core/Types/Variant.h | 3 ++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Core/Types/StringView.cpp b/Source/Engine/Core/Types/StringView.cpp index 39404179b..24a3978f8 100644 --- a/Source/Engine/Core/Types/StringView.cpp +++ b/Source/Engine/Core/Types/StringView.cpp @@ -35,7 +35,7 @@ StringView StringView::Left(int32 count) const StringView StringView::Right(int32 count) const { const int32 countClamped = count < 0 ? 0 : count < Length() ? count : Length(); - return StringView(**this + Length() - countClamped); + return StringView(**this + countClamped, Length() - countClamped); } StringView StringView::Substring(int32 startIndex) const diff --git a/Source/Engine/Core/Types/Variant.cpp b/Source/Engine/Core/Types/Variant.cpp index 3dd403d5f..3aea34368 100644 --- a/Source/Engine/Core/Types/Variant.cpp +++ b/Source/Engine/Core/Types/Variant.cpp @@ -2449,7 +2449,9 @@ void Variant::SetType(const VariantType& type) case VariantType::Structure: AllocStructure(); break; - default: ; + default: + AsUint64 = 0; + break; } } @@ -3065,6 +3067,69 @@ void Variant::DeleteValue() SetType(VariantType(VariantType::Null)); } +Variant Variant::Parse(const StringView& text, const VariantType& type) +{ + Variant result; + result.SetType(type); + if (text.IsEmpty()) + return result; + if (type != VariantType()) + { + switch (type.Type) + { + case VariantType::Bool: + if (text == TEXT("1") || text.Compare(StringView(TEXT("true"), 4), StringSearchCase::IgnoreCase) == 0) + result.AsBool = true; + break; + case VariantType::Int16: + StringUtils::Parse(text.Get(), &result.AsInt16); + break; + case VariantType::Uint16: + StringUtils::Parse(text.Get(), &result.AsUint16); + break; + case VariantType::Int: + StringUtils::Parse(text.Get(), &result.AsInt); + break; + case VariantType::Uint: + StringUtils::Parse(text.Get(), &result.AsUint); + break; + case VariantType::Int64: + StringUtils::Parse(text.Get(), &result.AsInt64); + break; + case VariantType::Uint64: + case VariantType::Enum: + StringUtils::Parse(text.Get(), &result.AsUint64); + break; + case VariantType::Float: + StringUtils::Parse(text.Get(), &result.AsFloat); + break; + case VariantType::Double: + StringUtils::Parse(text.Get(), &result.AsFloat); + result.AsDouble = (float)result.AsFloat; + break; + case VariantType::String: + result.SetString(text); + default: + break; + } + } + else + { + // Parse as number + int32 valueInt; + if (!StringUtils::Parse(text.Get(), text.Length(), &valueInt)) + { + result = valueInt; + } + else + { + // Fallback to string + result.SetString(text); + } + } + return result; +} + bool Variant::CanCast(const Variant& v, const VariantType& to) { if (v.Type == to) diff --git a/Source/Engine/Core/Types/Variant.h b/Source/Engine/Core/Types/Variant.h index fa7f748fe..cd05fc038 100644 --- a/Source/Engine/Core/Types/Variant.h +++ b/Source/Engine/Core/Types/Variant.h @@ -381,6 +381,9 @@ public: // Frees the object or data owned by this Variant container (eg. structure or object). void DeleteValue(); + // Parses the text into the Variant value. Allows to specify explicit value type. + static Variant Parse(const StringView& text, const VariantType& type = VariantType()); + FORCE_INLINE Variant Cast(const VariantType& to) const { return Cast(*this, to);