573 lines
20 KiB
C++
573 lines
20 KiB
C++
// Copyright 2017-2019 David Romanski (Socke). All Rights Reserved.
|
|
|
|
#include "FileFunctionsSocketClient.h"
|
|
|
|
UFileFunctionsSocketClient* UFileFunctionsSocketClient::fileFunctionsSocketClient;
|
|
|
|
UFileFunctionsSocketClient::UFileFunctionsSocketClient(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) {
|
|
fileFunctionsSocketClient = this;
|
|
}
|
|
|
|
UFileFunctionsSocketClient* UFileFunctionsSocketClient::getFileFunctionsSocketClientTarget() {
|
|
return fileFunctionsSocketClient;
|
|
}
|
|
|
|
FString UFileFunctionsSocketClient::getCleanDirectory(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath) {
|
|
if (directoryType == EFileFunctionsSocketClientDirectoryType::E_ad) {
|
|
return FPaths::ConvertRelativePathToFull(filePath);
|
|
}
|
|
else {
|
|
FString ProjectDir = FPaths::ProjectDir();
|
|
return FPaths::ConvertRelativePathToFull(ProjectDir + filePath);
|
|
}
|
|
}
|
|
|
|
void UFileFunctionsSocketClient::writeBytesToFile(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, TArray<uint8> bytes, bool& success) {
|
|
success = FFileHelper::SaveArrayToFile(bytes, *getCleanDirectory(directoryType, filePath));
|
|
}
|
|
|
|
void UFileFunctionsSocketClient::addBytesToFileAndCloseIt(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, TArray<uint8> bytes, bool& success) {
|
|
FArchive* writer = IFileManager::Get().CreateFileWriter(*getCleanDirectory(directoryType, filePath), EFileWrite::FILEWRITE_Append);
|
|
if (!writer) {
|
|
success = false;
|
|
return;
|
|
}
|
|
writer->Seek(writer->TotalSize());
|
|
writer->Serialize(bytes.GetData(), bytes.Num());
|
|
writer->Close();
|
|
delete writer;
|
|
|
|
success = true;
|
|
}
|
|
|
|
//void UFileFunctionsSocketClient::splittFile(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, int32 parts, bool& success){
|
|
// if (parts <= 0)
|
|
// parts = 1;
|
|
// FArchive* reader = IFileManager::Get().CreateFileReader(*getCleanDirectory(directoryType, filePath));
|
|
// if (!reader) {
|
|
// success = false;
|
|
// return;
|
|
// }
|
|
//
|
|
// int64 splittAfterBytes = reader->TotalSize()/ ((int64)parts);
|
|
// TArray<uint8> bytes;
|
|
//
|
|
// for (int32 i = 0; i < parts; i++){
|
|
// bytes.AddUninitialized(splittAfterBytes);
|
|
// reader->Serialize(bytes.GetData(), splittAfterBytes);
|
|
// if (FFileHelper::SaveArrayToFile(bytes, *getCleanDirectory(directoryType, filePath)) == false) {
|
|
// success = false;
|
|
// return;
|
|
// }
|
|
// splittAfterBytes =
|
|
// reader->Seek();
|
|
// }
|
|
//
|
|
//}
|
|
|
|
TArray<uint8> UFileFunctionsSocketClient::readBytesFromFile(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, bool& success) {
|
|
TArray<uint8> result;
|
|
success = FFileHelper::LoadFileToArray(result, *getCleanDirectory(directoryType, filePath));
|
|
return result;
|
|
}
|
|
|
|
void UFileFunctionsSocketClient::readStringFromFile(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, bool& success, FString& data) {
|
|
data.Empty();
|
|
success = FFileHelper::LoadFileToString(data, *getCleanDirectory(directoryType, filePath));
|
|
}
|
|
|
|
void UFileFunctionsSocketClient::writeStringToFile(EFileFunctionsSocketClientDirectoryType directoryType, FString data, FString filePath, EFileFunctionsSocketClientEncodingOptions fileEncoding, bool& success) {
|
|
success = FFileHelper::SaveStringToFile(data, *getCleanDirectory(directoryType, filePath), (FFileHelper::EEncodingOptions)fileEncoding);
|
|
}
|
|
|
|
|
|
|
|
void UFileFunctionsSocketClient::getMD5FromFile(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, bool& success, FString& MD5) {
|
|
getMD5FromFileAbsolutePath(getCleanDirectory(directoryType, filePath), success, MD5);
|
|
}
|
|
|
|
void UFileFunctionsSocketClient::getMD5FromFileAbsolutePath(FString filePath, bool& success, FString& MD5) {
|
|
MD5.Empty();
|
|
FArchive* reader = IFileManager::Get().CreateFileReader(*filePath);
|
|
if (!reader) {
|
|
success = false;
|
|
return;
|
|
}
|
|
|
|
TArray<uint8> byteArrayTmp;
|
|
int64 totalSize = reader->TotalSize();
|
|
int64 loadedBytes = 0;
|
|
int64 leftUploadBytes = 1024;
|
|
|
|
|
|
if (totalSize < leftUploadBytes)
|
|
leftUploadBytes = totalSize;
|
|
|
|
|
|
uint8 Digest[16];
|
|
FMD5 Md5Gen;
|
|
|
|
while ((loadedBytes + leftUploadBytes) <= totalSize) {
|
|
byteArrayTmp.Reset(leftUploadBytes);
|
|
byteArrayTmp.AddUninitialized(leftUploadBytes);
|
|
reader->Serialize(byteArrayTmp.GetData(), byteArrayTmp.Num());
|
|
loadedBytes += leftUploadBytes;
|
|
reader->Seek(loadedBytes);
|
|
|
|
Md5Gen.Update(byteArrayTmp.GetData(), byteArrayTmp.Num());
|
|
}
|
|
|
|
leftUploadBytes = totalSize - loadedBytes;
|
|
if (leftUploadBytes > 0) {
|
|
byteArrayTmp.Reset(leftUploadBytes);
|
|
byteArrayTmp.AddUninitialized(leftUploadBytes);
|
|
reader->Serialize(byteArrayTmp.GetData(), byteArrayTmp.Num());
|
|
loadedBytes += leftUploadBytes;
|
|
Md5Gen.Update(byteArrayTmp.GetData(), byteArrayTmp.Num());
|
|
}
|
|
|
|
if (reader != nullptr) {
|
|
reader->Close();
|
|
delete reader;
|
|
}
|
|
|
|
if (totalSize != loadedBytes) {
|
|
success = false;
|
|
return;
|
|
}
|
|
|
|
Md5Gen.Final(Digest);
|
|
for (int32 i = 0; i < 16; i++) {
|
|
MD5 += FString::Printf(TEXT("%02x"), Digest[i]);
|
|
}
|
|
|
|
success = true;
|
|
}
|
|
|
|
void UFileFunctionsSocketClient::stringToBase64String(FString string, FString& base64String) {
|
|
base64String.Empty();
|
|
FTCHARToUTF8 Convert(*string);
|
|
TArray<uint8> bytes;
|
|
bytes.Append(((uint8*)((ANSICHAR*)Convert.Get())), Convert.Length());
|
|
base64String = FBase64::Encode(bytes);
|
|
}
|
|
|
|
void UFileFunctionsSocketClient::base64StringToString(FString& string, FString base64String) {
|
|
string.Empty();
|
|
TArray<uint8> bytes;
|
|
if (FBase64::Decode(*base64String, bytes)) {
|
|
bytes.Add(0x00);// null-terminator
|
|
char* Data = (char*)bytes.GetData();
|
|
string = FString(UTF8_TO_TCHAR(Data));
|
|
}
|
|
}
|
|
|
|
|
|
void UFileFunctionsSocketClient::bytesToBase64String(TArray<uint8> bytes, FString& base64String) {
|
|
base64String.Empty();
|
|
base64String = FBase64::Encode(bytes);
|
|
}
|
|
|
|
TArray<uint8> UFileFunctionsSocketClient::base64StringToBytes(FString base64String, bool& success) {
|
|
TArray<uint8> fileData;
|
|
if (base64String.Len() % 2 != 0 || base64String.Len() < 4) {
|
|
success = false;
|
|
return fileData;
|
|
}
|
|
success = FBase64::Decode(*base64String, fileData);
|
|
return fileData;
|
|
}
|
|
|
|
void UFileFunctionsSocketClient::fileToBase64String(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, bool& success, FString& base64String, FString& fileName) {
|
|
base64String.Empty();
|
|
fileName.Empty();
|
|
TArray<uint8> fileData;
|
|
if (!FFileHelper::LoadFileToArray(fileData, *getCleanDirectory(directoryType, filePath))) {
|
|
success = false;
|
|
return;
|
|
}
|
|
base64String = FBase64::Encode(fileData);
|
|
success = true;
|
|
}
|
|
|
|
bool UFileFunctionsSocketClient::fileExists(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath) {
|
|
return FPaths::FileExists(*getCleanDirectory(directoryType, filePath));
|
|
}
|
|
|
|
bool UFileFunctionsSocketClient::fileExistsAbsolutePath(FString filePath) {
|
|
return FPaths::FileExists(*filePath);
|
|
}
|
|
|
|
bool UFileFunctionsSocketClient::directoryExists(EFileFunctionsSocketClientDirectoryType directoryType, FString path) {
|
|
return FPaths::DirectoryExists(*getCleanDirectory(directoryType, path));
|
|
}
|
|
|
|
int64 UFileFunctionsSocketClient::fileSize(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath) {
|
|
return FPlatformFileManager::Get().GetPlatformFile().FileSize(*getCleanDirectory(directoryType, filePath));
|
|
}
|
|
|
|
int64 UFileFunctionsSocketClient::fileSizeAbsolutePath(FString filePath) {
|
|
return FPlatformFileManager::Get().GetPlatformFile().FileSize(*filePath);
|
|
}
|
|
|
|
bool UFileFunctionsSocketClient::deleteFile(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath) {
|
|
return FPlatformFileManager::Get().GetPlatformFile().DeleteFile(*getCleanDirectory(directoryType, filePath));
|
|
}
|
|
|
|
bool UFileFunctionsSocketClient::deleteFileAbsolutePath(FString filePath) {
|
|
return FPlatformFileManager::Get().GetPlatformFile().DeleteFile(*filePath);
|
|
}
|
|
|
|
|
|
bool UFileFunctionsSocketClient::deleteDirectory(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath) {
|
|
return FPlatformFileManager::Get().GetPlatformFile().DeleteDirectory(*getCleanDirectory(directoryType, filePath));
|
|
}
|
|
|
|
bool UFileFunctionsSocketClient::isReadOnly(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath) {
|
|
return FPlatformFileManager::Get().GetPlatformFile().IsReadOnly(*getCleanDirectory(directoryType, filePath));
|
|
}
|
|
|
|
bool UFileFunctionsSocketClient::moveFile(EFileFunctionsSocketClientDirectoryType directoryTypeTo, FString filePathTo, EFileFunctionsSocketClientDirectoryType directoryTypeFrom, FString filePathFrom) {
|
|
return FPlatformFileManager::Get().GetPlatformFile().MoveFile(*getCleanDirectory(directoryTypeTo, filePathTo), *getCleanDirectory(directoryTypeFrom, filePathFrom));
|
|
}
|
|
|
|
bool UFileFunctionsSocketClient::setReadOnly(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, bool bNewReadOnlyValue) {
|
|
return FPlatformFileManager::Get().GetPlatformFile().SetReadOnly(*getCleanDirectory(directoryType, filePath), bNewReadOnlyValue);
|
|
}
|
|
|
|
FDateTime UFileFunctionsSocketClient::getTimeStamp(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath) {
|
|
return FPlatformFileManager::Get().GetPlatformFile().GetTimeStamp(*getCleanDirectory(directoryType, filePath));
|
|
}
|
|
|
|
void UFileFunctionsSocketClient::setTimeStamp(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, FDateTime DateTime) {
|
|
FPlatformFileManager::Get().GetPlatformFile().SetTimeStamp(*getCleanDirectory(directoryType, filePath), DateTime);
|
|
}
|
|
|
|
FDateTime UFileFunctionsSocketClient::getAccessTimeStamp(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath) {
|
|
return FPlatformFileManager::Get().GetPlatformFile().GetAccessTimeStamp(*getCleanDirectory(directoryType, filePath));
|
|
}
|
|
|
|
FString UFileFunctionsSocketClient::getFilenameOnDisk(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath) {
|
|
return FPlatformFileManager::Get().GetPlatformFile().GetFilenameOnDisk(*getCleanDirectory(directoryType, filePath));
|
|
}
|
|
|
|
bool UFileFunctionsSocketClient::createDirectory(EFileFunctionsSocketClientDirectoryType directoryType, FString path) {
|
|
return FPlatformFileManager::Get().GetPlatformFile().CreateDirectory(*getCleanDirectory(directoryType, path));
|
|
}
|
|
|
|
void UFileFunctionsSocketClient::getAllFilesFromDirectory(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, int32& count, TArray<FString>& files, TArray<FString>& filePaths, FString fileType) {
|
|
if (filePath.Len() < 1) {
|
|
return;
|
|
}
|
|
files.Empty();
|
|
filePaths.Empty();
|
|
|
|
FString dir = getCleanDirectory(directoryType, filePath);
|
|
FPaths::NormalizeDirectoryName(filePath);
|
|
|
|
if (!FPaths::DirectoryExists(dir)) {
|
|
return;
|
|
}
|
|
IFileManager& FileManager = IFileManager::Get();
|
|
|
|
dir += "/" + fileType;
|
|
|
|
FileManager.FindFiles(files, *dir, true, false);
|
|
|
|
|
|
filePath += "/";
|
|
for (int32 i = 0; i < files.Num(); i++) {
|
|
filePaths.Add((filePath + files[i]));
|
|
//UE_LOG(LogTemp, Display, TEXT("->%s"), *files[i]);
|
|
}
|
|
count = files.Num();
|
|
}
|
|
|
|
FFileFunctionsSocketClientOpenFile UFileFunctionsSocketClient::openFile(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath){
|
|
|
|
FArchive* writer = IFileManager::Get().CreateFileWriter(*getCleanDirectory(directoryType, filePath), EFileWrite::FILEWRITE_Append);
|
|
FFileFunctionsSocketClientOpenFile file;
|
|
file.writer = writer;
|
|
return file;
|
|
}
|
|
|
|
int64 UFileFunctionsSocketClient::addBytesToFile(FFileFunctionsSocketClientOpenFile openFile, TArray<uint8> bytes){
|
|
//UE_LOG(LogTemp, Warning, TEXT("xxxxx WRITE: %i"), bytes.Num());
|
|
if (openFile.writer != nullptr) {
|
|
openFile.writer->Seek(openFile.writer->TotalSize());
|
|
openFile.writer->Serialize(bytes.GetData(), bytes.Num());
|
|
//openFile.writer->Flush();
|
|
return openFile.writer->TotalSize();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void UFileFunctionsSocketClient::closeFile(FFileFunctionsSocketClientOpenFile openFile){
|
|
if (openFile.writer != nullptr) {
|
|
openFile.writer->Close();
|
|
openFile.writer = nullptr;
|
|
}
|
|
}
|
|
|
|
|
|
bool UFileFunctionsSocketClient::encryptFileWithAES(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, FString newFileName, FString key, bool writeEncryptedFileSizeToFile){
|
|
|
|
if (filePath.IsEmpty() || newFileName.IsEmpty() || key.Len() != 32) {
|
|
UE_LOG(LogTemp, Error, TEXT("encryptFileWithAES: FilePath or newFileName empty or wrong key length. The key must consist of 32 ANSI compatible characters."));
|
|
return false;
|
|
}
|
|
|
|
FString dir = getCleanDirectory(directoryType, filePath);
|
|
FString fileName = FPaths::GetCleanFilename(dir);
|
|
int64 fileSize = FPlatformFileManager::Get().GetPlatformFile().FileSize(*dir);
|
|
|
|
TArray64<uint8> data;
|
|
if (!FFileHelper::LoadFileToArray(data, *dir)) {
|
|
UE_LOG(LogTemp, Error, TEXT("encryptFileWithAES: File could not be loaded: %s"),*dir);
|
|
return false;
|
|
}
|
|
|
|
const int64 encryptedFileSize = Align(data.Num(), FAES::AESBlockSize);
|
|
|
|
if (data.Num() < encryptedFileSize) {
|
|
data.AddUninitialized(encryptedFileSize - data.Num());
|
|
}
|
|
|
|
FAES::EncryptData(data.GetData(), encryptedFileSize, TCHAR_TO_ANSI(*key));
|
|
|
|
dir = dir.Replace(*fileName, *newFileName);
|
|
if (FPaths::FileExists(*dir)) {
|
|
FPlatformFileManager::Get().GetPlatformFile().DeleteFile(*dir);
|
|
}
|
|
|
|
FArchive* writer = IFileManager::Get().CreateFileWriter(*dir, EFileWrite::FILEWRITE_Append);
|
|
if (!writer) {
|
|
UE_LOG(LogTemp, Error, TEXT("encryptFileWithAES: File could not be saved: %s"), *dir);
|
|
data.Empty();
|
|
return false;
|
|
}
|
|
|
|
if (writeEncryptedFileSizeToFile) {
|
|
TArray<uint8> byteArray;
|
|
union {
|
|
int64 tmpVal;
|
|
uint8 tmpArray[8];
|
|
} u;
|
|
u.tmpVal = fileSize;
|
|
byteArray.AddZeroed(8);
|
|
|
|
FMemory::Memcpy(byteArray.GetData(), u.tmpArray, 8);
|
|
writer->Serialize(byteArray.GetData(), byteArray.Num());
|
|
byteArray.Empty();
|
|
}
|
|
|
|
writer->Serialize(data.GetData(), data.Num());
|
|
writer->Close();
|
|
delete writer;
|
|
|
|
data.Empty();
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
bool UFileFunctionsSocketClient::decryptFileWithAES(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, FString newFileName, FString key,
|
|
bool hasEncryptedFileSizeInFile, int64 originalFileLength){
|
|
|
|
if (filePath.IsEmpty() || newFileName.IsEmpty() || key.Len() != 32) {
|
|
UE_LOG(LogTemp, Error, TEXT("decryptFileWithAES: FilePath or newFileName empty or wrong key length. The key must consist of 32 ANSI compatible characters."));
|
|
return false;
|
|
}
|
|
|
|
FString dir = getCleanDirectory(directoryType, filePath);
|
|
FString fileName = FPaths::GetCleanFilename(dir);
|
|
int64 fileSize = FPlatformFileManager::Get().GetPlatformFile().FileSize(*dir);
|
|
|
|
FArchive* reader = IFileManager::Get().CreateFileReader(*dir);
|
|
if (!reader) {
|
|
UE_LOG(LogTemp, Error, TEXT("decryptFileWithAES: File could not be loaded: %s"), *dir);
|
|
return false;
|
|
}
|
|
|
|
if (hasEncryptedFileSizeInFile) {
|
|
TArray<uint8> bytes;
|
|
bytes.AddZeroed(8);
|
|
reader->Serialize(bytes.GetData(), bytes.Num());
|
|
FMemory::Memcpy(&originalFileLength, bytes.GetData(), 8);
|
|
bytes.Empty();
|
|
fileSize = fileSize-8;
|
|
}
|
|
|
|
if (fileSize < originalFileLength) {
|
|
originalFileLength = fileSize;
|
|
UE_LOG(LogTemp, Warning, TEXT("decryptFileWithAES: The encrypted file size is smaller than the original file size. File may be corrupted: %s"), *dir);
|
|
return false;
|
|
}
|
|
|
|
TArray64<uint8> data;
|
|
data.AddUninitialized(fileSize);
|
|
reader->Serialize(data.GetData(), data.Num());
|
|
reader->Close();
|
|
delete reader;
|
|
|
|
|
|
const int64 encryptedFileSize = Align(data.Num(), FAES::AESBlockSize);
|
|
if (data.Num() < encryptedFileSize) {
|
|
UE_LOG(LogTemp, Error, TEXT("decryptFileWithAES: Wrong data length. File could not be decrypted: %s"),*dir);
|
|
return false;
|
|
}
|
|
|
|
FAES::DecryptData(data.GetData(), encryptedFileSize, TCHAR_TO_ANSI(*key));
|
|
|
|
dir = dir.Replace(*fileName, *newFileName);
|
|
if (FPaths::FileExists(*dir)) {
|
|
FPlatformFileManager::Get().GetPlatformFile().DeleteFile(*dir);
|
|
}
|
|
|
|
FArchive* writer = IFileManager::Get().CreateFileWriter(*dir, EFileWrite::FILEWRITE_Append);
|
|
if (!writer) {
|
|
UE_LOG(LogTemp, Error, TEXT("encryptFileWithAES: File could not be saved: %s"), *dir);
|
|
data.Empty();
|
|
return false;
|
|
}
|
|
writer->Serialize(data.GetData(), originalFileLength);
|
|
writer->Close();
|
|
delete writer;
|
|
|
|
data.Empty();
|
|
return true;
|
|
}
|
|
|
|
FString UFileFunctionsSocketClient::encryptMessageWithAES(FString message, FString key) {
|
|
|
|
if (message.IsEmpty() || key.Len() != 32) {
|
|
UE_LOG(LogTemp, Error, TEXT("encryptMessageWithAES:Message empty or wrong key length. The key must consist of 32 ANSI compatible characters."));
|
|
return FString();
|
|
}
|
|
|
|
TArray<uint8> data = FStringToByteArray(message);
|
|
data.Add(0x00);// null-terminator
|
|
const int64 encryptedFileSize = Align(data.Num(), FAES::AESBlockSize);
|
|
|
|
if (data.Num() < encryptedFileSize){
|
|
data.AddUninitialized(encryptedFileSize-data.Num());
|
|
}
|
|
|
|
FAES::EncryptData(data.GetData(), encryptedFileSize, TCHAR_TO_ANSI(*key));
|
|
|
|
FString encryptedBase64String = FString();
|
|
bytesToBase64String(data, encryptedBase64String);
|
|
|
|
data.Empty();
|
|
|
|
return encryptedBase64String;
|
|
}
|
|
|
|
FString UFileFunctionsSocketClient::decryptMessageWithAES(FString message, FString key) {
|
|
if (message.IsEmpty() || key.Len() != 32) {
|
|
UE_LOG(LogTemp, Error, TEXT("decryptMessageFromAES: Message empty or wrong key length. The key must consist of 32 ANSI compatible characters."));
|
|
return FString();
|
|
}
|
|
|
|
bool success = false;
|
|
TArray<uint8> data = base64StringToBytes(message, success);
|
|
|
|
|
|
const int64 encryptedFileSize = Align(data.Num(), FAES::AESBlockSize);
|
|
if (data.Num() < encryptedFileSize) {
|
|
UE_LOG(LogTemp, Error, TEXT("decryptMessageFromAES: Wrong string length. Message could not be decrypted."));
|
|
return FString();
|
|
}
|
|
|
|
FAES::DecryptData(data.GetData(), encryptedFileSize, TCHAR_TO_ANSI(*key));
|
|
|
|
FString s = FString(UTF8_TO_TCHAR((char*)data.GetData()));
|
|
|
|
data.Empty();
|
|
|
|
return s;
|
|
}
|
|
|
|
|
|
TArray<uint8> UFileFunctionsSocketClient::FStringToByteArray(FString s) {
|
|
FTCHARToUTF8 Convert(*s);
|
|
TArray<uint8> data;
|
|
data.Append((uint8*)Convert.Get(), Convert.Length());
|
|
return data;
|
|
}
|
|
|
|
|
|
FString UFileFunctionsSocketClient::int64ToString(int64 Num) {
|
|
FString str = FString();
|
|
const TCHAR* DigitToChar = TEXT("9876543210123456789");
|
|
constexpr int64 ZeroDigitIndex = 9;
|
|
bool bIsNumberNegative = Num < 0;
|
|
const int64 TempBufferSize = 32; // 32 is big enough
|
|
TCHAR TempNum[TempBufferSize];
|
|
int64 TempAt = TempBufferSize; // fill the temp string from the top down.
|
|
|
|
// Convert to string assuming base ten.
|
|
do
|
|
{
|
|
TempNum[--TempAt] = DigitToChar[ZeroDigitIndex + (Num % 10)];
|
|
Num /= 10;
|
|
} while (Num);
|
|
|
|
if (bIsNumberNegative)
|
|
{
|
|
TempNum[--TempAt] = TEXT('-');
|
|
}
|
|
|
|
const TCHAR* CharPtr = TempNum + TempAt;
|
|
const int64 NumChars = TempBufferSize - TempAt;
|
|
str.Append(CharPtr, NumChars);
|
|
|
|
return str;
|
|
}
|
|
|
|
|
|
|
|
|
|
void UFileFunctionsSocketClient::readBytesFromFileInPartsAsync(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, int32 bufferSize, float delayBetweenReadsInSeconds) {
|
|
UFileFunctionsSocketClient::getFileFunctionsSocketClientTarget()->readBytesFromFileInPartsAsyncInternal(directoryType, filePath, bufferSize, delayBetweenReadsInSeconds);
|
|
}
|
|
|
|
void UFileFunctionsSocketClient::readBytesFromFileInPartsAsyncInternal(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, int32 bufferSize, float delayBetweenReadsInSeconds) {
|
|
|
|
FString dir = UFileFunctionsSocketClient::getCleanDirectory(directoryType, filePath);
|
|
|
|
if (readFileInPartsThreads.Find(*dir) != nullptr) {
|
|
UE_LOG(LogTemp, Warning, TEXT("ReadBytesFromFileInPartsAsync: %s is being read already. Operation canceled."), *dir);
|
|
return;
|
|
}
|
|
|
|
FReadFileInPartsSocketClientThread* readThread = new FReadFileInPartsSocketClientThread(dir, bufferSize, delayBetweenReadsInSeconds);
|
|
readFileInPartsThreads.Add(dir, readThread);
|
|
}
|
|
|
|
void UFileFunctionsSocketClient::cancelReadBytesFromFileInParts(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath) {
|
|
UFileFunctionsSocketClient::getFileFunctionsSocketClientTarget()->cancelReadBytesFromFileInPartsInternal(directoryType, filePath);
|
|
}
|
|
|
|
void UFileFunctionsSocketClient::cancelReadBytesFromFileInPartsInternal(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath) {
|
|
FString dir = UFileFunctionsSocketClient::getCleanDirectory(directoryType, filePath);
|
|
|
|
if (readFileInPartsThreads.Find(*dir) != nullptr) {
|
|
(*readFileInPartsThreads.Find(*dir))->stopThread();
|
|
}
|
|
}
|
|
|
|
void UFileFunctionsSocketClient::cleanReadBytesFromFileInParts(FString cleanDir) {
|
|
if (readFileInPartsThreads.Find(*cleanDir) != nullptr) {
|
|
readFileInPartsThreads.Remove(*cleanDir);
|
|
}
|
|
}
|
|
|
|
//void UFileFunctionsSocketClient::changeDelayInBytesFromFileInParts(EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, float delayBetweenReadsInSeconds) {
|
|
// FString dir = UFileFunctionsSocketClient::getCleanDirectory(directoryType, filePath);
|
|
//
|
|
// if (readFileInPartsThreads.Find(*dir) != nullptr) {
|
|
// (*readFileInPartsThreads.Find(*dir))->setDelayBetweenReadsInSeconds(delayBetweenReadsInSeconds);
|
|
// }
|
|
//}
|