TArray with offset to FString

Hey community,

Please can you help with a little c++ magic?

My issue is I have a TArray buffer arriving to my FSocket,
Retrieving int,uint, bool, ushort are all perfectly fine but I’m trying to retrieve an FString from the array.

I was hoping to use this from

/Rama's String From Binary Array
//This function requires 
//		#include <string>
FString AYourClass::StringFromBinaryArray(const TArray<uint8>& BinaryArray)
{
	//Create a string from a byte array!
	const std::string cstr( reinterpret_cast<const char*>(BinaryArray.GetData()), BinaryArray.Num() );
 
	//FString can take in the c_str() of a std::string
	return FString(cstr.c_str());
}

My problem here is that my BinaryArray has more than just a string is contain various other paramter data.

How would I be able to create some function that would take the TArray with an offset and a length to create a new returnable FString?

I will continue to try various options and post a response if I manage to achieve this goal.

Cheers.

ok I figured this out for those who need this I’ve posted it below

//String From Binary Array (based on's original)
//This function requires 
//		#include <string>
FString ANDGSocket::StringFromBinaryArray(const TArray<uint8> BinaryArray, int offset, uint16 strLng)
{
	//Create a string from a byte array!
	std::string cstr(reinterpret_cast<const char*>(&BinaryArray[offset]), strLng);
	return FString(cstr.c_str());
}

This is now working and I would like to acknowledge for the original code.

How does this compare with using a BinaryArchive?

binaryArchive << myString;

Using:

class FBufferArchive : public FMemoryWriter, public TArray
class FMemoryReader final : public FMemoryArchive
class FArrayReader final : public FMemoryArchive, public TArray<uint8>

This allows you to just use an FArchive in any low level code and potentially share read and write code. The other pro is cleaner looking high level code but I’m interested any counter arguments if they exist.

For instance how does memory abuse compare? I don’t use std::string’s much / ever but I’d assume a copy to the cstr variable, then a copy to the FString return value and possibly a copy again in the calling code - all non trivial operations.

This is what I’m using…


  1. To read:

FString contents;
			FFileHelper::BufferToString(contents, rData.GetData(), rData.Num());

  1. To write (a subset of FFileHelper::SaveStringToFile):

FBufferArchive asArray;

const TCHAR* StrPtr = *rData;
bool SaveAsUnicode = !FCString::IsPureAnsi(StrPtr);
if (SaveAsUnicode)
{
	UCS2CHAR BOM = UNICODE_BOM;
	asArray.Serialize(&BOM, sizeof(UCS2CHAR));

	auto Src = StringCast<UCS2CHAR>(StrPtr, rData.Len());
	asArray.Serialize((UCS2CHAR*)Src.Get(), Src.Length() * sizeof(UCS2CHAR));
}
else
{
	auto Src = StringCast<ANSICHAR>(StrPtr, rData.Len());
	asArray.Serialize((ANSICHAR*)Src.Get(), Src.Length() * sizeof(ANSICHAR));
}

asArray

asArray can be written to file / http etc.


Obviously bulkier code but it seems to be working (I’m sending string files to and from s3 / dynamodb / ec2 via HTTP requests) you you’re just going to wrap it in your own API.

With the above code memory allocations are fairly sensible (a single allocation in each case).
*EDIT: Two allocations, StringCast does it’s own allocation for larger (>128 character) conversions.

Minor gripe about FFileHelpers - it would be nice to have StringToBuffer to complement BufferToString!