Adds plugins
This commit is contained in:
30
Plugins/FileSDK/FileSDK.uplugin
Normal file
30
Plugins/FileSDK/FileSDK.uplugin
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 16,
|
||||
"VersionName": "1.16",
|
||||
"FriendlyName": "Blueprint FileSDK",
|
||||
"Description": "A simple plugin to interact with files and folders within blueprints.",
|
||||
"Category": "Code Plugins",
|
||||
"CreatedBy": "Incanta Games",
|
||||
"CreatedByURL": "https://incanta.games",
|
||||
"DocsURL": "https://wiki.incanta.games/plugins/filesdk",
|
||||
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/4f737815666c4e7dabf2043fb55a8419",
|
||||
"SupportURL": "https://discord.gg/cDcP3rBBUc",
|
||||
"EngineVersion": "4.27.0",
|
||||
"CanContainContent": false,
|
||||
"Installed": true,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "FileSDK",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "PreLoadingScreen",
|
||||
"WhitelistPlatforms": [
|
||||
"Win64",
|
||||
"Win32",
|
||||
"Mac",
|
||||
"Linux",
|
||||
"LinuxAArch64"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
21
Plugins/FileSDK/LICENSE
Normal file
21
Plugins/FileSDK/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Incanta Games
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
37
Plugins/FileSDK/README.md
Normal file
37
Plugins/FileSDK/README.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Unreal Blueprint FileSDK
|
||||
|
||||
This is an Unreal Engine plugin to give you blueprint nodes for various File IO/Management tasks.
|
||||
|
||||
Some, but not all, of the things this plugin lets you do:
|
||||
- Read/write files as text or binary
|
||||
- Random access file reading (read a specific part of the file and not all of it)
|
||||
- Read directory contents with detailed file info
|
||||
- Search directories for files/directories
|
||||
- Rename files/directories
|
||||
- Copy files/directories
|
||||
|
||||
## Documentation
|
||||
|
||||
Find a full, detailed list of all the different blueprint nodes this plugin provides at https://wiki.incanta.games/plugins/filesdk
|
||||
|
||||
## Marketplace
|
||||
|
||||
This asset is available **FOR FREE** on the Unreal Engine Marketplace at https://www.unrealengine.com/marketplace/en-US/product/blueprint-file-sdk.
|
||||
|
||||
Any and all enhancements will be made to this plugin and will continue to be free; there won't be a "paid pro version." We don't believe in the whole bait-and-switch ploy. We hope you enjoy it!
|
||||
|
||||
## Follow Us!
|
||||
|
||||
Checkout the below links if you want to make sure you get the latest and greatest news from Incanta Games:
|
||||
- Twitter: https://twitter.com/IncantaGames
|
||||
- Discord: https://discord.gg/cDcP3rBBUc
|
||||
|
||||
## Support
|
||||
|
||||
We have a Discord server where you can get expedited support for both issues and feature requests: https://discord.gg/cDcP3rBBUc
|
||||
|
||||
You can also make an issue on this GitHub repository: https://github.com/IncantaGames/unreal-bp-file-sdk/issues
|
||||
|
||||
## Donations
|
||||
|
||||
Here at Incanta Games, we strongly believe that content should be available for indie developers at a reasonable price. Lots of other vendors price gouge to take advantage of devs who don't have the chops to do some coding. We continue to strive to help you bring magic to the world in your games by making sure plugins are reasonably cheap or free. We'll keep doing this, but if you want to help support this mission you can give us a tip at https://ko-fi.com/incanta. Any and all donations are much appreciated and help us continue to make more awesome content for you!
|
||||
46
Plugins/FileSDK/Source/FileSDK/FileSDK.Build.cs
Normal file
46
Plugins/FileSDK/Source/FileSDK/FileSDK.Build.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright Incanta Games 2020. All Rights Reserved.
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class FileSDK : ModuleRules {
|
||||
public FileSDK(ReadOnlyTargetRules Target) : base(Target) {
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
20
Plugins/FileSDK/Source/FileSDK/Private/FileSDK.cpp
Normal file
20
Plugins/FileSDK/Source/FileSDK/Private/FileSDK.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright Incanta Games 2020. All Rights Reserved.
|
||||
|
||||
#include "FileSDK.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FFileSDKModule"
|
||||
|
||||
DEFINE_LOG_CATEGORY(LogFileSDK);
|
||||
|
||||
void FFileSDKModule::StartupModule() {
|
||||
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
|
||||
}
|
||||
|
||||
void FFileSDKModule::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(FFileSDKModule, FileSDK)
|
||||
613
Plugins/FileSDK/Source/FileSDK/Private/FileSDKBPLibrary.cpp
Normal file
613
Plugins/FileSDK/Source/FileSDK/Private/FileSDKBPLibrary.cpp
Normal file
@@ -0,0 +1,613 @@
|
||||
// Copyright Incanta Games 2020. All Rights Reserved.
|
||||
|
||||
#include "FileSDKBPLibrary.h"
|
||||
|
||||
UFileSDKBPLibrary::UFileSDKBPLibrary(
|
||||
const FObjectInitializer& ObjectInitializer
|
||||
) : Super(ObjectInitializer) {
|
||||
//
|
||||
}
|
||||
|
||||
UFileSDKFileReader * UFileSDKBPLibrary::OpenFileReader(
|
||||
FString FileName,
|
||||
bool OpenInBinaryMode
|
||||
) {
|
||||
UFileSDKFileReader * fileReader = NewObject<UFileSDKFileReader>();
|
||||
fileReader->OpenFile(FileName, OpenInBinaryMode);
|
||||
return fileReader;
|
||||
}
|
||||
|
||||
void UFileSDKBPLibrary::CreateFile(
|
||||
FString FileName,
|
||||
bool ClearContentsIfExists,
|
||||
bool CreateDirectoryTree
|
||||
) {
|
||||
IPlatformFile & PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
|
||||
|
||||
FString directoryName = FPaths::GetPath(FileName);
|
||||
bool directoryExists = PlatformFile.DirectoryExists(*directoryName);
|
||||
|
||||
if (!directoryExists && CreateDirectoryTree) {
|
||||
FFileManagerGeneric::Get().MakeDirectory(*directoryName, true);
|
||||
} else if (!directoryExists) {
|
||||
UE_LOG(
|
||||
LogFileSDK,
|
||||
Fatal,
|
||||
TEXT("Cannot create file %s because directory %s doesn't exist. Ensure the directory exists before or enable 'CreateDirectoryTree'"),
|
||||
*FileName,
|
||||
*directoryName
|
||||
);
|
||||
}
|
||||
|
||||
bool fileExists = PlatformFile.FileExists(*FileName);
|
||||
|
||||
if ((ClearContentsIfExists && fileExists) || !fileExists) {
|
||||
FFileHelper::SaveStringToFile(FString(), *FileName);
|
||||
}
|
||||
}
|
||||
|
||||
bool UFileSDKBPLibrary::DeleteFile(FString FileName) {
|
||||
IPlatformFile & PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
|
||||
|
||||
if (PlatformFile.FileExists(*FileName)) {
|
||||
return FFileManagerGeneric::Get().Delete(*FileName);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool UFileSDKBPLibrary::CreateDirectory(
|
||||
FString DirectoryName,
|
||||
bool CreateDirectoryTree
|
||||
) {
|
||||
return FFileManagerGeneric::Get().MakeDirectory(*DirectoryName, CreateDirectoryTree);
|
||||
}
|
||||
|
||||
bool UFileSDKBPLibrary::DeleteDirectory(
|
||||
FString DirectoryName,
|
||||
bool Recursive
|
||||
) {
|
||||
return FFileManagerGeneric::Get().DeleteDirectory(*DirectoryName, false, Recursive);
|
||||
}
|
||||
|
||||
bool UFileSDKBPLibrary::RenameFileOrDirectory(
|
||||
FString Source,
|
||||
FString Destination
|
||||
) {
|
||||
IPlatformFile & PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
|
||||
|
||||
return PlatformFile.MoveFile(*Destination, *Source);
|
||||
}
|
||||
|
||||
bool UFileSDKBPLibrary::CopyFile(
|
||||
FString Source,
|
||||
FString Destination,
|
||||
const FFileSDKCopyDelegate & ProgressCallback,
|
||||
FFileSDKDelegatePreInfo PreInfo,
|
||||
int ChunkSizeInKilobytes,
|
||||
bool OverwriteDestination
|
||||
) {
|
||||
IPlatformFile & PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
|
||||
|
||||
const int64 MaxBufferSize = ChunkSizeInKilobytes * 1024;
|
||||
|
||||
// Note, the below code is mostly copied from the
|
||||
// engine's GenericPlatformFile.cpp source file
|
||||
|
||||
if (PlatformFile.FileExists(*Destination) && !OverwriteDestination) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TUniquePtr<IFileHandle> FromFile(PlatformFile.OpenRead(*Source, false));
|
||||
if (!FromFile) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TUniquePtr<IFileHandle> ToFile(PlatformFile.OpenWrite(*Destination, false, false));
|
||||
if (!ToFile) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int64 Size = FromFile->Size();
|
||||
int totalSizeKb = FMath::DivideAndRoundUp(Size, int64(1000));
|
||||
if (Size < 1) {
|
||||
check(Size == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
int64 AllocSize = FMath::Min<int64>(MaxBufferSize, Size);
|
||||
check(AllocSize);
|
||||
|
||||
uint8* Buffer = (uint8*)FMemory::Malloc(int32(AllocSize));
|
||||
check(Buffer);
|
||||
|
||||
while (Size) {
|
||||
int64 ThisSize = FMath::Min<int64>(AllocSize, Size);
|
||||
FromFile->Read(Buffer, ThisSize);
|
||||
ToFile->Write(Buffer, ThisSize);
|
||||
Size -= ThisSize;
|
||||
ProgressCallback.ExecuteIfBound(
|
||||
PreInfo.PriorWritten + totalSizeKb - FMath::DivideAndRoundUp(Size, int64(1000)),
|
||||
PreInfo.TotalSize > 0 ? PreInfo.TotalSize : totalSizeKb
|
||||
);
|
||||
check(Size >= 0);
|
||||
}
|
||||
|
||||
FMemory::Free(Buffer);
|
||||
|
||||
#if PLATFORM_MAC || PLATFORM_IOS
|
||||
// Copied from ApplePlatformFile.cpp which has this extra implementation
|
||||
// copied the contents of ApplePlatformFile::Stat since it's a private method
|
||||
// hacky, but it does the job. the original code hasn't changed in 7 years.
|
||||
// also using FPaths::NormalizeFilename since it's the exact same as
|
||||
// ApplePlatformFile::NormalizeFilename (which is protected)
|
||||
|
||||
struct stat FileInfo;
|
||||
FString normalizedSource(Source);
|
||||
FString normalizedDestination(Destination);
|
||||
|
||||
FPaths::NormalizeFilename(normalizedSource);
|
||||
FPaths::NormalizeFilename(normalizedDestination);
|
||||
|
||||
if (stat(TCHAR_TO_UTF8(*normalizedSource), &FileInfo) == 0) {
|
||||
FileInfo.st_mode |= S_IWUSR;
|
||||
|
||||
chmod(TCHAR_TO_UTF8(*normalizedDestination), FileInfo.st_mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UFileSDKBPLibrary::CopyFileAsync(
|
||||
FString Source,
|
||||
FString Destination,
|
||||
const FFileSDKCopyDelegate & ProgressCallback,
|
||||
FFileSDKDelegatePreInfo PreInfo,
|
||||
int ChunkSizeInKilobytes
|
||||
) {
|
||||
FFunctionGraphTask::CreateAndDispatchWhenReady(
|
||||
[=] {
|
||||
UFileSDKBPLibrary::CopyFile(
|
||||
Source,
|
||||
Destination,
|
||||
ProgressCallback,
|
||||
PreInfo,
|
||||
ChunkSizeInKilobytes
|
||||
);
|
||||
},
|
||||
TStatId(),
|
||||
nullptr,
|
||||
ENamedThreads::AnyThread
|
||||
);
|
||||
}
|
||||
|
||||
bool UFileSDKBPLibrary::CopyDirectory(
|
||||
FString Source,
|
||||
FString Destination,
|
||||
const FFileSDKCopyDelegate & ProgressCallback,
|
||||
bool OverwriteDestination,
|
||||
int ChunkSizeInKilobytes
|
||||
) {
|
||||
IPlatformFile & PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
|
||||
|
||||
// Note, the below code is mostly copied from the
|
||||
// engine's GenericPlatformFile.cpp source file
|
||||
|
||||
check(*Destination);
|
||||
check(*Source);
|
||||
|
||||
FString DestDir(Destination);
|
||||
FPaths::NormalizeDirectoryName(DestDir);
|
||||
|
||||
FString SourceDir(Source);
|
||||
FPaths::NormalizeDirectoryName(SourceDir);
|
||||
|
||||
// Does Source dir exist?
|
||||
if (!PlatformFile.DirectoryExists(*SourceDir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Destination directory exists already or can be created ?
|
||||
if (
|
||||
!PlatformFile.DirectoryExists(*DestDir) &&
|
||||
!PlatformFile.CreateDirectory(*DestDir)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get total size
|
||||
struct FStatFilesAndDirs : public IPlatformFile::FDirectoryStatVisitor {
|
||||
IPlatformFile & PlatformFile;
|
||||
int64 TotalFileSize;
|
||||
|
||||
FStatFilesAndDirs(IPlatformFile& InPlatformFile)
|
||||
: PlatformFile(InPlatformFile)
|
||||
, TotalFileSize(0) {
|
||||
}
|
||||
|
||||
virtual bool Visit(const TCHAR* FilenameOrDirectory, const FFileStatData& StatData) {
|
||||
if (!StatData.bIsDirectory) {
|
||||
TotalFileSize += StatData.FileSize;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// copy files and directories visitor
|
||||
FStatFilesAndDirs StatFilesAndDirs(PlatformFile);
|
||||
|
||||
// don't bother getting file size of dir
|
||||
// if the user doesn't want it
|
||||
if (ProgressCallback.IsBound()) {
|
||||
bool statResult = PlatformFile.IterateDirectoryStatRecursively(*SourceDir, StatFilesAndDirs);
|
||||
|
||||
if (!statResult) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy all files and directories
|
||||
struct FCopyFilesAndDirs : public IPlatformFile::FDirectoryVisitor {
|
||||
IPlatformFile & PlatformFile;
|
||||
const TCHAR* SourceRoot;
|
||||
const TCHAR* DestRoot;
|
||||
bool bOverwrite;
|
||||
int chunkSizeInKilobytes;
|
||||
FFileSDKCopyDelegate progressCallback;
|
||||
FFileSDKDelegatePreInfo preInfo;
|
||||
|
||||
FCopyFilesAndDirs(
|
||||
IPlatformFile& InPlatformFile,
|
||||
const TCHAR* InSourceRoot,
|
||||
const TCHAR* InDestRoot,
|
||||
bool bInOverwrite,
|
||||
int inChunkSizeInKilobytes,
|
||||
FFileSDKCopyDelegate inProgressCallback,
|
||||
int inTotalSizeKB
|
||||
) :
|
||||
PlatformFile(InPlatformFile),
|
||||
SourceRoot(InSourceRoot),
|
||||
DestRoot(InDestRoot),
|
||||
bOverwrite(bInOverwrite),
|
||||
chunkSizeInKilobytes(inChunkSizeInKilobytes),
|
||||
progressCallback(inProgressCallback) {
|
||||
preInfo.TotalSize = inTotalSizeKB;
|
||||
preInfo.PriorWritten = 0;
|
||||
}
|
||||
|
||||
virtual bool Visit(const TCHAR* FilenameOrDirectory, bool bIsDirectory) {
|
||||
FString NewName(FilenameOrDirectory);
|
||||
// change the root
|
||||
NewName = NewName.Replace(SourceRoot, DestRoot);
|
||||
|
||||
if (bIsDirectory) {
|
||||
// create new directory structure
|
||||
if (!PlatformFile.CreateDirectoryTree(*NewName) && !PlatformFile.DirectoryExists(*NewName)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Delete destination file if it exists and we are overwriting
|
||||
if (!PlatformFile.FileExists(*NewName) || bOverwrite) {
|
||||
// Copy file from source
|
||||
if (
|
||||
!UFileSDKBPLibrary::CopyFile(
|
||||
FilenameOrDirectory,
|
||||
NewName,
|
||||
progressCallback,
|
||||
preInfo,
|
||||
chunkSizeInKilobytes
|
||||
)
|
||||
) {
|
||||
// Not all files could be copied
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (progressCallback.IsBound()) {
|
||||
auto statData = PlatformFile.GetStatData(FilenameOrDirectory);
|
||||
preInfo.PriorWritten += FMath::DivideAndRoundUp(statData.FileSize, int64(1000));
|
||||
}
|
||||
}
|
||||
return true; // continue searching
|
||||
}
|
||||
};
|
||||
|
||||
// copy files and directories visitor
|
||||
FCopyFilesAndDirs CopyFilesAndDirs(
|
||||
PlatformFile,
|
||||
*SourceDir,
|
||||
*DestDir,
|
||||
OverwriteDestination,
|
||||
ChunkSizeInKilobytes,
|
||||
ProgressCallback,
|
||||
FMath::DivideAndRoundUp(StatFilesAndDirs.TotalFileSize, int64(1000))
|
||||
);
|
||||
|
||||
// create all files subdirectories and files in subdirectories!
|
||||
return PlatformFile.IterateDirectoryRecursively(*SourceDir, CopyFilesAndDirs);
|
||||
}
|
||||
|
||||
void UFileSDKBPLibrary::CopyDirectoryAsync(
|
||||
FString Source,
|
||||
FString Destination,
|
||||
const FFileSDKCopyDelegate & ProgressCallback,
|
||||
bool OverwriteDestination,
|
||||
int ChunkSizeInKilobytes
|
||||
) {
|
||||
FFunctionGraphTask::CreateAndDispatchWhenReady(
|
||||
[=] {
|
||||
UFileSDKBPLibrary::CopyDirectory(
|
||||
Source,
|
||||
Destination,
|
||||
ProgressCallback,
|
||||
OverwriteDestination,
|
||||
ChunkSizeInKilobytes
|
||||
);
|
||||
},
|
||||
TStatId(),
|
||||
nullptr,
|
||||
ENamedThreads::AnyThread
|
||||
);
|
||||
}
|
||||
|
||||
bool UFileSDKBPLibrary::ReadStringFromFile(FString FileName, FString & Content) {
|
||||
return FFileHelper::LoadFileToString(Content, *FileName);
|
||||
}
|
||||
|
||||
bool UFileSDKBPLibrary::ReadLinesFromFile(
|
||||
FString FileName,
|
||||
TSubclassOf<class UFileSDKLineReader> LineReader,
|
||||
TArray<FString> & Lines
|
||||
) {
|
||||
bool result = false;
|
||||
|
||||
if (LineReader.GetDefaultObject() != nullptr) {
|
||||
auto reader = NewObject<UFileSDKLineReader>(
|
||||
(UObject*) GetTransientPackage(),
|
||||
*LineReader
|
||||
);
|
||||
|
||||
result = FFileHelper::LoadFileToStringArrayWithPredicate(
|
||||
Lines,
|
||||
*FileName,
|
||||
[reader](const FString & line) { return reader->FilterLine(line); }
|
||||
);
|
||||
} else {
|
||||
result = FFileHelper::LoadFileToStringArrayWithPredicate(
|
||||
Lines,
|
||||
*FileName,
|
||||
[](const FString&) { return true; }
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool UFileSDKBPLibrary::WriteStringToFile(
|
||||
FString FileName,
|
||||
FString Content,
|
||||
bool Append,
|
||||
EFileSDKEncodingOptions Encoding
|
||||
) {
|
||||
FFileHelper::EEncodingOptions internalEncoding;
|
||||
switch (Encoding) {
|
||||
case EFileSDKEncodingOptions::AutoDetect: {
|
||||
internalEncoding = FFileHelper::EEncodingOptions::AutoDetect;
|
||||
break;
|
||||
}
|
||||
case EFileSDKEncodingOptions::ForceAnsi: {
|
||||
internalEncoding = FFileHelper::EEncodingOptions::ForceAnsi;
|
||||
break;
|
||||
}
|
||||
case EFileSDKEncodingOptions::ForceUnicode: {
|
||||
internalEncoding = FFileHelper::EEncodingOptions::ForceUnicode;
|
||||
break;
|
||||
}
|
||||
case EFileSDKEncodingOptions::ForceUTF8: {
|
||||
internalEncoding = FFileHelper::EEncodingOptions::ForceUTF8;
|
||||
break;
|
||||
}
|
||||
case EFileSDKEncodingOptions::ForceUTF8WithoutBOM: {
|
||||
internalEncoding = FFileHelper::EEncodingOptions::ForceUTF8WithoutBOM;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
internalEncoding = FFileHelper::EEncodingOptions::AutoDetect;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Append) {
|
||||
return FFileHelper::SaveStringToFile(
|
||||
Content,
|
||||
*FileName,
|
||||
internalEncoding,
|
||||
&IFileManager::Get(),
|
||||
std::ios_base::app
|
||||
);
|
||||
} else {
|
||||
return FFileHelper::SaveStringToFile(Content, *FileName, internalEncoding);
|
||||
}
|
||||
}
|
||||
|
||||
bool UFileSDKBPLibrary::WriteBytesToFile(FString FileName, TArray<uint8> Content) {
|
||||
return FFileHelper::SaveArrayToFile(Content, *FileName);
|
||||
}
|
||||
|
||||
bool UFileSDKBPLibrary::ReadBytesFromFile(FString FileName, TArray<uint8> & Content) {
|
||||
return FFileHelper::LoadFileToArray(Content, *FileName);
|
||||
}
|
||||
|
||||
TArray<FString> UFileSDKBPLibrary::GetFilesFromDirectory(
|
||||
FString DirectoryToSearch,
|
||||
FString FilterFilesWithExtension,
|
||||
bool SearchSubfolders,
|
||||
EFileSDKFileType FileType
|
||||
) {
|
||||
TArray<FString> FileNames;
|
||||
IFileManager & FileManager = IFileManager::Get();
|
||||
|
||||
if (SearchSubfolders) {
|
||||
if (FileType == EFileSDKFileType::File) {
|
||||
FileManager.FindFilesRecursive(
|
||||
FileNames,
|
||||
*DirectoryToSearch,
|
||||
*(TEXT("*") + FilterFilesWithExtension),
|
||||
true,
|
||||
false
|
||||
);
|
||||
} else {
|
||||
FileManager.FindFilesRecursive(
|
||||
FileNames,
|
||||
*DirectoryToSearch,
|
||||
TEXT("*"),
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
} else {
|
||||
TArray<FString> relativeFileNames;
|
||||
|
||||
if (FileType == EFileSDKFileType::File) {
|
||||
FileManager.FindFiles(
|
||||
relativeFileNames,
|
||||
*DirectoryToSearch,
|
||||
*FilterFilesWithExtension
|
||||
);
|
||||
} else {
|
||||
FileManager.FindFiles(
|
||||
relativeFileNames,
|
||||
*(DirectoryToSearch + FGenericPlatformMisc::GetDefaultPathSeparator() + TEXT("*")),
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
for (FString fileName : relativeFileNames) {
|
||||
FileNames.Add(
|
||||
DirectoryToSearch +
|
||||
FGenericPlatformMisc::GetDefaultPathSeparator() +
|
||||
fileName
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return FileNames;
|
||||
}
|
||||
|
||||
TArray<FFileSDKFileInfo> UFileSDKBPLibrary::GetDirectoryContentsWithFileInfo(
|
||||
FString Directory,
|
||||
bool SearchSubfolders
|
||||
) {
|
||||
TArray<FFileSDKFileInfo> contents;
|
||||
IFileManager & FileManager = IFileManager::Get();
|
||||
|
||||
TArray<FString> filePaths;
|
||||
if (SearchSubfolders) {
|
||||
FileManager.FindFilesRecursive(
|
||||
filePaths,
|
||||
*Directory,
|
||||
TEXT("*"),
|
||||
true,
|
||||
true
|
||||
);
|
||||
} else {
|
||||
TArray<FString> relativeFileNames;
|
||||
|
||||
FileManager.FindFiles(
|
||||
relativeFileNames,
|
||||
*(Directory + FGenericPlatformMisc::GetDefaultPathSeparator() + TEXT("*")),
|
||||
true,
|
||||
true
|
||||
);
|
||||
|
||||
for (FString fileName : relativeFileNames) {
|
||||
filePaths.Add(
|
||||
Directory +
|
||||
FGenericPlatformMisc::GetDefaultPathSeparator() +
|
||||
fileName
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (FString path : filePaths) {
|
||||
FFileSDKFileInfo info;
|
||||
info.AbsolutePath = path;
|
||||
info.Filename = FPaths::GetCleanFilename(path);
|
||||
UFileSDKBPLibrary::GetFileOrDirectoryInfo(path, info);
|
||||
contents.Add(info);
|
||||
}
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
||||
void UFileSDKBPLibrary::GetFileOrDirectoryInfo(FString Path, FFileSDKFileInfo & Info) {
|
||||
IPlatformFile & PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
|
||||
|
||||
FFileStatData data = PlatformFile.GetStatData(*Path);
|
||||
|
||||
Info.AbsolutePath = Path;
|
||||
Info.Filename = FPaths::GetCleanFilename(Path);
|
||||
Info.CreationTime = data.CreationTime;
|
||||
Info.AccessTime = data.AccessTime;
|
||||
Info.ModificationTime = data.ModificationTime;
|
||||
Info.FileSize = data.FileSize;
|
||||
Info.bIsDirectory = data.bIsDirectory;
|
||||
Info.bIsReadOnly = data.bIsReadOnly;
|
||||
Info.bIsValid = data.bIsValid;
|
||||
}
|
||||
|
||||
FString UFileSDKBPLibrary::GetCurrentUsername() {
|
||||
#if PLATFORM_WINDOWS
|
||||
return FWindowsPlatformMisc::GetEnvironmentVariable(ANSI_TO_TCHAR("USERNAME"));
|
||||
#elif PLATFORM_LINUX
|
||||
return FUnixPlatformMisc::GetEnvironmentVariable(ANSI_TO_TCHAR("USER"));
|
||||
#elif PLATFORM_MAC
|
||||
return FApplePlatformMisc::GetEnvironmentVariable(ANSI_TO_TCHAR("USER"));
|
||||
#else
|
||||
return "PLATFORM_NOT_SUPPORTED";
|
||||
#endif
|
||||
}
|
||||
|
||||
FString UFileSDKBPLibrary::GetCurrentUserHomeDirectory() {
|
||||
#if PLATFORM_WINDOWS
|
||||
return FWindowsPlatformMisc::GetEnvironmentVariable(ANSI_TO_TCHAR("HOMEDRIVE")) + FWindowsPlatformMisc::GetEnvironmentVariable(ANSI_TO_TCHAR("HOMEPATH"));
|
||||
#elif PLATFORM_LINUX
|
||||
return FUnixPlatformMisc::GetEnvironmentVariable(ANSI_TO_TCHAR("HOME"));
|
||||
#elif PLATFORM_MAC
|
||||
return FApplePlatformMisc::GetEnvironmentVariable(ANSI_TO_TCHAR("HOME"));
|
||||
#else
|
||||
return "PLATFORM_NOT_SUPPORTED";
|
||||
#endif
|
||||
}
|
||||
|
||||
FString UFileSDKBPLibrary::GetEnvironmentVariable(FString VariableName) {
|
||||
#if PLATFORM_WINDOWS
|
||||
return FWindowsPlatformMisc::GetEnvironmentVariable(*VariableName);
|
||||
#elif PLATFORM_LINUX
|
||||
return FUnixPlatformMisc::GetEnvironmentVariable(*VariableName);
|
||||
#elif PLATFORM_MAC
|
||||
return FApplePlatformMisc::GetEnvironmentVariable(*VariableName);
|
||||
#else
|
||||
return "PLATFORM_NOT_SUPPORTED";
|
||||
#endif
|
||||
}
|
||||
|
||||
std::ios_base::seekdir UFileSDKBPLibrary::FileAnchorToSeekDir(
|
||||
EFileSDKFileAnchor Anchor
|
||||
) {
|
||||
switch (Anchor) {
|
||||
case EFileSDKFileAnchor::Beginning: {
|
||||
return std::ios_base::beg;
|
||||
}
|
||||
case EFileSDKFileAnchor::Current: {
|
||||
return std::ios_base::cur;
|
||||
}
|
||||
case EFileSDKFileAnchor::End:
|
||||
default: {
|
||||
return std::ios_base::end;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright Incanta Games 2021. All Rights Reserved.
|
||||
|
||||
#include "FileSDKCopyFileAsync.h"
|
||||
|
||||
void UFileSDKCopyFileAsync::Activate() {
|
||||
FFileSDKFileInfo fileInfo;
|
||||
UFileSDKBPLibrary::GetFileOrDirectoryInfo(Source, fileInfo);
|
||||
|
||||
if (fileInfo.bIsDirectory) {
|
||||
FFunctionGraphTask::CreateAndDispatchWhenReady(
|
||||
[=] {
|
||||
auto successful = UFileSDKBPLibrary::CopyDirectory(
|
||||
Source,
|
||||
Destination,
|
||||
ProgressCallback,
|
||||
OverwriteDestination,
|
||||
ChunkSizeInKilobytes
|
||||
);
|
||||
|
||||
Completed.Broadcast(successful);
|
||||
},
|
||||
TStatId(),
|
||||
nullptr,
|
||||
ENamedThreads::AnyThread
|
||||
);
|
||||
} else {
|
||||
FFileSDKDelegatePreInfo PreInfo;
|
||||
FFunctionGraphTask::CreateAndDispatchWhenReady(
|
||||
[=] {
|
||||
auto successful = UFileSDKBPLibrary::CopyFile(
|
||||
Source,
|
||||
Destination,
|
||||
ProgressCallback,
|
||||
PreInfo,
|
||||
ChunkSizeInKilobytes,
|
||||
OverwriteDestination
|
||||
);
|
||||
|
||||
Completed.Broadcast(successful);
|
||||
},
|
||||
TStatId(),
|
||||
nullptr,
|
||||
ENamedThreads::AnyThread
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
UFileSDKCopyFileAsync* UFileSDKCopyFileAsync::CopyFileAsync(
|
||||
UObject* WorldContextObject,
|
||||
FString Source,
|
||||
FString Destination,
|
||||
const FFileSDKCopyDelegate & ProgressCallback,
|
||||
bool OverwriteDestination,
|
||||
int ChunkSizeInKilobytes
|
||||
) {
|
||||
// Create Action Instance for Blueprint System
|
||||
UFileSDKCopyFileAsync* Action = NewObject<UFileSDKCopyFileAsync>();
|
||||
Action->Source = Source;
|
||||
Action->Destination = Destination;
|
||||
Action->ProgressCallback = ProgressCallback;
|
||||
Action->OverwriteDestination = OverwriteDestination;
|
||||
Action->ChunkSizeInKilobytes = ChunkSizeInKilobytes;
|
||||
Action->RegisterWithGameInstance(WorldContextObject);
|
||||
|
||||
return Action;
|
||||
}
|
||||
102
Plugins/FileSDK/Source/FileSDK/Private/FileSDKFileReader.cpp
Normal file
102
Plugins/FileSDK/Source/FileSDK/Private/FileSDKFileReader.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
// Copyright Incanta Games 2020. All Rights Reserved.
|
||||
|
||||
#include "FileSDKFileReader.h"
|
||||
#include "FileSDKBPLibrary.h"
|
||||
|
||||
UFileSDKFileReader::UFileSDKFileReader(
|
||||
const FObjectInitializer& ObjectInitializer
|
||||
) : Super(ObjectInitializer) {
|
||||
//
|
||||
}
|
||||
|
||||
void UFileSDKFileReader::OpenFile(
|
||||
FString fileName,
|
||||
bool OpenInBinaryMode
|
||||
) {
|
||||
this->FileName = fileName;
|
||||
this->BinaryMode = OpenInBinaryMode;
|
||||
this->fileReader = new std::ifstream();
|
||||
if (OpenInBinaryMode) {
|
||||
this->fileReader->open(TCHAR_TO_UTF8(*fileName), std::ios_base::in | std::ios_base::binary);
|
||||
} else {
|
||||
this->fileReader->open(TCHAR_TO_UTF8(*fileName), std::ios_base::in);
|
||||
}
|
||||
}
|
||||
|
||||
bool UFileSDKFileReader::IsGood() {
|
||||
return this->fileReader && this->fileReader->good();
|
||||
}
|
||||
|
||||
bool UFileSDKFileReader::SeekFilePosition(
|
||||
EFileSDKFileAnchor Anchor,
|
||||
int Offset
|
||||
) {
|
||||
if (this->fileReader && this->fileReader->good()) {
|
||||
this->fileReader->seekg(
|
||||
Offset,
|
||||
UFileSDKBPLibrary::FileAnchorToSeekDir(Anchor)
|
||||
);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int UFileSDKFileReader::ReadBytes(int Num, TArray<uint8> & Content) {
|
||||
if (this->fileReader && this->fileReader->good()) {
|
||||
char * buffer = new char[Num];
|
||||
Content.Reserve(Num);
|
||||
memset(buffer, 0, Num);
|
||||
this->fileReader->read(buffer, Num);
|
||||
int numRead = this->fileReader->gcount();
|
||||
Content.Append((uint8*) buffer, numRead);
|
||||
return numRead;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int UFileSDKFileReader::ReadBytesToEnd(TArray<uint8> & Content) {
|
||||
if (this->fileReader && this->fileReader->good()) {
|
||||
int currentPosition = this->fileReader->tellg();
|
||||
this->fileReader->seekg(0, std::ios_base::end);
|
||||
int endPosition = this->fileReader->tellg();
|
||||
this->fileReader->seekg(currentPosition, std::ios_base::beg);
|
||||
|
||||
return this->ReadBytes(endPosition - currentPosition + 1, Content);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int UFileSDKFileReader::ReadString(int Num, FString & Content) {
|
||||
if (this->fileReader && this->fileReader->good()) {
|
||||
char * buffer = new char[Num + 1]; // one more for string termination
|
||||
Content.Reset(Num);
|
||||
memset(buffer, 0, Num + 1);
|
||||
this->fileReader->read(buffer, Num);
|
||||
Content.Append(buffer);
|
||||
return this->fileReader->gcount();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int UFileSDKFileReader::ReadStringToEnd(FString & Content) {
|
||||
if (this->fileReader && this->fileReader->good()) {
|
||||
int currentPosition = this->fileReader->tellg();
|
||||
this->fileReader->seekg(0, std::ios_base::end);
|
||||
int endPosition = this->fileReader->tellg();
|
||||
this->fileReader->seekg(currentPosition, std::ios_base::beg);
|
||||
|
||||
return this->ReadString(endPosition - currentPosition + 1, Content);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void UFileSDKFileReader::Close() {
|
||||
if (this->fileReader) {
|
||||
this->fileReader->close();
|
||||
}
|
||||
}
|
||||
34
Plugins/FileSDK/Source/FileSDK/Public/FileAnchor.h
Normal file
34
Plugins/FileSDK/Source/FileSDK/Public/FileAnchor.h
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright Incanta Games 2021. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ios>
|
||||
|
||||
UENUM( BlueprintType )
|
||||
enum class EFileSDKFileAnchor : uint8 {
|
||||
/**
|
||||
* References the beginning of the file. Great for reading metadata, resetting your location,
|
||||
* or just going to exact location. If you're in the middle of the file and want to to go to
|
||||
* 300 bytes from the beginning, set Anchor to Beginning and Offset to 300. A negative Offset
|
||||
* doesn't make sense when using Beginning.
|
||||
*/
|
||||
Beginning,
|
||||
|
||||
/**
|
||||
* References the current location of the file reader. Great for skipping chunks of data
|
||||
* (i.e. your file has an array of stuff and you only want to read the metadata headers for
|
||||
* each item, you can read the metadata, skip past the actual chunk, and go to the next
|
||||
* metadata location) If you want to advanced your current location 100 bytes backwards,
|
||||
* set Anchor to Current and Offset to -100.
|
||||
*/
|
||||
Current,
|
||||
|
||||
/**
|
||||
* References the end of the file. Great for reading footers where information is stored
|
||||
* at the end of the file. Many times you use this when you open the file, but the metadata
|
||||
* you want is near the end of the file a fixed number of bytes. For example, 300 bytes from
|
||||
* the end would have Anchor set to End and Offset set to -300. A positive Offset doesn't
|
||||
* make sense when using Beginning.
|
||||
*/
|
||||
End
|
||||
};
|
||||
15
Plugins/FileSDK/Source/FileSDK/Public/FileSDK.h
Normal file
15
Plugins/FileSDK/Source/FileSDK/Public/FileSDK.h
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright Incanta Games 2020. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogFileSDK, Log, All);
|
||||
|
||||
class FFileSDKModule : public IModuleInterface {
|
||||
public:
|
||||
|
||||
/** IModuleInterface implementation */
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
563
Plugins/FileSDK/Source/FileSDK/Public/FileSDKBPLibrary.h
Normal file
563
Plugins/FileSDK/Source/FileSDK/Public/FileSDKBPLibrary.h
Normal file
@@ -0,0 +1,563 @@
|
||||
// Copyright Incanta Games 2020. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ios>
|
||||
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "Misc/Paths.h"
|
||||
#include "Misc/FileHelper.h"
|
||||
#include "HAL/FileManagerGeneric.h"
|
||||
#include "Async/TaskGraphInterfaces.h"
|
||||
#include "Templates/SubclassOf.h"
|
||||
|
||||
#include "FileSDKFileInfo.h"
|
||||
#include "FileSDKFileType.h"
|
||||
#include "FileAnchor.h"
|
||||
#include "FileSDKLineReader.h"
|
||||
#include "FileSDKEncodingOptions.h"
|
||||
#include "FileSDK.h"
|
||||
#include "FileSDKFileReader.h"
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#include "Windows/WindowsPlatformMisc.h"
|
||||
#elif PLATFORM_LINUX || PLATFORM_ANDROID
|
||||
#include "Unix/UnixPlatformMisc.h"
|
||||
#elif PLATFORM_MAC || PLATFORM_IOS
|
||||
#include "Apple/ApplePlatformMisc.h"
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include "FileSDKBPLibrary.generated.h"
|
||||
|
||||
UDELEGATE()
|
||||
DECLARE_DYNAMIC_DELEGATE_TwoParams(FFileSDKCopyDelegate, int, KilobytesWritten, int, TotalKilobytes);
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FFileSDKDelegatePreInfo {
|
||||
GENERATED_USTRUCT_BODY();
|
||||
int PriorWritten;
|
||||
int TotalSize;
|
||||
|
||||
FFileSDKDelegatePreInfo() {
|
||||
PriorWritten = 0;
|
||||
TotalSize = 0;
|
||||
}
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class UFileSDKBPLibrary : public UBlueprintFunctionLibrary {
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/**
|
||||
* Creates a File Reader instance; File Readers can be used to control how the file is read.
|
||||
* You can seek to different parts of the file, only read in a specified number of bytes, etc.
|
||||
* This gives you the most amount of control and is great for only reading metadata in large files.
|
||||
*
|
||||
* @param FileName An absolute path of the file that you want to open for reading.
|
||||
* @param OpenInBinaryMode Setting this to true will open the file for reading binary data;
|
||||
* false opens the file to read text data.
|
||||
*
|
||||
* @return The File Reader instance regardless of the status of successful open.
|
||||
* See the `Is Good` node before attempting to read anything.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Open File Reader",
|
||||
Keywords = "FileSDK open file reader"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static UFileSDKFileReader * OpenFileReader(
|
||||
FString FileName,
|
||||
bool OpenInBinaryMode = false
|
||||
);
|
||||
|
||||
/**
|
||||
* Creates an empty file.
|
||||
*
|
||||
* @param FileName An absolute path to the file you want to create.
|
||||
* @param ClearContentsIfExists If set to true this node will completely delete any content in the file.
|
||||
* @param CreateDirectoryTree If set to true, any missing folders to get to File Name will be automatically created.
|
||||
* See docs at wiki.incanta.games for more details.
|
||||
*
|
||||
* @return Returns true if the file was successfully deleted.
|
||||
* Returns false if the file doesn't exist or the file couldn't be deleted.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Create File",
|
||||
Keywords = "FileSDK create make generate file"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static void CreateFile(FString FileName, bool ClearContentsIfExists = true, bool CreateDirectoryTree = true);
|
||||
|
||||
/**
|
||||
* Deletes a file if it exists; does nothing if it doesn't exist.
|
||||
*
|
||||
* @param FileName An absolute path to the file you want to delete.
|
||||
*
|
||||
* @return Returns true if the file was successfully deleted.
|
||||
* Returns false if the file doesn't exist or the file couldn't be deleted.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Delete File",
|
||||
Keywords = "FileSDK delete file destroy"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static bool DeleteFile(FString FileName);
|
||||
|
||||
/**
|
||||
* Creates a directory.
|
||||
*
|
||||
* @param DirectoryName An absolute path to the directory you want to create.
|
||||
* @param CreateDirectoryTree If set to true, any missing folders to get to File Name will be automatically created.
|
||||
* See docs at wiki.incanta.games for more details.
|
||||
*
|
||||
* @return Returns whether or not the directory was successfully created.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Create Directory",
|
||||
Keywords = "FileSDK create make generate directory folder"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static bool CreateDirectory(FString DirectoryName, bool CreateDirectoryTree = true);
|
||||
|
||||
/**
|
||||
* Deletes a directory.
|
||||
*
|
||||
* @param DirectoryName An absolute path to the directory you want to create.
|
||||
* @param Recursive If set to true, all files and folders in this directory will be deleted.
|
||||
* If set to false, the directory will only be deleted if it is empty.
|
||||
*
|
||||
* @return Returns whether or not the directory was successfully deleted.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Delete Directory",
|
||||
Keywords = "FileSDK delete destroy remove directory folder"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static bool DeleteDirectory(FString DirectoryName, bool Recursive = true);
|
||||
|
||||
/**
|
||||
* Renames/moves a file or a directory to a new name/location.
|
||||
*
|
||||
* @param Source An absolute path to the file/directory that you want to rename/move.
|
||||
* @param Destination An absolute path of the new location/name you want for the file or directory.
|
||||
* You cannot provide "/path/to/file.csv" for Source and only provide "file-old.csv" for Destination;
|
||||
* you must provide the full absolute path of the new file (i.e. "/path/to/file-old.csv").
|
||||
*
|
||||
* @return Returns whether or not the file/directory was successfully renamed/moved.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Rename File or Directory",
|
||||
Keywords = "FileSDK rename move file directory folder"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static bool RenameFileOrDirectory(FString Source, FString Destination);
|
||||
|
||||
/**
|
||||
* Copies a file, creating a duplicate version. Performs the copy operation on the main game thread;
|
||||
* this can have performance issues for large files. See `Copy File Async` to perform the copy in the
|
||||
* background (in a separate thread).
|
||||
*
|
||||
* @param Source An absolute path to the file you want to copy.
|
||||
* @param Destination An absolute path to where you want to copy the file to. You cannot provide
|
||||
* "/path/to/file.csv" for Source and only provide "file-old.csv" for Destination; you must provide
|
||||
* the full absolute path of the new file (i.e. "/path/to/file-old.csv").
|
||||
* @param ProgressCallback This allows you to attach an event to receive execution when progress is made,
|
||||
* allowing you to update a UI or other variables about the progress left for copying the file.
|
||||
* @param PreInfo The number of kilobytes you want each chunk of data to be copied as.
|
||||
* Smaller numbers can give you more fine progress updates, but at the cost of more disk IO operations,
|
||||
* potentially slowing down the overall copy.
|
||||
* @param OverwriteDestination If file exists and this is set to true, the contents of the file will be overwritten.
|
||||
*
|
||||
* @return Returns false if Source could not be opened (likely because it doesn't exist) or if Destination
|
||||
* could not be opened for write permissions (likely the directory doesn't exist, or the user doesn't have
|
||||
* permissions to write there). Returns true if the copy was successful.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Copy File",
|
||||
Keywords = "FileSDK copy file",
|
||||
AutoCreateRefTerm = "ProgressCallback, PreInfo",
|
||||
HidePin = "PreInfo"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static bool CopyFile(
|
||||
FString Source,
|
||||
FString Destination,
|
||||
const FFileSDKCopyDelegate & ProgressCallback,
|
||||
FFileSDKDelegatePreInfo PreInfo,
|
||||
int ChunkSizeInKilobytes = 1024,
|
||||
bool OverwriteDestination = false
|
||||
);
|
||||
|
||||
/**
|
||||
* Copies a file, creating a duplicate version. Performs the copy operation in a separate
|
||||
* background thread, preventing the game thread from waiting for the copy operation to finish.
|
||||
*
|
||||
* @param Source An absolute path to the file you want to copy.
|
||||
* @param Destination An absolute path to where you want to copy the file to. You cannot provide
|
||||
* "/path/to/file.csv" for Source and only provide "file-old.csv" for Destination; you must provide
|
||||
* the full absolute path of the new file (i.e. "/path/to/file-old.csv").
|
||||
* @param ProgressCallback This allows you to attach an event to receive execution when progress is made,
|
||||
* allowing you to update a UI or other variables about the progress left for copying the file.
|
||||
* @param ChunkSizeInKilobytes The number of kilobytes you want each chunk of data to be copied as.
|
||||
* Smaller numbers can give you more fine progress updates, but at the cost of more disk IO operations,
|
||||
* potentially slowing down the overall copy.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DeprecatedFunction,
|
||||
DeprecationMessage="This function has been deprecated; please use 'Copy File or Directory Async'.",
|
||||
DisplayName = "Copy File Async",
|
||||
Keywords = "FileSDK copy file async",
|
||||
AutoCreateRefTerm = "ProgressCallback, PreInfo",
|
||||
HidePin = "PreInfo"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static void CopyFileAsync(
|
||||
FString Source,
|
||||
FString Destination,
|
||||
const FFileSDKCopyDelegate & ProgressCallback,
|
||||
FFileSDKDelegatePreInfo PreInfo,
|
||||
int ChunkSizeInKilobytes = 1024
|
||||
);
|
||||
|
||||
/**
|
||||
* Copies a directory, including all of its contents, creating a duplicate version.
|
||||
* Performs the copy operation on the main game thread; this can have performance issues for large
|
||||
* directories. See "Copy Directory Async" to perform the copy in the background (in a separate thread).
|
||||
*
|
||||
* @param Source An absolute path to the directory you want to copy.
|
||||
* @param Destination An absolute path to where you want to copy the directory to.
|
||||
* @param ProgressCallback This allows you to attach an event to receive execution when progress is made,
|
||||
* allowing you to update a UI or other variables about the progress left for copying the directory.
|
||||
* @param OverwriteDestination If set to true, if a particular file exists in the respective Destination
|
||||
* location, it will be overwritten with the new contents. Otherwise it will be ignored. For example if
|
||||
* you're copying "/path/from" to "/path/to", and "/path/to/file.txt" already exists, if this is set to true,
|
||||
* /path/from/file.txt will overwrite "/path/to/file.txt", if set to false, "/path/to/file.txt" will remain
|
||||
* unchanged.
|
||||
* @param ChunkSizeInKilobytes The number of kilobytes you want each chunk of data to be copied as.
|
||||
* Smaller numbers can give you more fine progress updates, but at the cost of more disk IO operations,
|
||||
* potentially slowing down the overall copy.
|
||||
*
|
||||
* @return Returns true if the copy finished successfully. Returns false if any of the files couldn't be
|
||||
* copied or if subdirectories couldn't be created (usually this happens if there are permissions issues
|
||||
* or files are open in other programs).
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Copy Directory",
|
||||
Keywords = "FileSDK copy directory folder",
|
||||
AutoCreateRefTerm = "ProgressCallback"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static bool CopyDirectory(
|
||||
FString Source,
|
||||
FString Destination,
|
||||
const FFileSDKCopyDelegate & ProgressCallback,
|
||||
bool OverwriteDestination = false,
|
||||
int ChunkSizeInKilobytes = 1024
|
||||
);
|
||||
|
||||
/**
|
||||
* Copies a directory, including all of its contents, creating a duplicate version.
|
||||
* Performs the copy operation in a separate background thread, preventing the game thread
|
||||
* from waiting for the copy operation to finish.
|
||||
*
|
||||
* @param Source An absolute path to the directory you want to copy.
|
||||
* @param Destination An absolute path to where you want to copy the directory to.
|
||||
* @param ProgressCallback This allows you to attach an event to receive execution when progress is made,
|
||||
* allowing you to update a UI or other variables about the progress left for copying the directory.
|
||||
* @param OverwriteDestination If set to true, if a particular file exists in the respective Destination
|
||||
* location, it will be overwritten with the new contents. Otherwise it will be ignored. For example if
|
||||
* you're copying "/path/from" to "/path/to", and "/path/to/file.txt" already exists, if this is set to true,
|
||||
* /path/from/file.txt will overwrite "/path/to/file.txt", if set to false, "/path/to/file.txt" will remain
|
||||
* unchanged.
|
||||
* @param ChunkSizeInKilobytes The number of kilobytes you want each chunk of data to be copied as.
|
||||
* Smaller numbers can give you more fine progress updates, but at the cost of more disk IO operations,
|
||||
* potentially slowing down the overall copy.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DeprecatedFunction,
|
||||
DeprecationMessage="This function has been deprecated; please use 'Copy File or Directory Async'.",
|
||||
DisplayName = "Copy Directory Async",
|
||||
Keywords = "FileSDK copy directory folder async",
|
||||
AutoCreateRefTerm = "ProgressCallback"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static void CopyDirectoryAsync(
|
||||
FString Source,
|
||||
FString Destination,
|
||||
const FFileSDKCopyDelegate & ProgressCallback,
|
||||
bool OverwriteDestination = false,
|
||||
int ChunkSizeInKilobytes = 1024
|
||||
);
|
||||
|
||||
/**
|
||||
* Reads the entire contents of a file as text into a string.
|
||||
*
|
||||
* @param FileName An absolute path to the file you would like to read.
|
||||
*
|
||||
* @param Content The entire contents of File Name.
|
||||
* @return Returns true if the file could be opened and read successfully.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintPure,
|
||||
meta = (
|
||||
DisplayName = "Read String from File",
|
||||
Keywords = "FileSDK read file string text"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static bool ReadStringFromFile(FString FileName, FString & Content);
|
||||
|
||||
/**
|
||||
* Read the entire contents of a file as an array of strings. Each element in the array is a
|
||||
* separate line in the file. Both LF (Line Feed, used in Linux and Mac systems) and CRLF
|
||||
* (Carriage Return, Line Feed, used in Windows systems) are supported.
|
||||
*
|
||||
* @param FileName An absolute path to the file you would like to read.
|
||||
* @param LineReader While every line is read from the file regardless, you can use this
|
||||
* parameter to filter which lines are returned in Lines. To do this, specify a child class
|
||||
* of the "FileSDKLineReader" class and override the "FilterLine" function. When the "FilterLine"
|
||||
* function returns true, the line is provided in the output of the "Read Lines From File" function.
|
||||
* Find more details in our docs at wiki.incanta.games.
|
||||
*
|
||||
* @param Lines The lines of the file, optionally filtered by LineReader. These do not contain the
|
||||
* line endings (i.e. there is no LF or CRLF character(s) at the end of the strings).
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintPure,
|
||||
meta = (
|
||||
DisplayName = "Read Lines from File",
|
||||
Keywords = "FileSDK read lines array file string text"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static bool ReadLinesFromFile(
|
||||
FString FileName,
|
||||
TSubclassOf<class UFileSDKLineReader> LineReader,
|
||||
TArray<FString> & Lines
|
||||
);
|
||||
|
||||
/**
|
||||
* Writes a string as text to a file, with options to overwrite/append as well as encoding options.
|
||||
* Will create the file if it doesn't exist. This node expects the parent directory to already exist
|
||||
* (i.e. it will not create directories for you, and will return false if the parent directories do not exist).
|
||||
*
|
||||
* @param FileName An absolute path to the file you would like to write.
|
||||
* @param Content The text you would like to write to the file.
|
||||
* @param Append If set to true, the file will be erased before writing Content to it; if set to false,
|
||||
* Content will be written at the end of hte file. New lines/carriage returns will not be automatically
|
||||
* inserted for you.
|
||||
* @param Encoding Encoding options that are passed down to the file writer. "Auto Detect" will do its
|
||||
* best to determine the encoding of the string, but you can also use one of the
|
||||
* "Force (Ansi | Unicode | UTF8 | UTF8WithoutBOM)" options to force how the contents are encoded.
|
||||
*
|
||||
* @return Returns true if the file could be opened and written successfully.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Write String to File",
|
||||
Keywords = "FileSDK write append save file string text"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static bool WriteStringToFile(
|
||||
FString FileName,
|
||||
FString Content,
|
||||
bool Append = false,
|
||||
EFileSDKEncodingOptions Encoding = EFileSDKEncodingOptions::AutoDetect
|
||||
);
|
||||
|
||||
/**
|
||||
* Writes a Byte array as binary data to a file. This node currently always overwrites the
|
||||
* file contents. If you have a use case for appending binary files, please let us know.
|
||||
* Will create the file if it doesn't exist. This node expects the parent directory to already
|
||||
* exist (i.e. it will not create directories for you, and will return false if the parent
|
||||
* directories do not exist).
|
||||
*
|
||||
* @param FileName An absolute path to the file you want to write.
|
||||
* @param Content The bytes you would like to write to the file.
|
||||
*
|
||||
* @return Returns true if the file was opened wnd written successfully.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Write Bytes to File",
|
||||
Keywords = "FileSDK write save file bytes binary"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static bool WriteBytesToFile(FString FileName, TArray<uint8> Content);
|
||||
|
||||
/**
|
||||
* Reads the entire contents of a file as a binary Byte array.
|
||||
*
|
||||
* @param FileName An absolute path to the file you want to read.
|
||||
*
|
||||
* @param Content The entire contents of File Name.
|
||||
* @return Returns true if the file was opened and read successfully.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintPure,
|
||||
meta = (
|
||||
DisplayName = "Read Bytes from File",
|
||||
Keywords = "FileSDK read file bytes binary"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static bool ReadBytesFromFile(FString FileName, TArray<uint8> & Content);
|
||||
|
||||
/**
|
||||
* Searches for files or directories in a directory.
|
||||
*
|
||||
* @param DirectoryToSearch An absolute path to the directory that you want to search in.
|
||||
* @param FilterFilesWithExtension Only used if "File Type" is "File". This argument allows
|
||||
* you to filter the results by the file extension. Proper usage of this argument is
|
||||
* ".txt", ".csv", etc, including the period.
|
||||
* @param SearchSubfolders Whether or not to search subdirectories (true) or just search
|
||||
* the single folder provided (false).
|
||||
* @param FileType Whether or not to search for a "File" or a "Directory".
|
||||
*
|
||||
* @return An array of absolute paths to each file or directory found.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Get Files or Directories from Directory",
|
||||
Keywords = "FileSDK get search find files list directory contents"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static TArray<FString> GetFilesFromDirectory(
|
||||
FString DirectoryToSearch,
|
||||
FString FilterFilesWithExtension,
|
||||
bool SearchSubfolders = false,
|
||||
EFileSDKFileType FileType = EFileSDKFileType::File
|
||||
);
|
||||
|
||||
/**
|
||||
* Lists the contents of a directory, including both files and directories, with supplemental information.
|
||||
*
|
||||
* @param Directory An absolute path to the directory that you want to list contents of.
|
||||
* @param SearchSubfolders Whether or not to search subdirectories (true) or just search the
|
||||
* single folder provided (false).
|
||||
*
|
||||
* @return An array of FileSDKFileInfo structs, one for each file and directory, each containing detailed
|
||||
* information of the file/directory.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Get Directory Contents with File Info",
|
||||
Keywords = "FileSDK get search find files list directory contents file info stat"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static TArray<FFileSDKFileInfo> GetDirectoryContentsWithFileInfo(
|
||||
FString Directory,
|
||||
bool SearchSubfolders = false
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns detailed information for a specific file or directory.
|
||||
*
|
||||
* @param Path An absolute path to the file or directory you want information for.
|
||||
*
|
||||
* @param Info The detailed info struct of the file.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintPure,
|
||||
meta = (
|
||||
DisplayName = "Get File or Directory Info",
|
||||
Keywords = "FileSDK get file"
|
||||
),
|
||||
Category = "FileSDK"
|
||||
)
|
||||
static void GetFileOrDirectoryInfo(FString Path, FFileSDKFileInfo & Info);
|
||||
|
||||
/**
|
||||
* Retrieves the current username for whoever is running the program/game. (i.e. <user> in C:\Users\<user>)
|
||||
*
|
||||
* @return On Windows, this returns the environment variable "%USERNAME%". On Mac and Linux, this returns
|
||||
* the environment variable "$USER". On other platforms, it returns "PLATFORM_NOT_SUPPORTED".
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintPure,
|
||||
meta = (
|
||||
DisplayName = "Get Current Username",
|
||||
Keywords = "FileSDK get current user name username"
|
||||
),
|
||||
Category = "FileSDK | Paths"
|
||||
)
|
||||
static FString GetCurrentUsername();
|
||||
|
||||
/**
|
||||
* Returns the current user's home directory. (i.e. the entire C:\Users\<user path)
|
||||
*
|
||||
* @return On Windows, this returns the environment variable "%HOMEDRIVE%" concatenated with "%HOMEPATH%"
|
||||
* (i.e. "%HOMEDRIVE%%HOMEPATH%"). On Mac and Linux, this returns the environment variable "$HOME".
|
||||
* On other platforms, it returns "PLATFORM_NOT_SUPPORTED".
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintPure,
|
||||
meta = (
|
||||
DisplayName = "Get Current User Home Directory",
|
||||
Keywords = "FileSDK get current user home directory"
|
||||
),
|
||||
Category = "FileSDK | Paths"
|
||||
)
|
||||
static FString GetCurrentUserHomeDirectory();
|
||||
|
||||
/**
|
||||
* Returns the value of an environment variable.
|
||||
*
|
||||
* @param VariableName On Windows, you fetch environment variables in Command Prompt with something like "%VAR%";
|
||||
* on Mac and Linux, you fetch environment variables in the terminal with something like "$VAR".
|
||||
* In both cases, Variable Name is VAR without the "%" or "$".
|
||||
*
|
||||
* @return Returns the value of the environment variable if it's set. If it's not set it returns an empty string.
|
||||
* On target platforms that are not Windows, Mac, or Linux, "PLATFORM_NOT_SUPPORTED" is returned.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintPure,
|
||||
meta = (
|
||||
DisplayName = "Get Environment Variable",
|
||||
Keywords = "FileSDK get environment env variable"
|
||||
),
|
||||
Category = "FileSDK | Paths"
|
||||
)
|
||||
static FString GetEnvironmentVariable(FString VariableName);
|
||||
|
||||
static std::ios_base::seekdir FileAnchorToSeekDir(EFileSDKFileAnchor Anchor);
|
||||
};
|
||||
100
Plugins/FileSDK/Source/FileSDK/Public/FileSDKCopyFileAsync.h
Normal file
100
Plugins/FileSDK/Source/FileSDK/Public/FileSDKCopyFileAsync.h
Normal file
@@ -0,0 +1,100 @@
|
||||
// Copyright Incanta Games 2021. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Kismet/BlueprintAsyncActionBase.h"
|
||||
#include "FileSDKBPLibrary.h"
|
||||
|
||||
#include "FileSDKCopyFileAsync.generated.h"
|
||||
|
||||
// Event that will be the 'Completed' exec wire in the blueprint node along with all parameters as output pins.
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(
|
||||
FFileSDKOnCopyCompleted,
|
||||
bool,
|
||||
Successful
|
||||
);
|
||||
|
||||
UCLASS()
|
||||
class FILESDK_API UFileSDKCopyFileAsync : public UBlueprintAsyncActionBase {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
/** Execute the actual load */
|
||||
virtual void Activate() override;
|
||||
|
||||
/**
|
||||
* Copy a file or a directory, creating a duplicate version. Performs the copy operation
|
||||
* in a separate background thread, preventing the game thread from waiting for the copy
|
||||
* operation to finish.
|
||||
*
|
||||
* @param Source An absolute path to the file you want to copy.
|
||||
* @param Destination An absolute path to where you want to copy the file to. You cannot provide
|
||||
* "/path/to/file.csv" for Source and only provide "file-old.csv" for Destination; you must provide
|
||||
* the full absolute path of the new file (i.e. "/path/to/file-old.csv").
|
||||
* @param ProgressCallback This allows you to attach an event to receive execution when progress is made,
|
||||
* allowing you to update a UI or other variables about the progress left for copying the file.
|
||||
* @param OverwriteDestination If set to true, if a particular file exists in the respective Destination
|
||||
* location, it will be overwritten with the new contents. Otherwise it will be ignored. For example if
|
||||
* you're copying "/path/from" to "/path/to", and "/path/to/file.txt" already exists, if this is set to true,
|
||||
* /path/from/file.txt will overwrite "/path/to/file.txt", if set to false, "/path/to/file.txt" will remain
|
||||
* unchanged.
|
||||
* @param ChunkSizeInKilobytes The number of kilobytes you want each chunk of data to be copied as.
|
||||
* Smaller numbers can give you more fine progress updates, but at the cost of more disk IO operations,
|
||||
* potentially slowing down the overall copy.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Copy File or Directory Async",
|
||||
BlueprintInternalUseOnly="true",
|
||||
Category="FileSDK",
|
||||
WorldContext="WorldContextObject"
|
||||
)
|
||||
)
|
||||
static UFileSDKCopyFileAsync* CopyFileAsync(
|
||||
UObject* WorldContextObject,
|
||||
FString Source,
|
||||
FString Destination,
|
||||
const FFileSDKCopyDelegate & ProgressCallback,
|
||||
bool OverwriteDestination = false,
|
||||
int ChunkSizeInKilobytes = 1024
|
||||
);
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FFileSDKOnCopyCompleted Completed;
|
||||
|
||||
/**
|
||||
* An absolute path to the file you want to copy.
|
||||
*/
|
||||
FString Source;
|
||||
|
||||
/**
|
||||
* An absolute path to where you want to copy the file to. You cannot provide
|
||||
* "/path/to/file.csv" for Source and only provide "file-old.csv" for Destination; you must provide
|
||||
* the full absolute path of the new file (i.e. "/path/to/file-old.csv").
|
||||
*/
|
||||
FString Destination;
|
||||
|
||||
/**
|
||||
* This allows you to attach an event to receive execution when progress is made,
|
||||
* allowing you to update a UI or other variables about the progress left for copying the file.
|
||||
*/
|
||||
FFileSDKCopyDelegate ProgressCallback;
|
||||
|
||||
/**
|
||||
* If set to true, if a particular file exists in the respective Destination
|
||||
* location, it will be overwritten with the new contents. Otherwise it will be ignored. For example if
|
||||
* you're copying "/path/from" to "/path/to", and "/path/to/file.txt" already exists, if this is set to true,
|
||||
* /path/from/file.txt will overwrite "/path/to/file.txt", if set to false, "/path/to/file.txt" will remain
|
||||
* unchanged.
|
||||
*/
|
||||
bool OverwriteDestination;
|
||||
|
||||
/**
|
||||
* The number of kilobytes you want each chunk of data to be copied as.
|
||||
* Smaller numbers can give you more fine progress updates, but at the
|
||||
* cost of more disk IO operations, potentially slowing down the overall copy.
|
||||
*/
|
||||
int ChunkSizeInKilobytes;
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright Incanta Games 2021. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Misc/FileHelper.h"
|
||||
|
||||
UENUM( BlueprintType )
|
||||
enum class EFileSDKEncodingOptions : uint8 {
|
||||
AutoDetect,
|
||||
ForceAnsi,
|
||||
ForceUnicode,
|
||||
ForceUTF8,
|
||||
ForceUTF8WithoutBOM
|
||||
};
|
||||
46
Plugins/FileSDK/Source/FileSDK/Public/FileSDKFileInfo.h
Normal file
46
Plugins/FileSDK/Source/FileSDK/Public/FileSDKFileInfo.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright Incanta Games 2020. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "FileSDKFileInfo.generated.h"
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FFileSDKFileInfo {
|
||||
GENERATED_USTRUCT_BODY();
|
||||
|
||||
/** The full absolute path and file name */
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Details")
|
||||
FString AbsolutePath;
|
||||
|
||||
/** The file name without the path */
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Details")
|
||||
FString Filename;
|
||||
|
||||
/** The time that the file or directory was originally created, or FDateTime::MinValue if the creation time is unknown */
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Details")
|
||||
FDateTime CreationTime;
|
||||
|
||||
/** The time that the file or directory was last accessed, or FDateTime::MinValue if the access time is unknown */
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Details")
|
||||
FDateTime AccessTime;
|
||||
|
||||
/** The time the the file or directory was last modified, or FDateTime::MinValue if the modification time is unknown */
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Details")
|
||||
FDateTime ModificationTime;
|
||||
|
||||
/** Size of the file (in bytes), or -1 if the file size is unknown */
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Details")
|
||||
int64 FileSize;
|
||||
|
||||
/** True if this data is for a directory, false if it's for a file */
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Details")
|
||||
bool bIsDirectory;
|
||||
|
||||
/** True if this file is read-only */
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Details")
|
||||
bool bIsReadOnly;
|
||||
|
||||
/** True if file or directory was found, false otherwise. Note that this value being true does not ensure that the other members are filled in with meaningful data, as not all file systems have access to all of this data */
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Details")
|
||||
bool bIsValid;
|
||||
};
|
||||
163
Plugins/FileSDK/Source/FileSDK/Public/FileSDKFileReader.h
Normal file
163
Plugins/FileSDK/Source/FileSDK/Public/FileSDKFileReader.h
Normal file
@@ -0,0 +1,163 @@
|
||||
// Copyright Incanta Games 2021. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "UObject/Object.h"
|
||||
#include "FileAnchor.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "FileSDKFileReader.generated.h"
|
||||
|
||||
class UFileSDKBPLibrary;
|
||||
|
||||
UCLASS(BlueprintType, Blueprintable)
|
||||
class UFileSDKFileReader : public UObject {
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
void OpenFile(FString fileName, bool OpenInBinaryMode);
|
||||
|
||||
/**
|
||||
* Checks to see if the file reader is in a "good" state. This is synonymous to the C++ good function.
|
||||
* This function returns false if the file reader is in a bad state, failed, or at the end of the file.
|
||||
*
|
||||
* @return Returns false if the file reader is in a bad state, failed, or at the end of the file.
|
||||
* Returns true if the file is successfully open and ready to read more bytes (i.e. the pointer
|
||||
* is not at the end of the file).
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "File Is Good",
|
||||
Keywords = "FileSDK file reader is good open"
|
||||
),
|
||||
Category = "FileSDK | File Reader"
|
||||
)
|
||||
bool IsGood();
|
||||
|
||||
/**
|
||||
* Change the position of the File Reader; this is essentially a pointer of where you're going
|
||||
* to start reading for any of the following read nodes. When you open a File Reader, the seek
|
||||
* position starts at the Beginning. This is synonymous to the C++ seekg function.
|
||||
*
|
||||
* @param Anchor This defines the "from" where that Offset is applied to.
|
||||
* @param Offset Number of bytes to offset from the Anchor.
|
||||
*
|
||||
* @return Returns true if the file is open and "File Is Good"; otherwise returns false.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Seek File Position",
|
||||
Keywords = "FileSDK seek change file position pointer"
|
||||
),
|
||||
Category = "FileSDK | File Reader"
|
||||
)
|
||||
bool SeekFilePosition(EFileSDKFileAnchor Anchor, int Offset);
|
||||
|
||||
/**
|
||||
* Reads a specified number of bytes from the current file reader location as a binary Byte array.
|
||||
* The file reader location is advanced to where ever it finishes reading.
|
||||
*
|
||||
* @param Num The number of bytes to read. If Num greater than the number of bytes left in the file,
|
||||
* it will read to the end of the file.
|
||||
*
|
||||
* @param Content The bytes that were read in as a binary Byte array.
|
||||
* @return The actual number of bytes read. This is usually only different than Num if you reached
|
||||
* the end of the file. You should, however, still use Is Good to check if you're at the end of the file.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Read Bytes",
|
||||
Keywords = "FileSDK read bytes"
|
||||
),
|
||||
Category = "FileSDK | File Reader"
|
||||
)
|
||||
int ReadBytes(int Num, TArray<uint8> & Content);
|
||||
|
||||
/**
|
||||
* Reads the rest of the file from the current location as a binary Byte array. The file reader
|
||||
* location is advanced to the end of the file.
|
||||
*
|
||||
* @param Content The bytes that were read in as a binary Byte array.
|
||||
* @return The actual number of bytes read.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Read Bytes To End",
|
||||
Keywords = "FileSDK read bytes to end"
|
||||
),
|
||||
Category = "FileSDK | File Reader"
|
||||
)
|
||||
int ReadBytesToEnd(TArray<uint8> & Content);
|
||||
|
||||
/**
|
||||
* Reads a specified number of bytes from the current file reader location as a String.
|
||||
* The file reader location is advanced to where ever it finishes reading.
|
||||
*
|
||||
* @param Num The number of bytes to read. If Num greater than the number of bytes left in the file,
|
||||
* it will read to the end of the file.
|
||||
*
|
||||
* @param Content The bytes that were read in as a String.
|
||||
* @return The actual number of bytes read. This is usually only different than Num if you reached
|
||||
* the end of the file. You should, however, still use "File Is Good" to check if you're at the end of the file.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Read String",
|
||||
Keywords = "FileSDK read string chars characters"
|
||||
),
|
||||
Category = "FileSDK | File Reader"
|
||||
)
|
||||
int ReadString(int Num, FString & Content);
|
||||
|
||||
/**
|
||||
* Reads the rest of the file from the current location as a String. The file reader location
|
||||
* is advanced to the end of the file.
|
||||
*
|
||||
* @param Content The bytes that were read in as a String.
|
||||
* @return The actual number of bytes read.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Read String to End",
|
||||
Keywords = "FileSDK read string chars characters to end"
|
||||
),
|
||||
Category = "FileSDK | File Reader"
|
||||
)
|
||||
int ReadStringToEnd(FString & Content);
|
||||
|
||||
/**
|
||||
* Closes the file if it's valid/open. Does nothing otherwise.
|
||||
*/
|
||||
UFUNCTION(
|
||||
BlueprintCallable,
|
||||
meta = (
|
||||
DisplayName = "Close File Reader",
|
||||
Keywords = "FileSDK file reader close"
|
||||
),
|
||||
Category = "FileSDK | File Reader"
|
||||
)
|
||||
void Close();
|
||||
|
||||
/**
|
||||
* The absolute path to the file being read.
|
||||
*/
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Details")
|
||||
FString FileName;
|
||||
|
||||
/**
|
||||
* True if the file was opened to be read in binary mode, false for text.
|
||||
*/
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Details")
|
||||
bool BinaryMode;
|
||||
|
||||
private:
|
||||
std::ifstream * fileReader;
|
||||
|
||||
friend class UFileSDKBPLibrary;
|
||||
};
|
||||
9
Plugins/FileSDK/Source/FileSDK/Public/FileSDKFileType.h
Normal file
9
Plugins/FileSDK/Source/FileSDK/Public/FileSDKFileType.h
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright Incanta Games 2020. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
UENUM( BlueprintType )
|
||||
enum class EFileSDKFileType : uint8 {
|
||||
File,
|
||||
Directory,
|
||||
};
|
||||
28
Plugins/FileSDK/Source/FileSDK/Public/FileSDKLineReader.h
Normal file
28
Plugins/FileSDK/Source/FileSDK/Public/FileSDKLineReader.h
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright Incanta Games 2021. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "FileSDKLineReader.generated.h"
|
||||
|
||||
UCLASS(Blueprintable)
|
||||
class FILESDK_API UFileSDKLineReader : public UObject {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/**
|
||||
* An overridable function that dictates whether or not a line in a file
|
||||
* is filtered. Should return true if the line should be provided, false
|
||||
* if the line should be filtered out (not included).
|
||||
*
|
||||
* @param Line The contents of the current line, excluding line endings.
|
||||
*
|
||||
* @return Should return true if the line should be provided, false
|
||||
* if the line should be filtered out (not included).
|
||||
*/
|
||||
UFUNCTION(BlueprintNativeEvent, Category = "FileSDK")
|
||||
bool FilterLine(const FString & Line);
|
||||
|
||||
virtual bool FilterLine_Implementation(const FString & line) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user