Here’s a first attempt :
//.h
UFUNCTION(BlueprintCallable)
static int32 LZ4_Compress(const FString& Input, FString& Result);
//.cpp
#include "TraceLog/Private/Trace/LZ4/lz4.c.inl"
int32 UMyLib::LZ4_Compress(const FString& Input, FString& Result)
{
TArray<TCHAR> TCharArray = Input.GetCharArray();
TArray<uint8> Bytes;
Bytes.Reserve(TCharArray.Num() * sizeof(TCHAR));
for (int i = 0; i < Input.Len(); i++)
{
uint8 CharBytes[sizeof(TCHAR)];
FMemory::Memcpy(&CharBytes[0], &TCharArray[i], sizeof(TCHAR));
for (int CharIdx = 0; CharIdx < sizeof(TCHAR); CharIdx++)
{
Bytes.Add(CharBytes[CharIdx]);
}
}
char* src = reinterpret_cast<char*>(Bytes.GetData());
int32 inputSize = Bytes.Num();
int bound = LZ4_compressBound(inputSize);
char* dst = (char*)FMemory::Malloc(bound + 1);
int32 written = LZ4_compress_default(src, dst, inputSize, bound);
dst[written] = '\0';
Result = dst;
FMemory::Free(dst);
return written;
}
Note that the compressed buffer can contain zeroes (string terminators) so it is probably a very bad idea to store the result back in a FString.
Unfortunately blueprints do not support things like uint8* or TArray<uint8> so it’s gonna be difficult to send such a binary buffer over the network via standard RPCs.
I can think of two possible approaches :
-
Wrap results in a custom USTRUCT, store the buffer natively (it won’t be visible to BP, but you’ll still be able to pass the struct around), and write custom serializer for networking.
-
Convert the result buffer into a
TArray<int32>, by merging bytes 4 by 4, so you can actually use it in blueprints.