Files
UnrealEngineUWP/Engine/Source/Runtime/Serialization/Private/Backends/JsonStructSerializerBackend.cpp
jeanmichel dignard 2ce7666d2d Copying //UE4/Dev-Core [at] 10708550 to Dev-Main (//UE4/Dev-Main)
#rb none

#ROBOMERGE-OWNER: jeanmichel.dignard
#ROBOMERGE-AUTHOR: robert.manuszewski
#ROBOMERGE-SOURCE: CL 10708666 in //UE4/Main/...
#ROBOMERGE-BOT: TOOLS (Main -> Dev-Tools-Staging) (v626-10872990)

[CL 10898071 by jeanmichel dignard in Dev-Tools-Staging branch]
2020-01-07 15:54:23 -05:00

258 lines
9.3 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Backends/JsonStructSerializerBackend.h"
#include "UObject/UnrealType.h"
#include "UObject/EnumProperty.h"
#include "UObject/TextProperty.h"
#include "UObject/PropertyPortFlags.h"
/* Internal helpers
*****************************************************************************/
namespace JsonStructSerializerBackend
{
// Writes a property value to the serialization output.
template<typename ValueType>
void WritePropertyValue(const TSharedRef<TJsonWriter<UCS2CHAR>> JsonWriter, const FStructSerializerState& State, const ValueType& Value)
{
if ((State.ValueProperty == nullptr) ||
(State.ValueProperty->ArrayDim > 1) ||
State.ValueProperty->GetOwner<FArrayProperty>() ||
State.ValueProperty->GetOwner<FSetProperty>())
{
JsonWriter->WriteValue(Value);
}
else if (State.KeyProperty != nullptr)
{
FString KeyString;
State.KeyProperty->ExportTextItem(KeyString, State.KeyData, nullptr, nullptr, PPF_None);
JsonWriter->WriteValue(KeyString, Value);
}
else
{
JsonWriter->WriteValue(State.ValueProperty->GetName(), Value);
}
}
// Writes a null value to the serialization output.
void WriteNull(const TSharedRef<TJsonWriter<UCS2CHAR>> JsonWriter, const FStructSerializerState& State)
{
if ((State.ValueProperty == nullptr) ||
(State.ValueProperty->ArrayDim > 1) ||
State.ValueProperty->GetOwner<FArrayProperty>() ||
State.ValueProperty->GetOwner<FSetProperty>())
{
JsonWriter->WriteNull();
}
else if (State.KeyProperty != nullptr)
{
FString KeyString;
State.KeyProperty->ExportTextItem(KeyString, State.KeyData, nullptr, nullptr, PPF_None);
JsonWriter->WriteNull(KeyString);
}
else
{
JsonWriter->WriteNull(State.ValueProperty->GetName());
}
}
}
/* IStructSerializerBackend interface
*****************************************************************************/
void FJsonStructSerializerBackend::BeginArray(const FStructSerializerState& State)
{
if (State.ValueProperty->GetOwner<FArrayProperty>())
{
JsonWriter->WriteArrayStart();
}
else if (State.KeyProperty != nullptr)
{
FString KeyString;
State.KeyProperty->ExportTextItem(KeyString, State.KeyData, nullptr, nullptr, PPF_None);
JsonWriter->WriteArrayStart(KeyString);
}
else
{
JsonWriter->WriteArrayStart(State.ValueProperty->GetName());
}
}
void FJsonStructSerializerBackend::BeginStructure(const FStructSerializerState& State)
{
if (State.ValueProperty != nullptr)
{
if (State.ValueProperty->GetOwner<FArrayProperty>() || State.ValueProperty->GetOwner<FSetProperty>())
{
JsonWriter->WriteObjectStart();
}
else if (State.KeyProperty != nullptr)
{
FString KeyString;
State.KeyProperty->ExportTextItem(KeyString, State.KeyData, nullptr, nullptr, PPF_None);
JsonWriter->WriteObjectStart(KeyString);
}
else
{
JsonWriter->WriteObjectStart(State.ValueProperty->GetName());
}
}
else
{
JsonWriter->WriteObjectStart();
}
}
void FJsonStructSerializerBackend::EndArray(const FStructSerializerState& /*State*/)
{
JsonWriter->WriteArrayEnd();
}
void FJsonStructSerializerBackend::EndStructure(const FStructSerializerState& /*State*/)
{
JsonWriter->WriteObjectEnd();
}
void FJsonStructSerializerBackend::WriteComment(const FString& Comment)
{
// Json does not support comments
}
void FJsonStructSerializerBackend::WriteProperty(const FStructSerializerState& State, int32 ArrayIndex)
{
using namespace JsonStructSerializerBackend;
// booleans
if (State.FieldType == FBoolProperty::StaticClass())
{
WritePropertyValue(JsonWriter, State, CastFieldChecked<FBoolProperty>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex));
}
// unsigned bytes & enumerations
else if (State.FieldType == FEnumProperty::StaticClass())
{
FEnumProperty* EnumProperty = CastFieldChecked<FEnumProperty>(State.ValueProperty);
WritePropertyValue(JsonWriter, State, EnumProperty->GetEnum()->GetNameStringByValue(EnumProperty->GetUnderlyingProperty()->GetSignedIntPropertyValue(EnumProperty->ContainerPtrToValuePtr<void>(State.ValueData, ArrayIndex))));
}
else if (State.FieldType == FByteProperty::StaticClass())
{
FByteProperty* ByteProperty = CastFieldChecked<FByteProperty>(State.ValueProperty);
if (ByteProperty->IsEnum())
{
WritePropertyValue(JsonWriter, State, ByteProperty->Enum->GetNameStringByValue(ByteProperty->GetPropertyValue_InContainer(State.ValueData, ArrayIndex)));
}
else
{
WritePropertyValue(JsonWriter, State, (double)ByteProperty->GetPropertyValue_InContainer(State.ValueData, ArrayIndex));
}
}
// floating point numbers
else if (State.FieldType == FDoubleProperty::StaticClass())
{
WritePropertyValue(JsonWriter, State, CastFieldChecked<FDoubleProperty>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex));
}
else if (State.FieldType == FFloatProperty::StaticClass())
{
WritePropertyValue(JsonWriter, State, CastFieldChecked<FFloatProperty>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex));
}
// signed integers
else if (State.FieldType == FIntProperty::StaticClass())
{
WritePropertyValue(JsonWriter, State, (double)CastFieldChecked<FIntProperty>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex));
}
else if (State.FieldType == FInt8Property::StaticClass())
{
WritePropertyValue(JsonWriter, State, (double)CastFieldChecked<FInt8Property>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex));
}
else if (State.FieldType == FInt16Property::StaticClass())
{
WritePropertyValue(JsonWriter, State, (double)CastFieldChecked<FInt16Property>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex));
}
else if (State.FieldType == FInt64Property::StaticClass())
{
WritePropertyValue(JsonWriter, State, (double)CastFieldChecked<FInt64Property>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex));
}
// unsigned integers
else if (State.FieldType == FUInt16Property::StaticClass())
{
WritePropertyValue(JsonWriter, State, (double)CastFieldChecked<FUInt16Property>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex));
}
else if (State.FieldType == FUInt32Property::StaticClass())
{
WritePropertyValue(JsonWriter, State, (double)CastFieldChecked<FUInt32Property>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex));
}
else if (State.FieldType == FUInt64Property::StaticClass())
{
WritePropertyValue(JsonWriter, State, (double)CastFieldChecked<FUInt64Property>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex));
}
// names, strings & text
else if (State.FieldType == FNameProperty::StaticClass())
{
WritePropertyValue(JsonWriter, State, CastFieldChecked<FNameProperty>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex).ToString());
}
else if (State.FieldType == FStrProperty::StaticClass())
{
WritePropertyValue(JsonWriter, State, CastFieldChecked<FStrProperty>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex));
}
else if (State.FieldType == FTextProperty::StaticClass())
{
const FText& TextValue = CastFieldChecked<FTextProperty>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex);
if (EnumHasAnyFlags(Flags, EStructSerializerBackendFlags::WriteTextAsComplexString))
{
FString TextValueString;
FTextStringHelper::WriteToBuffer(TextValueString, TextValue);
WritePropertyValue(JsonWriter, State, TextValueString);
}
else
{
WritePropertyValue(JsonWriter, State, TextValue.ToString());
}
}
// classes & objects
else if (State.FieldType == FClassProperty::StaticClass())
{
UObject* const& Value = CastFieldChecked<FClassProperty>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex);
WritePropertyValue(JsonWriter, State, Value ? Value->GetPathName() : FString());
}
else if (State.FieldType == FSoftClassProperty::StaticClass())
{
FSoftObjectPtr const& Value = CastFieldChecked<FSoftClassProperty>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex);
WritePropertyValue(JsonWriter, State, Value.IsValid() ? Value->GetPathName() : FString());
}
else if (State.FieldType == FObjectProperty::StaticClass())
{
UObject* const& Value = CastFieldChecked<FObjectProperty>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex);
WritePropertyValue(JsonWriter, State, Value ? Value->GetPathName() : FString());
}
else if (State.FieldType == FWeakObjectProperty::StaticClass())
{
FWeakObjectPtr const& Value = CastFieldChecked<FWeakObjectProperty>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex);
WritePropertyValue(JsonWriter, State, Value.IsValid() ? Value.Get()->GetPathName() : FString());
}
else if (State.FieldType == FSoftObjectProperty::StaticClass())
{
FSoftObjectPtr const& Value = CastFieldChecked<FSoftObjectProperty>(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex);
WritePropertyValue(JsonWriter, State, Value.ToString());
}
// unsupported property type
else
{
UE_LOG(LogSerialization, Verbose, TEXT("FJsonStructSerializerBackend: Property %s cannot be serialized, because its type (%s) is not supported"), *State.ValueProperty->GetFName().ToString(), *State.ValueType->GetFName().ToString());
}
}