cleanupFinish

This commit is contained in:
2025-10-02 20:55:14 +05:00
parent d8bc2790be
commit f26a1608f6
56 changed files with 2574 additions and 0 deletions
@@ -0,0 +1,7 @@
{
"BuildId": "23058290",
"Modules":
{
"EasyXMLParser": "UnrealEditor-EasyXMLParser.dll"
}
}
@@ -0,0 +1,8 @@
[FilterPlugin]
; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and
; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively.
;
; Examples:
; /README.txt
; /Extras/...
; /Binaries/ThirdParty/*.dll
@@ -0,0 +1,29 @@
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0.1",
"FriendlyName": "EasyXMLParser",
"Description": "Parse xml easily",
"Category": "Programming",
"CreatedBy": "ayumax",
"CreatedByURL": "https://github.com/ayumax",
"DocsURL": "https://github.com/ayumax/EasyXMLParserSample",
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/af98110080a4411a8eaf3b8e931b8655",
"SupportURL": "",
"CanContainContent": false,
"IsBetaVersion": false,
"Installed": true,
"Modules": [
{
"Name": "EasyXMLParser",
"Type": "Runtime",
"LoadingPhase": "Default",
"WhitelistPlatforms": [
"Android",
"Win64",
"Mac",
"IOS"
]
}
]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -0,0 +1,53 @@
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
public class EasyXMLParser : ModuleRules
{
public EasyXMLParser(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PublicIncludePaths.AddRange(
new string[] {
// ... add public include paths required here ...
}
);
PrivateIncludePaths.AddRange(
new string[] {
// ... add other private include paths required here ...
}
);
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
// ... add other public dependencies that you statically link with here ...
}
);
PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
"XmlParser"
}
);
DynamicallyLoadedModuleNames.AddRange(
new string[]
{
// ... add any modules that your module loads dynamically here ...
}
);
}
}
@@ -0,0 +1,52 @@
// Copyright 2019 ayumax. All Rights Reserved.
#include "EasyXMLAsyncLoadFromFile.h"
#include "Engine/World.h"
#include "TimerManager.h"
#include "Async/Async.h"
#include "Utils/CustomXMLParser.h"
#include "EasyXMLParseManager.h"
UEasyXMLAsyncLoadFromFile::UEasyXMLAsyncLoadFromFile(const FObjectInitializer& ObjectInitializer)
:Super(ObjectInitializer)
{
}
UEasyXMLAsyncLoadFromFile* UEasyXMLAsyncLoadFromFile::AsyncLoadFromFile(UObject* WorldContextObject, const FString& FilePath, bool IsAblolute)
{
auto Action = NewObject<UEasyXMLAsyncLoadFromFile>();
Action->RegisterWithGameInstance(WorldContextObject);
Action->_XMLFile = FilePath;
Action->_IsAblolute = IsAblolute;
return Action;
}
void UEasyXMLAsyncLoadFromFile::Activate()
{
AsyncTask(ENamedThreads::AnyBackgroundThreadNormalTask, [this]()
{
auto manager = NewObject<UEasyXMLParseManager>();
FString _errorMessage;
EEasyXMLParserErrorCode _isSuccessed;
auto rootElement = manager->LoadFromFile(_XMLFile, _IsAblolute, _isSuccessed, _errorMessage);
if (_isSuccessed == EEasyXMLParserErrorCode::Successed)
{
AsyncTask(ENamedThreads::GameThread, [this, rootElement]()
{
Successed.Broadcast(rootElement, TEXT(""));
SetReadyToDestroy();
});
}
else
{
AsyncTask(ENamedThreads::GameThread, [this, _errorMessage]()
{
Failed.Broadcast(nullptr, _errorMessage);
SetReadyToDestroy();
});
}
});
}
@@ -0,0 +1,50 @@
// Copyright 2019 ayumax. All Rights Reserved.
#include "EasyXMLAsyncLoadFromString.h"
#include "Engine/World.h"
#include "TimerManager.h"
#include "Async/Async.h"
#include "Utils/CustomXMLParser.h"
UEasyXMLAsyncLoadFromString::UEasyXMLAsyncLoadFromString(const FObjectInitializer& ObjectInitializer)
:Super(ObjectInitializer)
{
}
UEasyXMLAsyncLoadFromString* UEasyXMLAsyncLoadFromString::AsyncLoadFromString(UObject* WorldContextObject, const FString& XMLString)
{
auto Action = NewObject<UEasyXMLAsyncLoadFromString>();
Action->RegisterWithGameInstance(WorldContextObject);
Action->_XMLString = XMLString;
return Action;
}
void UEasyXMLAsyncLoadFromString::Activate()
{
AsyncTask(ENamedThreads::AnyBackgroundThreadNormalTask, [this]()
{
CustomXMLParser parser;
FString _errorMessage;
auto rootElement = parser.Parse(_XMLString, _errorMessage);
if (rootElement != nullptr)
{
AsyncTask(ENamedThreads::GameThread, [this, rootElement]()
{
Successed.Broadcast(rootElement, TEXT(""));
SetReadyToDestroy();
});
}
else
{
AsyncTask(ENamedThreads::GameThread, [this, _errorMessage]()
{
Failed.Broadcast(nullptr, _errorMessage);
SetReadyToDestroy();
});
}
});
}
@@ -0,0 +1,13 @@
// Copyright 2019 ayumax. All Rights Reserved.
#include "EasyXMLAttribute.h"
#include "EasyXMLElement.h"
UEasyXMLAttribute* UEasyXMLAttribute::CreateAttribute(UEasyXMLElement* ParentObject, FString _Name, FString _Value)
{
auto newAttribute = NewObject<UEasyXMLAttribute>(ParentObject == nullptr ? (UObject*)GetTransientPackage() : ParentObject);
newAttribute->Parent = ParentObject;
newAttribute->Name = _Name;
newAttribute->Value = _Value.TrimStartAndEnd();
return newAttribute;
}
@@ -0,0 +1,223 @@
// Copyright 2019 ayumax. All Rights Reserved.
#include "EasyXMLElement.h"
#include "EasyXMLAttribute.h"
#include "Internationalization/Regex.h"
UEasyXMLElement* UEasyXMLElement::CreateElement(UEasyXMLObject* ParentObject, FString Tag, FString Content, int32 _LineNumber)
{
auto newElement = NewObject<UEasyXMLElement>(ParentObject == nullptr ? (UObject*)GetTransientPackage() : ParentObject);
newElement->Parent = ParentObject;
newElement->Name = Tag;
newElement->Value = Content.TrimStartAndEnd();
newElement->LineNumber = _LineNumber;
return newElement;
}
int32 UEasyXMLElement::ReadInt(const FString& AccessString, int32 DefaultValue)
{
auto foundElement = ReadEasyXMLObject(AccessString);
if (!foundElement) return DefaultValue;
return foundElement->GetIntValue(DefaultValue);
}
float UEasyXMLElement::ReadFloat(const FString& AccessString, float DefaultValue)
{
auto foundElement = ReadEasyXMLObject(AccessString);
if (!foundElement) return DefaultValue;
return foundElement->GetFloatValue(DefaultValue);
}
FString UEasyXMLElement::ReadString(const FString& AccessString, const FString& DefaultValue)
{
auto foundElement = ReadEasyXMLObject(AccessString);
if (!foundElement) return DefaultValue;
return foundElement->GetStringValue(DefaultValue);
}
bool UEasyXMLElement::ReadBool(const FString& AccessString, bool DefaultValue)
{
auto foundElement = ReadEasyXMLObject(AccessString);
if (!foundElement) return DefaultValue;
return foundElement->GetBoolValue(DefaultValue);
}
UEasyXMLElement* UEasyXMLElement::ReadElement(const FString& AccessString, EEasyXMLParserFound& Result)
{
auto filterArray = ReadElements(AccessString, Result);
return filterArray.Num() > 0 ? filterArray[0] : nullptr;
}
TArray<UEasyXMLElement*> UEasyXMLElement::ReadElements(const FString& AccessString, EEasyXMLParserFound& Result)
{
TArray<UEasyXMLElement*> foundElements;
TArray<FString> Accessers;
AccessString.ParseIntoArray(Accessers, TEXT("."), true);
Result = EEasyXMLParserFound::NotFound;
auto parentNode = this;
for (int i = 0; i < Accessers.Num(); ++i)
{
auto accesseName = Accessers[i];
if (accesseName.IsEmpty()) return foundElements;
if (accesseName[0] == TEXT('@'))
{
return foundElements;
}
FString elementName;
int32 arrayIndex = 0;
bool IsArrayAccess = IsAccessAsArray(accesseName, elementName, arrayIndex);
auto filterNodes = parentNode->GetElementsByTagName(elementName);
if (i == (Accessers.Num() - 1))
{
if (IsArrayAccess)
{
if (filterNodes.Num() > arrayIndex)
{
foundElements.Emplace(filterNodes[arrayIndex]);
}
}
else
{
foundElements = filterNodes;
}
}
else
{
if (filterNodes.Num() > arrayIndex)
{
parentNode = filterNodes[arrayIndex];
}
if (!parentNode) return foundElements;
}
}
Result = EEasyXMLParserFound::Found;
return foundElements;
}
UEasyXMLObject* UEasyXMLElement::ReadEasyXMLObject(const FString& AccessString)
{
TArray<FString> Accessers;
AccessString.ParseIntoArray(Accessers, TEXT("."), true);
auto parentNode = this;
for (auto accesseName : Accessers)
{
if (!parentNode) return nullptr;
if (accesseName.IsEmpty()) return nullptr;
if (accesseName[0] == TEXT('@'))
{
EEasyXMLParserFound retFound;
return parentNode->GetAttribute(accesseName.Mid(1), retFound);
}
FString elementName;
int32 arrayIndex = 0;
IsAccessAsArray(accesseName, elementName, arrayIndex);
auto filterNodes = parentNode->GetElementsByTagName(elementName);
if (filterNodes.Num() > arrayIndex)
{
parentNode = filterNodes[arrayIndex];
}
else
{
return nullptr;
}
}
return parentNode;
}
TArray<UEasyXMLElement*> UEasyXMLElement::GetElementsByTagName(const FString& TagName)
{
TArray<UEasyXMLElement*> foundElements = Children.FilterByPredicate(
[TagName](UEasyXMLElement* child)
{
return child->Name.Equals(TagName, ESearchCase::IgnoreCase);
});
return foundElements;
}
UEasyXMLAttribute* UEasyXMLElement::GetAttribute(const FString& AtrributeName, EEasyXMLParserFound& Result)
{
if (Attributes.Contains(AtrributeName))
{
Result = EEasyXMLParserFound::Found;
return Attributes[AtrributeName];
}
Result = EEasyXMLParserFound::NotFound;
return nullptr;
}
bool UEasyXMLElement::IsAccessAsArray(const FString& AccessName, FString& ElementName, int32& ArrayIndex)
{
const FRegexPattern pattern = FRegexPattern(FString(TEXT("(.*)\\[([0-9]+)\\]$")));
FRegexMatcher matcher(pattern, AccessName);
while (matcher.FindNext())
{
ElementName = matcher.GetCaptureGroup(1);
FString numStr = matcher.GetCaptureGroup(2);
if (numStr.IsNumeric())
{
ArrayIndex = (FCString::Atoi(*numStr));
}
return true;
}
ElementName = AccessName;
ArrayIndex = 0;
return false;
}
bool UEasyXMLElement::IsContainAttributeKeys(const TArray<FString>& Keys, TArray<FString>& FoundAttributeKeys)
{
TArray<FString> attributeKeys;
Attributes.GetKeys(attributeKeys);
for (auto key : Keys)
{
bool found = false;
for (auto attributeKey : attributeKeys)
{
if (key.Equals(attributeKey, ESearchCase::IgnoreCase))
{
found = true;
FoundAttributeKeys.Emplace(attributeKey);
}
}
if (!found) return false;
}
return true;
}
@@ -0,0 +1,49 @@
// Copyright 2019 ayumax. All Rights Reserved.
#include "EasyXMLObject.h"
#include "Utils/CustomXMLParser.h"
int32 UEasyXMLObject::GetIntValue(int32 DefaultValue)
{
if (Value.IsEmpty()) return DefaultValue;
int32 _index = 0;
if (Value.IsNumeric() && !Value.FindChar(TEXT('.'), _index))
{
return FCString::Atoi(*Value);
}
return DefaultValue;
}
float UEasyXMLObject::GetFloatValue(float DefaultValue)
{
if (Value.IsEmpty()) return DefaultValue;
auto isSuccess = Value.IsNumeric();
return isSuccess ? FCString::Atof(*Value) : DefaultValue;
}
FString UEasyXMLObject::GetStringValue(FString DefaultValue)
{
if (Value.IsEmpty()) return DefaultValue;
return Value;
}
bool UEasyXMLObject::GetBoolValue(bool DefaultValue)
{
if (Value.IsEmpty()) return DefaultValue;
if (Value.Equals(TEXT("true"), ESearchCase::IgnoreCase))
{
return true;
}
else if (Value.Equals(TEXT("false"), ESearchCase::IgnoreCase))
{
return false;
}
return DefaultValue;
}
@@ -0,0 +1,37 @@
// Copyright 2019 ayumax. All Rights Reserved.
#include "EasyXMLParseManager.h"
#include "Misc/Paths.h"
#include "Misc/FileHelper.h"
#include "EasyXMLElement.h"
#include "Utils/CustomXMLParser.h"
UEasyXMLElement* UEasyXMLParseManager::LoadFromString(const FString& XMLString, EEasyXMLParserErrorCode& Result, FString& ErrorMessage)
{
CustomXMLParser parser;
FString _errorMessage;
auto rootElement = parser.Parse(XMLString, _errorMessage);
Result = rootElement != nullptr ? EEasyXMLParserErrorCode::Successed : EEasyXMLParserErrorCode::Failed;
ErrorMessage = _errorMessage;
return rootElement;
}
UEasyXMLElement* UEasyXMLParseManager::LoadFromFile(const FString& FilePath, bool IsAblolute, EEasyXMLParserErrorCode& Result, FString& ErrorMessage)
{
auto readPath = FilePath;
if (!IsAblolute)
{
readPath = FPaths::Combine(FPaths::ProjectContentDir(), FilePath);
}
if (!FPaths::FileExists(readPath)) return nullptr;
FString xmlString;
FFileHelper::LoadFileToString(xmlString, *readPath);
return LoadFromString(xmlString, Result, ErrorMessage);
}
@@ -0,0 +1,20 @@
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#include "EasyXMLParser.h"
#define LOCTEXT_NAMESPACE "FEasyXMLParserModule"
void FEasyXMLParserModule::StartupModule()
{
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
}
void FEasyXMLParserModule::ShutdownModule()
{
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
// we call this function before unloading the module.
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FEasyXMLParserModule, EasyXMLParser)
@@ -0,0 +1,270 @@
// Copyright 2019 ayumax. All Rights Reserved.
#include "Misc/AutomationTest.h"
#include "EasyXMLParseManager.h"
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FNodeAccessTest, "EasyXMLParser.NodeAccessTest", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::SmokeFilter)
bool FNodeAccessTest::RunTest(const FString& Parameters)
{
{
FString xmlString = TEXT("<root>\r")
TEXT("<!-- comment desu -->\r")
TEXT("<abc attr1=\"10\" attr2=\"false\">\r")
TEXT("123\r")
TEXT("</abc>\r")
TEXT("<abc/>\r")
TEXT("<abc>40</abc>\r")
TEXT("<abc>ZZZZ</abc>\r")
TEXT("<bbb>\r")
TEXT("bbbChild\r")
TEXT("</bbb>\r")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.abc")), TEXT("123"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.abc[0]")), TEXT("123"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.abc[1]")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.abc[2]")), TEXT("40"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.abc[3]")), TEXT("ZZZZ"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.bbb")), TEXT("bbbChild"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.abc[0].@attr1")), TEXT("10"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.abc[0].@attr2")), TEXT("false"));
}
return true;
}
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FNodeAccessTest2, "EasyXMLParser.NodeAccessTest2", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::SmokeFilter)
bool FNodeAccessTest2::RunTest(const FString& Parameters)
{
FString XMLSource =
TEXT("<PurchaseOrder PurchaseOrderNumber=\"99503\" OrderDate=\"1999-10-20\">\r")
TEXT("<Address Type=\"Shipping\">\r")
TEXT("<Name>Ellen Adams</Name>\r")
TEXT("<Street>123 Maple Street</Street>\r")
TEXT("<City>Mill Valley</City>\r")
TEXT("<State>CA</State>\r")
TEXT("<Zip>10999</Zip>\r")
TEXT("<Country>USA</Country>\r")
TEXT("</Address>\r")
TEXT("<Address Type=\"Billing\">\r")
TEXT("<Name>Tai Yee</Name>\r")
TEXT("<Street>8 Oak Avenue</Street>\r")
TEXT("<City>Old Town</City>\r")
TEXT("<State>PA</State>\r")
TEXT("<Zip>95819</Zip>\r")
TEXT("<Country>USA</Country>\r")
TEXT("</Address>\r")
TEXT("<DeliveryNotes>Please leave packages in shed by driveway.</DeliveryNotes>\r")
TEXT("<Items>\r")
TEXT("<Item PartNumber=\"872-AA\">\r")
TEXT("<ProductName>Lawnmower</ProductName>\r")
TEXT("<Quantity>1</Quantity>\r")
TEXT("<USPrice>148.95</USPrice>\r")
TEXT("<Comment>Confirm this is electric</Comment>\r")
TEXT("</Item>\r")
TEXT("<Item PartNumber=\"926-AA\">\r")
TEXT("<ProductName>Baby Monitor</ProductName>\r")
TEXT("<Quantity>2</Quantity>\r")
TEXT("<USPrice>39.98</USPrice>\r")
TEXT("<ShipDate>1999-05-21</ShipDate>\r")
TEXT("</Item>\r")
TEXT("</Items>\r")
TEXT("</PurchaseOrder>\r");
{
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(XMLSource, result, errorMessage);
TestEqual(TEXT("success read"), rootNode->ReadInt(TEXT("PurchaseOrder.@PurchaseOrderNumber")), 99503);
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.@OrderDate")), TEXT("1999-10-20"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].@Type")), TEXT("Shipping"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].Name")), TEXT("Ellen Adams"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].Street")), TEXT("123 Maple Street"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].City")), TEXT("Mill Valley"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].State")), TEXT("CA"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].Zip")), TEXT("10999"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].Country")), TEXT("USA"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].@Type")), TEXT("Billing"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].Name")), TEXT("Tai Yee"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].Street")), TEXT("8 Oak Avenue"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].City")), TEXT("Old Town"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].State")), TEXT("PA"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].Zip")), TEXT("95819"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].Country")), TEXT("USA"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.DeliveryNotes")), TEXT("Please leave packages in shed by driveway."));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[0].@PartNumber")), TEXT("872-AA"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[0].ProductName")), TEXT("Lawnmower"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[0].Quantity")), TEXT("1"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[0].USPrice")), TEXT("148.95"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[0].Comment")), TEXT("Confirm this is electric"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[1].@PartNumber")), TEXT("926-AA"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[1].ProductName")), TEXT("Baby Monitor"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[1].Quantity")), TEXT("2"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[1].USPrice")), TEXT("39.98"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[1].ShipDate")), TEXT("1999-05-21"));
}
{
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(XMLSource, result, errorMessage);
EEasyXMLParserFound retFound;
auto Address0Node = rootNode->ReadElement(TEXT("PurchaseOrder.Address[0]"), retFound);
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
auto Address1Node = rootNode->ReadElement(TEXT("PurchaseOrder.Address[1]"), retFound);
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
auto Item0Node = rootNode->ReadElement(TEXT("PurchaseOrder.Items.Item[0]"), retFound);
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
auto Item1Node = rootNode->ReadElement(TEXT("PurchaseOrder.Items.Item[1]"), retFound);
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
TestEqual(TEXT("success read"), rootNode->ReadInt(TEXT("PurchaseOrder.@PurchaseOrderNumber")), 99503);
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.@OrderDate")), TEXT("1999-10-20"));
TestEqual(TEXT("success read"), Address0Node->ReadString(TEXT("@Type")), TEXT("Shipping"));
TestEqual(TEXT("success read"), Address0Node->ReadString(TEXT("Name")), TEXT("Ellen Adams"));
TestEqual(TEXT("success read"), Address0Node->ReadString(TEXT("Street")), TEXT("123 Maple Street"));
TestEqual(TEXT("success read"), Address0Node->ReadString(TEXT("City")), TEXT("Mill Valley"));
TestEqual(TEXT("success read"), Address0Node->ReadString(TEXT("State")), TEXT("CA"));
TestEqual(TEXT("success read"), Address0Node->ReadString(TEXT("Zip")), TEXT("10999"));
TestEqual(TEXT("success read"), Address0Node->ReadString(TEXT("Country")), TEXT("USA"));
TestEqual(TEXT("success read"), Address1Node->ReadString(TEXT("@Type")), TEXT("Billing"));
TestEqual(TEXT("success read"), Address1Node->ReadString(TEXT("Name")), TEXT("Tai Yee"));
TestEqual(TEXT("success read"), Address1Node->ReadString(TEXT("Street")), TEXT("8 Oak Avenue"));
TestEqual(TEXT("success read"), Address1Node->ReadString(TEXT("City")), TEXT("Old Town"));
TestEqual(TEXT("success read"), Address1Node->ReadString(TEXT("State")), TEXT("PA"));
TestEqual(TEXT("success read"), Address1Node->ReadString(TEXT("Zip")), TEXT("95819"));
TestEqual(TEXT("success read"), Address1Node->ReadString(TEXT("Country")), TEXT("USA"));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.DeliveryNotes")), TEXT("Please leave packages in shed by driveway."));
TestEqual(TEXT("success read"), Item0Node->ReadString(TEXT("@PartNumber")), TEXT("872-AA"));
TestEqual(TEXT("success read"), Item0Node->ReadString(TEXT("ProductName")), TEXT("Lawnmower"));
TestEqual(TEXT("success read"), Item0Node->ReadString(TEXT("Quantity")), TEXT("1"));
TestEqual(TEXT("success read"), Item0Node->ReadString(TEXT("USPrice")), TEXT("148.95"));
TestEqual(TEXT("success read"), Item0Node->ReadString(TEXT("Comment")), TEXT("Confirm this is electric"));
TestEqual(TEXT("success read"), Item1Node->ReadString(TEXT("@PartNumber")), TEXT("926-AA"));
TestEqual(TEXT("success read"), Item1Node->ReadString(TEXT("ProductName")), TEXT("Baby Monitor"));
TestEqual(TEXT("success read"), Item1Node->ReadString(TEXT("Quantity")), TEXT("2"));
TestEqual(TEXT("success read"), Item1Node->ReadString(TEXT("USPrice")), TEXT("39.98"));
TestEqual(TEXT("success read"), Item1Node->ReadString(TEXT("ShipDate")), TEXT("1999-05-21"));
}
{
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(XMLSource, result, errorMessage);
EEasyXMLParserFound retFound;
auto AddressNodes = rootNode->ReadElements(TEXT("PurchaseOrder.Address"), retFound);
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
auto ItemNodes = rootNode->ReadElements(TEXT("PurchaseOrder.Items.Item"), retFound);
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("@Type")), TEXT("Shipping"));
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Name")), TEXT("Ellen Adams"));
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Street")), TEXT("123 Maple Street"));
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("City")), TEXT("Mill Valley"));
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("State")), TEXT("CA"));
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Zip")), TEXT("10999"));
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Country")), TEXT("USA"));
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("@Type")), TEXT("Billing"));
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Name")), TEXT("Tai Yee"));
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Street")), TEXT("8 Oak Avenue"));
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("City")), TEXT("Old Town"));
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("State")), TEXT("PA"));
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Zip")), TEXT("95819"));
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Country")), TEXT("USA"));
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("@PartNumber")), TEXT("872-AA"));
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("ProductName")), TEXT("Lawnmower"));
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("Quantity")), TEXT("1"));
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("USPrice")), TEXT("148.95"));
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("Comment")), TEXT("Confirm this is electric"));
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("@PartNumber")), TEXT("926-AA"));
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("ProductName")), TEXT("Baby Monitor"));
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("Quantity")), TEXT("2"));
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("USPrice")), TEXT("39.98"));
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("ShipDate")), TEXT("1999-05-21"));
}
{
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(XMLSource, result, errorMessage);
TestEqual(TEXT("success read"), rootNode->ReadInt(TEXT("PurchaseOrder.PurchaseOrderNumber")), 0);
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.OrderDate")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].Type")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].Name-")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrde-r.Address[0].Street")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address-[0].City")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].State-")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder-.Address[0].Zip")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0]-.Country")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1]-.@Type")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder-.Address[1].Name")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].Stree-t")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1]-.City")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder-.Address[1].State")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].Zip-")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1]-.Country")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder-.DeliveryNotes")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[0].@PartNumber-")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[0]-.ProductName")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items-.Item[0].Quantity")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[4].USPrice")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[-1].Comment")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[8].@PartNumber")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[99].ProductName")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[7].Quantity")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[555].USPrice")), TEXT(""));
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[9999].ShipDate")), TEXT(""));
}
{
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(XMLSource, result, errorMessage);
EEasyXMLParserFound retFound;
auto AddressNodes = rootNode->ReadElements(TEXT("PurchaseOrder.Address"), retFound);
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
auto ItemNodes = rootNode->ReadElements(TEXT("PurchaseOrder.Items.Item"), retFound);
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("@Type-")), TEXT(""));
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Name-")), TEXT(""));
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Street-")), TEXT(""));
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("City-")), TEXT(""));
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("State-")), TEXT(""));
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Zip-")), TEXT(""));
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Country-")), TEXT(""));
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("@Type-")), TEXT(""));
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Name-")), TEXT(""));
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Street-")), TEXT(""));
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("City-")), TEXT(""));
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("State-")), TEXT(""));
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Zip-")), TEXT(""));
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Country-")), TEXT(""));
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("@PartNumber-")), TEXT(""));
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("ProductName-")), TEXT(""));
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("Quantity-")), TEXT(""));
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("USPrice-")), TEXT(""));
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("Comment-")), TEXT(""));
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("@PartNumber-")), TEXT(""));
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("ProductName-")), TEXT(""));
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("Quantity-")), TEXT(""));
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("USPrice-")), TEXT(""));
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("ShipDate-")), TEXT(""));
}
return true;
}
@@ -0,0 +1,428 @@
// Copyright 2019 ayumax. All Rights Reserved.
#include "Misc/AutomationTest.h"
#include "EasyXMLParseManager.h"
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FReadValueTest_Int, "EasyXMLParser.ReadValueTest.Int", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::SmokeFilter)
bool FReadValueTest_Int::RunTest(const FString& Parameters)
{
// parse success
{
FString xmlString = TEXT("<root>\r")
TEXT("<!-- comment desu -->\r")
TEXT("<abc attr1=\"10\" attr2=\"false\">\r")
TEXT("123\r")
TEXT("</abc>\r")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read int"), rootNode->ReadInt(TEXT("root.abc"), 0), 123);
}
// parse success
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("-123")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read int"), rootNode->ReadInt(TEXT("root.abc"), 0), -123);
}
// parse success
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("123456789")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read int"), rootNode->ReadInt(TEXT("root.abc"), 0), 123456789);
}
// parse ng(string)
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("text")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("ng read int(string)"), rootNode->ReadInt(TEXT("root.abc"), 0), 0);
}
// parse ng(float)
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("3.14")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("ng read int(float)"), rootNode->ReadInt(TEXT("root.abc"), 0), 0);
}
// parse ng(xml)
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("<def>")
TEXT("123")
TEXT("</def>")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("ng read int(xml)"), rootNode->ReadInt(TEXT("root.abc"), 0), 0);
}
return true;
}
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FReadValueTest_Float, "EasyXMLParser.ReadValueTest.Float", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::SmokeFilter)
bool FReadValueTest_Float::RunTest(const FString& Parameters)
{
// parse success
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("1.23")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read float"), rootNode->ReadFloat(TEXT("root.abc"), 0), 1.23f);
}
// parse success
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("-1.23")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read float"), rootNode->ReadFloat(TEXT("root.abc"), 0), -1.23f);
}
// parse success
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("123.456789")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read float"), rootNode->ReadFloat(TEXT("root.abc"), 0), 123.456789f);
}
// parse success
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("123")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read float"), rootNode->ReadFloat(TEXT("root.abc"), 0), 123.0f);
}
// parse ng(string)
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("text")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("ng read float(string)"), rootNode->ReadFloat(TEXT("root.abc"), 0), 0.0f);
}
// parse ng(xml)
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("<def>")
TEXT("1.23")
TEXT("</def>")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("ng read float(xml)"), rootNode->ReadFloat(TEXT("root.abc"), 0), 0.0f);
}
return true;
}
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FReadValueTest_Bool, "EasyXMLParser.ReadValueTest.Bool", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::SmokeFilter)
bool FReadValueTest_Bool::RunTest(const FString& Parameters)
{
// parse success
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("True")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read bool"), rootNode->ReadBool(TEXT("root.abc"), false), true);
}
// parse success
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("tRue")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read bool"), rootNode->ReadBool(TEXT("root.abc"), false), true);
}
// parse success
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("False")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read bool"), rootNode->ReadBool(TEXT("root.abc"), true), false);
}
// parse success
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("fAlse")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read bool"), rootNode->ReadBool(TEXT("root.abc"), true), false);
}
// parse ng(string)
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("text")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("ng read bool(string)"), rootNode->ReadBool(TEXT("root.abc"), false), false);
}
// parse ng(xml)
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("<def>")
TEXT("true")
TEXT("</def>")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("ng read bool(xml)"), rootNode->ReadBool(TEXT("root.abc"), false), false);
}
return true;
}
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FReadValueTest_String, "EasyXMLParser.ReadValueTest.String", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::SmokeFilter)
bool FReadValueTest_String::RunTest(const FString& Parameters)
{
// parse success
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("text")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read string"), rootNode->ReadString(TEXT("root.abc"), TEXT("")), TEXT("text"));
}
// parse success
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("123")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read string"), rootNode->ReadString(TEXT("root.abc"), TEXT("")), TEXT("123"));
}
// parse success
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("1.23")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read string"), rootNode->ReadString(TEXT("root.abc"), TEXT("")), TEXT("1.23"));
}
// parse success
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("true")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read string"), rootNode->ReadString(TEXT("root.abc"), TEXT("")), TEXT("true"));
}
// parse success
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("false")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read string"), rootNode->ReadString(TEXT("root.abc"), TEXT("")), TEXT("false"));
}
// parse ng(xml)
{
FString xmlString = TEXT("<root>")
TEXT("<abc>")
TEXT("<def>")
TEXT("text")
TEXT("</def>")
TEXT("</abc>")
TEXT("</root>");
EEasyXMLParserErrorCode result;
FString errorMessage;
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
TestEqual(TEXT("success read string"), rootNode->ReadString(TEXT("root.abc"), TEXT("")), TEXT(""));
}
return true;
}
@@ -0,0 +1,83 @@
// Copyright 2019 ayumax. All Rights Reserved.
#include "CustomXMLParser.h"
#include "Misc/FeedbackContext.h"
#include "EasyXMLElement.h"
#include "EasyXMLAttribute.h"
CustomXMLParser::CustomXMLParser()
{
}
CustomXMLParser::~CustomXMLParser()
{
}
UEasyXMLElement *CustomXMLParser::Parse(FString xmlString, FString &ErrorMessage)
{
RootElement = NewObject<UEasyXMLElement>();
XMLObjectStack.Emplace(RootElement);
FText _errorMessage;
int32 _errorMessageNumber;
if (!FFastXml::ParseXmlFile(this, TEXT(""), &xmlString[0], nullptr, false, false, _errorMessage, _errorMessageNumber))
{
ErrorMessage = FString::Printf(TEXT("line=%d, %s"), _errorMessageNumber, *_errorMessage.ToString());
return nullptr;
}
return RootElement;
}
bool CustomXMLParser::ProcessXmlDeclaration(const TCHAR *ElementData, int32 XmlFileLineNumber)
{
return true;
}
bool CustomXMLParser::ProcessElement(const TCHAR *ElementName, const TCHAR *ElementData, int32 XmlFileLineNumber)
{
auto currentNode = XMLObjectStack.Num() > 0 ? XMLObjectStack.Last() : nullptr;
auto newNode = UEasyXMLElement::CreateElement(currentNode, ElementName, ElementData, XmlFileLineNumber);
if (currentNode)
{
currentNode->Children.Emplace(newNode);
}
XMLObjectStack.Emplace(newNode);
return true;
}
bool CustomXMLParser::ProcessAttribute(const TCHAR *AttributeName, const TCHAR *AttributeValue)
{
auto currentNode = XMLObjectStack.Last();
if (!currentNode) return false;
if (currentNode->Attributes.Contains(AttributeName)) return false;
auto newAttribute = UEasyXMLAttribute::CreateAttribute(currentNode, AttributeName, AttributeValue);
currentNode->Attributes.Add(AttributeName, newAttribute);
return true;
}
bool CustomXMLParser::ProcessClose(const TCHAR *Element)
{
if (XMLObjectStack.Num() == 0) return false;
XMLObjectStack.RemoveAt(XMLObjectStack.Num() - 1);
return true;
}
bool CustomXMLParser::ProcessComment(const TCHAR *Comment)
{
if (XMLObjectStack.Num() == 0) return false;
XMLObjectStack.Last()->Comments.Emplace(Comment);
return true;
}
@@ -0,0 +1,68 @@
// Copyright 2019 ayumax. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "FastXml.h"
class UEasyXMLElement;
class CustomXMLParser : public IFastXmlCallback
{
public:
CustomXMLParser();
virtual ~CustomXMLParser();
UEasyXMLElement* Parse(FString xmlString, FString& ErrorMessage);
/**
* Called after the XML's header is parsed. This is usually the first call that you'll get back.
*
* @param ElementData Optional data for this element, nullptr if none
* @param XmlFileLineNumber Line number in the XML file we're on
*
* @return You should return true to continue processing the file, or false to stop processing immediately.
*/
virtual bool ProcessXmlDeclaration(const TCHAR* ElementData, int32 XmlFileLineNumber) override;
/**
* Called when a new XML element is encountered, starting a new scope. You'll receive a call to ProcessClose()
* when this element's scope has ended.
*
* @param ElementName The name of the element
* @param ElementData Optional data for this element, nullptr if none
* @param XmlFileLineNumber The line number in the XML file we're on
*
* @return You should return true to continue processing the file, or false to stop processing immediately.
*/
virtual bool ProcessElement(const TCHAR* ElementName, const TCHAR* ElementData, int32 XmlFileLineNumber) override;
/**
* Called when an XML attribute is encountered for the current scope's element.
*
* @param AttributeName The name of the attribute
* @param AttributeValue The value of the attribute
*
* @return You should return true to continue processing the file, or false to stop processing immediately.
*/
virtual bool ProcessAttribute(const TCHAR* AttributeName, const TCHAR* AttributeValue) override;
/**
* Called when an element's scope ends in the XML file
*
* @param ElementName Name of the element whose scope closed
*
* @return You should return true to continue processing the file, or false to stop processing immediately.
*/
virtual bool ProcessClose(const TCHAR* Element) override;
/**
* Called when a comment is encountered. This can happen pretty much anywhere in the file.
*
* @param Comment The comment text
*/
virtual bool ProcessComment(const TCHAR* Comment) override;
private:
TArray<UEasyXMLElement*> XMLObjectStack;
UEasyXMLElement* RootElement;
};
@@ -0,0 +1,40 @@
// Copyright 2019 ayumax. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "UObject/NoExportTypes.h"
#include "EasyXMLElement.h"
#include "EasyXMLAsyncLoadFromFile.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FEasyXMLAsyncLoadFromFile_Result, UEasyXMLElement*, XMLObject, FString, ErrorMessage);
UCLASS()
class EASYXMLPARSER_API UEasyXMLAsyncLoadFromFile : public UBlueprintAsyncActionBase
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintAssignable)
FEasyXMLAsyncLoadFromFile_Result Successed;
UPROPERTY(BlueprintAssignable)
FEasyXMLAsyncLoadFromFile_Result Failed;
private:
UPROPERTY(Transient)
FString _XMLFile;
UPROPERTY(Transient)
bool _IsAblolute;
public:
UEasyXMLAsyncLoadFromFile(const FObjectInitializer& ObjectInitializer);
UFUNCTION(BlueprintCallable, Category = "EasyXMLParser", meta = (WorldContext = "WorldContextObject", BlueprintInternalUseOnly = "true"))
static UEasyXMLAsyncLoadFromFile * AsyncLoadFromFile(UObject * WorldContextObject, const FString& FilePath, bool IsAblolute);
virtual void Activate() override;
};
@@ -0,0 +1,38 @@
// Copyright 2019 ayumax. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "UObject/NoExportTypes.h"
#include "EasyXMLElement.h"
#include "EasyXMLAsyncLoadFromString.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FEasyXMLAsyncLoadFromString_Result, UEasyXMLElement*, XMLObject, FString, ErrorMessage);
UCLASS()
class EASYXMLPARSER_API UEasyXMLAsyncLoadFromString : public UBlueprintAsyncActionBase
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintAssignable)
FEasyXMLAsyncLoadFromString_Result Successed;
UPROPERTY(BlueprintAssignable)
FEasyXMLAsyncLoadFromString_Result Failed;
private:
UPROPERTY(Transient)
FString _XMLString;
public:
UEasyXMLAsyncLoadFromString(const FObjectInitializer& ObjectInitializer);
UFUNCTION(BlueprintCallable, Category = "EasyXMLParser", meta = (WorldContext = "WorldContextObject", BlueprintInternalUseOnly = "true"))
static UEasyXMLAsyncLoadFromString* AsyncLoadFromString(UObject * WorldContextObject, const FString& XMLString);
virtual void Activate() override;
};
@@ -0,0 +1,18 @@
// Copyright 2019 ayumax. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "EasyXMLObject.h"
#include "EasyXMLAttribute.generated.h"
class UEasyXMLElement;
UCLASS(BlueprintType, Blueprintable)
class EASYXMLPARSER_API UEasyXMLAttribute : public UEasyXMLObject
{
GENERATED_BODY()
public:
static UEasyXMLAttribute* CreateAttribute(UEasyXMLElement* ParentObject, FString Name, FString Value);
};
@@ -0,0 +1,62 @@
// Copyright 2019 ayumax. All Rights Reserved.
#pragma once
#include "EasyXMLObject.h"
#include "EasyXMLParserEnums.h"
#include "EasyXMLElement.generated.h"
class UEasyXMLAttribute;
UCLASS(BlueprintType, Blueprintable)
class EASYXMLPARSER_API UEasyXMLElement : public UEasyXMLObject
{
GENERATED_BODY()
public:
static UEasyXMLElement* CreateElement(UEasyXMLObject* ParentObject, FString Tag, FString Content, int32 LineNumber);
public:
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|ReadValue")
int32 ReadInt(const FString& AccessString, int32 DefaultValue = 0);
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|ReadValue")
float ReadFloat(const FString& AccessString, float DefaultValue = 0.0f);
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|ReadValue")
FString ReadString(const FString& AccessString, const FString& DefaultValue = TEXT(""));
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|ReadValue")
bool ReadBool(const FString& AccessString, bool DefaultValue = false);
UFUNCTION(BlueprintCallable, Category = "EasyXMLParser|ReadValue", meta = (ExpandEnumAsExecs = "Result"))
UEasyXMLElement* ReadElement(const FString& AccessString, EEasyXMLParserFound& Result);
UFUNCTION(BlueprintCallable, Category = "EasyXMLParser|ReadValue", meta = (ExpandEnumAsExecs = "Result"))
TArray<UEasyXMLElement*> ReadElements(const FString& AccessString, EEasyXMLParserFound& Result);
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|Object", meta = (ExpandEnumAsExecs = "Result"))
UEasyXMLAttribute* GetAttribute(const FString& AtrributeName, EEasyXMLParserFound& Result);
public:
UEasyXMLObject* ReadEasyXMLObject(const FString& AccessString);
TArray<UEasyXMLElement*> GetElementsByTagName(const FString& TagName);
bool IsContainAttributeKeys(const TArray<FString>& Keys, TArray<FString>& FoundAttributeKeys);
private:
bool IsAccessAsArray(const FString& AccessName, FString& ElementName, int32& ArrayIndex);
public:
UPROPERTY(BlueprintReadOnly, Category = "EasyXMLParser|Object")
int32 LineNumber = 0;
UPROPERTY(BlueprintReadOnly, Category = "EasyXMLParser|Object")
TArray<UEasyXMLElement*> Children;
UPROPERTY(BlueprintReadOnly, Category = "EasyXMLParser|Object")
TMap<FString, UEasyXMLAttribute*> Attributes;
UPROPERTY(BlueprintReadOnly, Category = "EasyXMLParser|Object")
TArray<FString> Comments;
};
@@ -0,0 +1,37 @@
// Copyright 2019 ayumax. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "EasyXMLObject.generated.h"
UCLASS(BlueprintType, Blueprintable)
class EASYXMLPARSER_API UEasyXMLObject : public UObject
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|GetValue")
int32 GetIntValue(int32 DefaultValue = 0);
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|GetValue")
float GetFloatValue(float DefaultValue = 0.0f);
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|GetValue")
FString GetStringValue(FString DefaultValue = TEXT(""));
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|GetValue")
bool GetBoolValue(bool DefaultValue = false);
public:
UPROPERTY(BlueprintReadOnly, Category = "EasyXMLParser|Object")
FString Name = TEXT("");
UPROPERTY(BlueprintReadOnly, Category = "EasyXMLParser|Object")
FString Value = TEXT("");
UPROPERTY(BlueprintReadOnly, Category = "EasyXMLParser|Object")
UEasyXMLObject* Parent = nullptr;
};
@@ -0,0 +1,36 @@
// Copyright 2019 ayumax. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "EasyXMLElement.h"
#include "EasyXMLParserEnums.h"
#include "EasyXMLParseManager.generated.h"
/**
*
*/
UCLASS(BlueprintType, Blueprintable)
class EASYXMLPARSER_API UEasyXMLParseManager : public UObject
{
GENERATED_BODY()
public:
/**
* load xml file
* @param FilePath - xml file path
* @param IsAblolute - true:FilePath is absolute path, false:Relative path from "Content"
* @return xml object
*/
UFUNCTION(BlueprintCallable, Category = "EasyXMLParser", meta = (ExpandEnumAsExecs = "Result"))
static UEasyXMLElement* LoadFromFile(const FString& FilePath, bool IsAblolute, EEasyXMLParserErrorCode& Result, FString& ErrorMessage);
/**
* load xml string
* @param XMLString - xml file path
* @return xml object
*/
UFUNCTION(BlueprintCallable, Category = "EasyXMLParser", meta = (ExpandEnumAsExecs = "Result"))
static UEasyXMLElement* LoadFromString(const FString& XMLString, EEasyXMLParserErrorCode& Result, FString& ErrorMessage);
};
@@ -0,0 +1,15 @@
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
class FEasyXMLParserModule : public IModuleInterface
{
public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
@@ -0,0 +1,19 @@
// Copyright 2019 ayumax. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
UENUM(BlueprintType)
enum class EEasyXMLParserErrorCode : uint8
{
Successed,
Failed
};
UENUM(BlueprintType)
enum class EEasyXMLParserFound : uint8
{
Found,
NotFound
};
@@ -0,0 +1,7 @@
{
"BuildId": "23058290",
"Modules":
{
"JPrinter": "UnrealEditor-JPrinter.dll"
}
}
+23
View File
@@ -0,0 +1,23 @@
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "JPrinter",
"Description": "Now you can print picture from unreal direcly!, you print from file or even print a texture, only for windows, soon mac ox",
"Category": "Hardware",
"CreatedBy": "ZKarmaKun",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"SupportURL": "",
"EngineVersion": "5.1.0",
"CanContainContent": false,
"Installed": true,
"Modules": [
{
"Name": "JPrinter",
"Type": "Runtime",
"LoadingPhase": "Default"
}
]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

@@ -0,0 +1,69 @@
// Some copyright should be here...
using UnrealBuildTool;
using System.IO;
public class JPrinter : ModuleRules
{
public JPrinter(ReadOnlyTargetRules Target): base( Target )
{
PublicIncludePaths.AddRange(
new string[] {
"JPrinter/Public"
// ... add public include paths required here ...
}
);
PrivateIncludePaths.AddRange(
new string[] {
"JPrinter/Private",
// ... add other private include paths required here ...
}
);
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
// ... add other public dependencies that you statically link with here ...
}
);
PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
"ImageWrapper",
// ... add private dependencies that you statically link with here ...
}
);
DynamicallyLoadedModuleNames.AddRange(
new string[]
{
// ... add any modules that your module loads dynamically here ...
}
);
//string ModulePath = Path.GetDirectoryName(RulesCompiler.GetModuleFilename(this.GetType().Name));
/*
string ThirdParty = Path.GetFullPath(Path.Combine(ModuleDirectory, "../../ThirdParty/"));
string IncludePaths = Path.Combine(ThirdParty, "opencv", "include");
string LibPath = Path.Combine(ThirdParty, "opencv", "lib");
PublicIncludePaths.Add(IncludePaths);
PublicAdditionalLibraries.Add(LibPath + "/opencv_world300.lib");
PublicAdditionalLibraries.Add(LibPath + "/opencv_ts300.lib");*/
}
}
@@ -0,0 +1,22 @@
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#include "JPrinter.h"
#include "JPrinterPrivatePCH.h"
#define LOCTEXT_NAMESPACE "FJPrinterModule"
void FJPrinterModule::StartupModule()
{
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
}
void FJPrinterModule::ShutdownModule()
{
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
// we call this function before unloading the module.
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FJPrinterModule, JPrinter)
@@ -0,0 +1,266 @@
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#include "JPrinterBPLibrary.h"
#include "JPrinterPrivatePCH.h"
#define print(txt) GEngine->AddOnScreenDebugMessage(-1,10,FColor::Green, txt)
DEFINE_LOG_CATEGORY_STATIC(JPrinterLog, Log, All);
UJPrinterBPLibrary::UJPrinterBPLibrary(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
TArray<FString> UJPrinterBPLibrary::getPrinterList()
{
TArray<FString> out;
#if PLATFORM_WINDOWS
LPBYTE pPrinterEnum;
unsigned long pcbNeeded, pcbReturned;
PRINTER_INFO_2* printerInfo = NULL;
EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &pcbNeeded, &pcbReturned);
pPrinterEnum = new BYTE[pcbNeeded];
if (EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, pPrinterEnum, pcbNeeded, &pcbNeeded, &pcbReturned))
{
printerInfo = ((PRINTER_INFO_2*)pPrinterEnum);
for (unsigned short i = 0; i < pcbReturned; i++)
{
TCHAR* wname = printerInfo[i].pPrinterName;
FString name = wname;
out.Add(name);
}
}
#endif
return out;
}
FString UJPrinterBPLibrary::getPrimaryPrinterName()
{
FString out;
#if PLATFORM_WINDOWS
unsigned long size = 0;
GetDefaultPrinter(NULL, &size);
if (size)
{
TCHAR* buffer = new TCHAR[size];
GetDefaultPrinter(buffer, &size);
out = buffer;
}
#endif
return out;
}
#if PLATFORM_WINDOWS
printerInfo UJPrinterBPLibrary::getPrinterInfo(FString printer, bool usePrimary)
{
printerInfo out;
unsigned long size = 0;
LPWSTR defaultName = NULL;
GetDefaultPrinter(NULL, &size);
if (size)
{
TCHAR* buffer = new TCHAR[size];
GetDefaultPrinter(buffer, &size);
defaultName = buffer;
}
if (defaultName)
{
out.deviceName = defaultName;
LPBYTE pPrinterEnum;
unsigned long pcbNeeded, pcbReturned;
PRINTER_INFO_2* printerInfo = NULL;
EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &pcbNeeded, &pcbReturned);
pPrinterEnum = new BYTE[pcbNeeded];
if (EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, pPrinterEnum, pcbNeeded, &pcbNeeded, &pcbReturned))
{
printerInfo = ((PRINTER_INFO_2*)pPrinterEnum);
std::wstring wsdefaultName(defaultName);
std::string sdefaultName(wsdefaultName.begin(), wsdefaultName.end());
for (unsigned int i = 0; i < pcbReturned; i++)
{
LPWSTR name = printerInfo[i].pPrinterName;
std::wstring wsname(name);
std::string sname(wsname.begin(), wsname.end());
if (usePrimary)
{
if (sname == sdefaultName)
{
out.driver = printerInfo[i].pDriverName;
out.portName = printerInfo[i].pPortName;
}
}
else
{
std::string choosen(TCHAR_TO_ANSI(*printer));
if (sname == choosen)
{
out.driver = printerInfo[i].pDriverName;
out.portName = printerInfo[i].pPortName;
}
}
}
}
}
return out;
}
HBITMAP UJPrinterBPLibrary::getHBITMAPFromData(TArray<FColor>& bgraData, int32 width, int32 height, int32 bitDepth)
{
if (bgraData.Num() <= 0) return NULL;
uint8* rgb = new uint8[width * height * 3];
for (int i = 0; i < (width * height); i++)
{
rgb[3 * i + 0] = bgraData[i].B;
rgb[3 * i + 1] = bgraData[i].G;
rgb[3 * i + 2] = bgraData[i].R;
}
// Create DIB
HBITMAP hbmp = CreateBitmap(width, height, 1, 24, rgb);
if (hbmp == NULL) {
delete rgb;
return hbmp;
}
delete rgb;
return hbmp;
}
#endif
FString UJPrinterBPLibrary::Replace(FString source, FString in, FString out)
{
TArray<TCHAR> ar = source.GetCharArray();
FString result;
for (int i = 0; i < ar.Num(); i++)
{
if (ar[i] != in[0])
{
result += ar[i];
}
else
{
result += out;
}
}
return result;
}
bool UJPrinterBPLibrary::printImage(FString path, FString printer, bool usePrimary)
{
if (!FPaths::FileExists(path)) {
UE_LOG(JPrinterLog, Log, TEXT("%s"), *path)
return false;
}
if (usePrimary)
{
printer = getPrimaryPrinterName();
}
path = "\"" + path + "\"";
path = Replace(path, "/", "\\");
FString args = " c:\\WINDOWS\\system32\\shimgvw.dll,ImageView_PrintTo /pt " + path + " \"" + printer + "\"";
FString prg = "rundll32";
UE_LOG(JPrinterLog, Log, TEXT("%s%s"), *prg,*args);
int error=33; //= WinExec(TCHAR_TO_ANSI(*fullPath), SW_SHOW);
FPlatformProcess::CreateProc(
*prg,
*args,
false,//* @param bLaunchDetached if true, the new process will have its own window
false,//* @param bLaunchHidded if true, the new process will be minimized in the task bar
false,//* @param bLaunchReallyHidden if true, the new process will not have a window or be in the task bar
0,
0,
nullptr,//const TCHAR* OptionalWorkingDirectory,
nullptr
);
return (error == 33) ? true : false;
}
bool UJPrinterBPLibrary::printTexture2D(UTexture2D* texture, FString printer, bool usePrimary, EPaperSize paperSize)
{
if (!texture) return false;
//const double DPIConvertion = 142.0643729189789;
//const float DPIConvertion = 142.0643729189789f;
const float DPIConvertion = 142.06437f;
bool out = false;
int32 width = texture->GetSizeX();
int32 height = texture->GetSizeY();
int32 bitDepth = 24;
TArray<FColor> colorData;
colorData.Init(FColor(), width * height);
FTexture2DMipMap& Mip = texture->PlatformData->Mips[0];
uint8* Data = (uint8*)Mip.BulkData.Lock(LOCK_READ_WRITE);
for (int i = 0; i < colorData.Num(); i++)
{
colorData[i].R = Data[4 * i + 2];
colorData[i].G = Data[4 * i + 1];
colorData[i].B = Data[4 * i + 0];
colorData[i].A = 255;
}
Mip.BulkData.Unlock();
texture->UpdateResource();
if (paperSize != EPaperSize::None)
{
float scale = 1;
switch (paperSize)
{
case EPaperSize::letter:
if (width == 2969) break;
scale = FMath::FloorToFloat((2969.f / width) * 100) / 100.f;
break;
case EPaperSize::photo:
if (width == 1373) break;
scale = FMath::FloorToFloat((1373.f / width) * 1000) / 1000.f;
break;
default:
break;
}
if (scale != 1)
{
TArray<FColor> fixColorData;
FImageUtils::ImageResize(width, height, colorData, width * scale, height * scale, fixColorData, true);
width = width * scale;
height = height * scale;
colorData = fixColorData;
}
}
#if PLATFORM_WINDOWS
HWND currentWindow = GetActiveWindow();
printerInfo dev = getPrinterInfo(printer, usePrimary);
HBITMAP hBMP = getHBITMAPFromData(colorData, width, height, bitDepth);
//HBITMAP hBMP = (HBITMAP)LoadImage(NULL, L"D:/gokuHQ.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
HDC printerHDC = CreateDC(dev.driver, dev.deviceName, dev.portName, NULL);
if (printerHDC)
{
HDC hdc = CreateCompatibleDC(printerHDC);
SelectObject(hdc, hBMP);
Escape(printerHDC, STARTDOC, 8, "Happy-Doc", NULL);
BitBlt(printerHDC, 0, 0, width, height, hdc, 0, 0, SRCCOPY2);
Escape(printerHDC, NEWFRAME, 0, NULL, NULL);
Escape(printerHDC, ENDDOC, 0, NULL, NULL);
UE_LOG(JPrinterLog,Log, TEXT("Printing... wPX=%i hPX=%i"), width, height);
DeleteDC(printerHDC);
out = true;
}
#endif
return out;
}
@@ -0,0 +1,6 @@
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#include "JPrinter.h"
// You should place include statements to your module's private header files here. You only need to
// add includes for headers that are used in most of your module's source files though.
@@ -0,0 +1,14 @@
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Modules/ModuleManager.h"
class FJPrinterModule : public IModuleInterface
{
public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
@@ -0,0 +1,69 @@
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#pragma once
#if PLATFORM_WINDOWS
#include "Windows/AllowWindowsPlatformTypes.h"
#include "Windows.h"
#include "winspool.h"
#include "iostream"
#include "time.h"
#include "fstream"
#include "string"
#include "Windows/HideWindowsPlatformTypes.h"
#endif
#include "Engine.h"
#include "ImageUtils.h"
//opencv
//#include "opencv/cv.hpp"
#include "JPrinterBPLibrary.generated.h"
//using namespace cv;
#if PLATFORM_WINDOWS
struct printerInfo
{
LPCWSTR portName;
LPCWSTR driver;
LPCWSTR deviceName;
LPCWSTR output = NULL;
};
#define SRCCOPY2 (unsigned long)0x00CC0020
#endif
UENUM(BlueprintType)
enum class EPaperSize : uint8
{
None UMETA(DisplayName = "None"),
letter UMETA(DisplayName = "Letter 8 1/2 x 11 in"),
photo UMETA(DisplayName = "Photo 4 x 6 in"),
};
UCLASS()
class UJPrinterBPLibrary : public UBlueprintFunctionLibrary
{
GENERATED_UCLASS_BODY()
public:
UFUNCTION(BlueprintPure, Category = JPrinter)
static TArray<FString> getPrinterList();
UFUNCTION(BlueprintPure, Category = JPrinter)
static FString getPrimaryPrinterName();
UFUNCTION(BlueprintCallable, Category = JPrinter)
static bool printImage(FString path, FString printer, bool usePrimary = true);
UFUNCTION(BlueprintCallable, Category = JPrinter)
static bool printTexture2D(UTexture2D* texture, FString printer, bool usePrimary, EPaperSize paperSize = EPaperSize::None);
static FString Replace(FString source, FString in, FString out);
#if PLATFORM_WINDOWS
static printerInfo getPrinterInfo(FString printer, bool usePrimary);
static HBITMAP getHBITMAPFromData(TArray<FColor>& bgraData, int32 width, int32 height, int32 bitDepth);
#endif
};
@@ -0,0 +1,7 @@
{
"BuildId": "23058290",
"Modules":
{
"createProcess": "UnrealEditor-createProcess.dll"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

@@ -0,0 +1,22 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "createProcess.h"
#define LOCTEXT_NAMESPACE "FcreateProcessModule"
void FcreateProcessModule::StartupModule()
{
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
}
void FcreateProcessModule::ShutdownModule()
{
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
// we call this function before unloading the module.
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FcreateProcessModule, createProcess)
@@ -0,0 +1,46 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "createProcessBPLibrary.h"
#include "createProcess.h"
UcreateProcessBPLibrary::UcreateProcessBPLibrary(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
void UcreateProcessBPLibrary::createProc(FString FullPathOfProgramToRun, TArray<FString> CommandlineArgs, bool Detach, bool Hidden, int32 Priority, FString OptionalWorkingDirectory)
{ //Please note ProcessId should really be uint32 but that is not supported by BP yet
FString Args = "";
if (CommandlineArgs.Num() > 1)
{
Args = CommandlineArgs[0];
for (int32 v = 1; v < CommandlineArgs.Num(); v++)
{
Args += " " + CommandlineArgs[v];
}
}
else if (CommandlineArgs.Num() > 0)
{
Args = CommandlineArgs[0];
}
//uint32 NeedBPUINT32 = 0;
FPlatformProcess::CreateProc(
*FullPathOfProgramToRun,
*Args,
Detach,//* @param bLaunchDetached if true, the new process will have its own window
false,//* @param bLaunchHidded if true, the new process will be minimized in the task bar
Hidden,//* @param bLaunchReallyHidden if true, the new process will not have a window or be in the task bar
0,
Priority,
(OptionalWorkingDirectory != "") ? *OptionalWorkingDirectory : nullptr,//const TCHAR* OptionalWorkingDirectory,
nullptr
);
}
void UcreateProcessBPLibrary::RunSystemCommand(FString Command)
{
system(TCHAR_TO_ANSI(*Command));
}
@@ -0,0 +1,14 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Modules/ModuleManager.h"
class FcreateProcessModule : public IModuleInterface
{
public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
@@ -0,0 +1,36 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Kismet/BlueprintFunctionLibrary.h"
#include "GenericPlatform/GenericPlatformProcess.h"
#include "createProcessBPLibrary.generated.h"
/*
* Function library class.
* Each function in it is expected to be static and represents blueprint node that can be called in any blueprint.
*
* When declaring function you can define metadata for the node. Key function specifiers will be BlueprintPure and BlueprintCallable.
* BlueprintPure - means the function does not affect the owning object in any way and thus creates a node without Exec pins.
* BlueprintCallable - makes a function which can be executed in Blueprints - Thus it has Exec pins.
* DisplayName - full name of the node, shown when you mouse over the node and in the blueprint drop down menu.
* Its lets you name the node using characters not allowed in C++ function names.
* CompactNodeTitle - the word(s) that appear on the node.
* Keywords - the list of keywords that helps you to find node when you search for it using Blueprint drop-down menu.
* Good example is "Print String" node which you can find also by using keyword "log".
* Category - the category your node will be under in the Blueprint drop-down menu.
*
* For more info on custom blueprint nodes visit documentation:
* https://wiki.unrealengine.com/Custom_Blueprint_Node_Creation
*/
UCLASS()
class UcreateProcessBPLibrary : public UBlueprintFunctionLibrary
{
GENERATED_UCLASS_BODY()
UFUNCTION(BlueprintCallable, Category = "createProcess")
static void createProc(FString FullPathOfProgramToRun, TArray<FString> CommandlineArgs, bool Detach, bool Hidden, int32 Priority, FString OptionalWorkingDirectory);
UFUNCTION(BlueprintCallable, Category = "createProcess")
static void RunSystemCommand(FString Command);
};
@@ -0,0 +1,53 @@
// Some copyright should be here...
using UnrealBuildTool;
public class createProcess : ModuleRules
{
public createProcess(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PublicIncludePaths.AddRange(
new string[] {
// ... add public include paths required here ...
}
);
PrivateIncludePaths.AddRange(
new string[] {
// ... add other private include paths required here ...
}
);
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
// ... add other public dependencies that you statically link with here ...
}
);
PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
// ... add private dependencies that you statically link with here ...
}
);
DynamicallyLoadedModuleNames.AddRange(
new string[]
{
// ... add any modules that your module loads dynamically here ...
}
);
}
}
@@ -0,0 +1,26 @@
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "createProcess",
"Description": "",
"Category": "Process",
"CreatedBy": "Dron",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"SupportURL": "",
"EngineVersion": "5.1.0",
"CanContainContent": false,
"Installed": true,
"Modules": [
{
"Name": "createProcess",
"Type": "Runtime",
"LoadingPhase": "PostEngineInit",
"WhitelistPlatforms": [
"Win64"
]
}
]
}
@@ -0,0 +1,7 @@
{
"BuildId": "23058290",
"Modules":
{
"manageTextFile": "UnrealEditor-manageTextFile.dll"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

@@ -0,0 +1,22 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "manageTextFile.h"
#define LOCTEXT_NAMESPACE "FmanageTextFileModule"
void FmanageTextFileModule::StartupModule()
{
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
}
void FmanageTextFileModule::ShutdownModule()
{
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
// we call this function before unloading the module.
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FmanageTextFileModule, manageTextFile)
@@ -0,0 +1,75 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "manageTextFileBPLibrary.h"
#include "manageTextFile.h"
UmanageTextFileBPLibrary::UmanageTextFileBPLibrary(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
bool UmanageTextFileBPLibrary::CreateTextFile(FString Path, FString FileName, FString Text)
{
if (Path == "" || FileName == "") {
UE_LOG(LogTemp, Warning, TEXT("Empty Path or FileName, aborting"));
return false;
}
Path.ReplaceInline(TEXT("/"), TEXT("\\"));
FString fullpath(Path + "\\" + FileName);
return FFileHelper::SaveStringToFile(Text, *fullpath, FFileHelper::EEncodingOptions::ForceUTF8);
}
bool UmanageTextFileBPLibrary::AppendStringToFile(FString Path, FString FileName, FString Text)
{
if (Path == "" || FileName == "") {
UE_LOG(LogTemp, Warning, TEXT("Empty Path or FileName, aborting"));
return false;
}
Path.ReplaceInline(TEXT("/"), TEXT("\\"));
FString fullpath(Path + "\\" + FileName);
FString OldText;
if (FPaths::FileExists(fullpath))
{
FFileHelper::LoadFileToString(OldText, *fullpath);
OldText += Text;
return FFileHelper::SaveStringToFile(Text, *fullpath, FFileHelper::EEncodingOptions::ForceUTF8, &IFileManager::Get(), FILEWRITE_Append);
}
else
{
return CreateTextFile(Path, FileName, Text);
}
}
bool UmanageTextFileBPLibrary::FileExists(FString Path, FString FileName)
{
if (Path == "" || FileName == "") {
UE_LOG(LogTemp, Warning, TEXT("Empty Path or FileName, aborting"));
return false;
}
Path.ReplaceInline(TEXT("/"), TEXT("\\"));
return FPaths::FileExists(Path + "\\" + FileName);
}
bool UmanageTextFileBPLibrary::DeleteFile(FString Path, FString FileName)
{
if (Path == "" || FileName == "") {
UE_LOG(LogTemp, Warning, TEXT("Empty Path or FileName, aborting"));
return false;
}
Path.ReplaceInline(TEXT("/"), TEXT("\\"));
FString fullpath = Path + "\\" + FileName;
return FPlatformFileManager::Get().GetPlatformFile().DeleteFile(*fullpath);
}
bool UmanageTextFileBPLibrary::readFile(FString Path, FString FileName,FString &Str) {
if (Path == "" || FileName == "") {
UE_LOG(LogTemp, Warning, TEXT("Empty Path or FileName, aborting"));
return false;
}
FString fullpath = Path + "\\" + FileName;
return FFileHelper::LoadFileToString(Str, *fullpath);
}
@@ -0,0 +1,14 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Modules/ModuleManager.h"
class FmanageTextFileModule : public IModuleInterface
{
public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
@@ -0,0 +1,43 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
#include "HAL/PlatformFilemanager.h"
#include "manageTextFileBPLibrary.generated.h"
/*
* Function library class.
* Each function in it is expected to be static and represents blueprint node that can be called in any blueprint.
*
* When declaring function you can define metadata for the node. Key function specifiers will be BlueprintPure and BlueprintCallable.
* BlueprintPure - means the function does not affect the owning object in any way and thus creates a node without Exec pins.
* BlueprintCallable - makes a function which can be executed in Blueprints - Thus it has Exec pins.
* DisplayName - full name of the node, shown when you mouse over the node and in the blueprint drop down menu.
* Its lets you name the node using characters not allowed in C++ function names.
* CompactNodeTitle - the word(s) that appear on the node.
* Keywords - the list of keywords that helps you to find node when you search for it using Blueprint drop-down menu.
* Good example is "Print String" node which you can find also by using keyword "log".
* Category - the category your node will be under in the Blueprint drop-down menu.
*
* For more info on custom blueprint nodes visit documentation:
* https://wiki.unrealengine.com/Custom_Blueprint_Node_Creation
*/
UCLASS()
class UmanageTextFileBPLibrary : public UBlueprintFunctionLibrary
{
GENERATED_UCLASS_BODY()
UFUNCTION(BlueprintCallable, Category = "manageTextFile")
static bool CreateTextFile(FString Path, FString FileName, FString Text);
UFUNCTION(BlueprintCallable, Category = "manageTextFile")
static bool AppendStringToFile(FString Path, FString FileName, FString Text);
UFUNCTION(BlueprintCallable, Category = "manageTextFile")
static bool FileExists(FString Path, FString FileName);
UFUNCTION(BlueprintCallable, Category = "manageTextFile")
static bool DeleteFile(FString Path, FString FileName);
UFUNCTION(BlueprintCallable, Category = "manageTextFile")
static bool readFile(FString Path, FString FileName, FString & Str);
};
@@ -0,0 +1,53 @@
// Some copyright should be here...
using UnrealBuildTool;
public class manageTextFile : ModuleRules
{
public manageTextFile(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PublicIncludePaths.AddRange(
new string[] {
// ... add public include paths required here ...
}
);
PrivateIncludePaths.AddRange(
new string[] {
// ... add other private include paths required here ...
}
);
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
// ... add other public dependencies that you statically link with here ...
}
);
PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
// ... add private dependencies that you statically link with here ...
}
);
DynamicallyLoadedModuleNames.AddRange(
new string[]
{
// ... add any modules that your module loads dynamically here ...
}
);
}
}
@@ -0,0 +1,25 @@
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "manageTextFile",
"Description": "",
"Category": "fileIO",
"CreatedBy": "Dron",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"SupportURL": "",
"CanContainContent": false,
"Installed": true,
"Modules": [
{
"Name": "manageTextFile",
"Type": "Runtime",
"LoadingPhase": "PostEngineInit",
"WhitelistPlatforms": [
"Win64"
]
}
]
}