forked from LuckyRobots/LuckyWorldV2
219 lines
5.6 KiB
C++
219 lines
5.6 KiB
C++
// Copyright 2018-current Getnamo. All Rights Reserved
|
|
|
|
|
|
#include "SIOMessageConvert.h"
|
|
#include "Runtime/Json/Public/Serialization/JsonWriter.h"
|
|
#include "Runtime/Json/Public/Policies/CondensedJsonPrintPolicy.h"
|
|
#include "SIOJsonValue.h"
|
|
|
|
DEFINE_LOG_CATEGORY(SocketIO);
|
|
|
|
typedef TJsonWriterFactory< TCHAR, TCondensedJsonPrintPolicy<TCHAR> > FCondensedJsonStringWriterFactory;
|
|
typedef TJsonWriter< TCHAR, TCondensedJsonPrintPolicy<TCHAR> > FCondensedJsonStringWriter;
|
|
|
|
TSharedPtr<FJsonValue> USIOMessageConvert::ToJsonValue(const sio::message::ptr& Message)
|
|
{
|
|
if (Message == nullptr)
|
|
{
|
|
return MakeShareable(new FJsonValueNull());
|
|
}
|
|
|
|
auto flag = Message->get_flag();
|
|
|
|
if (flag == sio::message::flag_integer)
|
|
{
|
|
return MakeShareable(new FJsonValueNumber(Message->get_int()));
|
|
}
|
|
else if (flag == sio::message::flag_double)
|
|
{
|
|
return MakeShareable(new FJsonValueNumber(Message->get_double()));
|
|
}
|
|
else if (flag == sio::message::flag_string)
|
|
{
|
|
return MakeShareable(new FJsonValueString(FStringFromStd(Message->get_string())));
|
|
}
|
|
else if (flag == sio::message::flag_binary)
|
|
{
|
|
//FString WarningString = FString::Printf(TEXT("<binary (size %d bytes) not supported in FJsonValue, use raw sio::message methods>"), Binary->length());
|
|
|
|
//convert sio buffer ptr into the array
|
|
TArray<uint8> Buffer;
|
|
Buffer.Append((uint8*)(Message->get_binary()->data()), Message->get_binary()->size());
|
|
//todo: investigate if binary optimization is possible? Do we copy?
|
|
|
|
return MakeShareable(new FJsonValueBinary(Buffer));
|
|
}
|
|
else if (flag == sio::message::flag_array)
|
|
{
|
|
auto MessageVector = Message->get_vector();
|
|
TArray< TSharedPtr<FJsonValue> > InArray;
|
|
|
|
InArray.Reset(MessageVector.size());
|
|
|
|
for (auto ItemMessage : MessageVector)
|
|
{
|
|
InArray.Add(ToJsonValue(ItemMessage));
|
|
}
|
|
|
|
return MakeShareable(new FJsonValueArray(InArray));
|
|
}
|
|
else if (flag == sio::message::flag_object)
|
|
{
|
|
auto MessageMap = Message->get_map();
|
|
TSharedPtr<FJsonObject> InObject = MakeShareable(new FJsonObject());
|
|
|
|
for (auto MapPair : MessageMap)
|
|
{
|
|
InObject->SetField(FStringFromStd(MapPair.first), ToJsonValue(MapPair.second));
|
|
}
|
|
|
|
return MakeShareable(new FJsonValueObject(InObject));
|
|
}
|
|
else if (flag == sio::message::flag_boolean)
|
|
{
|
|
return MakeShareable(new FJsonValueBoolean(Message->get_bool()));
|
|
}
|
|
else if (flag == sio::message::flag_null)
|
|
{
|
|
return MakeShareable(new FJsonValueNull());
|
|
}
|
|
else
|
|
{
|
|
return MakeShareable(new FJsonValueNull());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
sio::message::ptr USIOMessageConvert::ToSIOMessage(const TSharedPtr<FJsonValue>& JsonValue)
|
|
{
|
|
if (!JsonValue.IsValid())
|
|
{
|
|
return sio::null_message::create();
|
|
}
|
|
else if (JsonValue->Type == EJson::None)
|
|
{
|
|
return sio::null_message::create();
|
|
}
|
|
else if (JsonValue->Type == EJson::Null)
|
|
{
|
|
return sio::null_message::create();
|
|
}
|
|
else if (JsonValue->Type == EJson::String)
|
|
{
|
|
if (FJsonValueBinary::IsBinary(JsonValue))
|
|
{
|
|
auto BinaryArray = FJsonValueBinary::AsBinary(JsonValue);
|
|
return sio::binary_message::create(std::make_shared<std::string>((char*)BinaryArray.GetData(), BinaryArray.Num()));
|
|
}
|
|
else
|
|
{
|
|
return sio::string_message::create(StdString(JsonValue->AsString()));
|
|
}
|
|
}
|
|
else if (JsonValue->Type == EJson::Number)
|
|
{
|
|
return sio::double_message::create(JsonValue->AsNumber());
|
|
}
|
|
else if (JsonValue->Type == EJson::Boolean)
|
|
{
|
|
return sio::bool_message::create(JsonValue->AsBool());
|
|
}
|
|
else if (JsonValue->Type == EJson::Array)
|
|
{
|
|
auto ValueArray = JsonValue->AsArray();
|
|
auto ArrayMessage = sio::array_message::create();
|
|
|
|
for (auto ItemValue : ValueArray)
|
|
{
|
|
//must use get_vector() for each
|
|
ArrayMessage->get_vector().push_back(ToSIOMessage(ItemValue));
|
|
}
|
|
|
|
return ArrayMessage;
|
|
}
|
|
else if (JsonValue->Type == EJson::Object)
|
|
{
|
|
auto ValueTmap = JsonValue->AsObject()->Values;
|
|
|
|
auto ObjectMessage = sio::object_message::create();
|
|
|
|
for (auto ItemPair : ValueTmap)
|
|
{
|
|
//important to use get_map() directly to insert the key in the correct map and not a pointer copy
|
|
ObjectMessage->get_map()[StdString(ItemPair.Key)] = ToSIOMessage(ItemPair.Value);
|
|
}
|
|
|
|
return ObjectMessage;
|
|
}
|
|
else
|
|
{
|
|
return sio::null_message::create();
|
|
}
|
|
}
|
|
|
|
//We assume utf8 in transport
|
|
std::string USIOMessageConvert::StdString(FString UEString)
|
|
{
|
|
return std::string(TCHAR_TO_UTF8(*UEString));
|
|
}
|
|
|
|
FString USIOMessageConvert::FStringFromStd(std::string StdString)
|
|
{
|
|
return FString(UTF8_TO_TCHAR(StdString.c_str()));
|
|
}
|
|
|
|
std::map<std::string, std::string> USIOMessageConvert::JsonObjectToStdStringMap(TSharedPtr<FJsonObject> InObject)
|
|
{
|
|
std::map<std::string, std::string> ParamMap;
|
|
|
|
if (InObject.IsValid())
|
|
{
|
|
for (auto Pair : InObject->Values)
|
|
{
|
|
TSharedPtr<FJsonValue> Value = Pair.Value;
|
|
|
|
//If it's a string value, add it to the std map
|
|
if (Value->Type == EJson::String)
|
|
{
|
|
ParamMap[USIOMessageConvert::StdString(Pair.Key)] = USIOMessageConvert::StdString(Value->AsString());
|
|
}
|
|
}
|
|
}
|
|
|
|
return ParamMap;
|
|
}
|
|
|
|
TMap<FString, FString> USIOMessageConvert::JsonObjectToFStringMap(TSharedPtr<FJsonObject> InObject)
|
|
{
|
|
TMap<FString, FString> ParamMap;
|
|
|
|
if (InObject.IsValid())
|
|
{
|
|
for (auto Pair : InObject->Values)
|
|
{
|
|
TSharedPtr<FJsonValue> Value = Pair.Value;
|
|
|
|
//If it's a string value, add it to the std map
|
|
if (Value->Type == EJson::String)
|
|
{
|
|
ParamMap.Add(Pair.Key, Value->AsString());
|
|
}
|
|
}
|
|
}
|
|
|
|
return ParamMap;
|
|
}
|
|
|
|
std::map<std::string, std::string> USIOMessageConvert::FStringMapToStdStringMap(const TMap<FString, FString>& InMap)
|
|
{
|
|
std::map<std::string, std::string> ParamMap;
|
|
|
|
for (auto Pair : InMap)
|
|
{
|
|
ParamMap[USIOMessageConvert::StdString(Pair.Key)] = USIOMessageConvert::StdString(Pair.Value);
|
|
}
|
|
|
|
return ParamMap;
|
|
}
|