Files
UnrealEngine/Engine/Source/Programs/TraceAnalyzer/Private/TextSerializer.cpp
2025-05-18 13:04:45 +08:00

265 lines
6.1 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "TextSerializer.h"
#include "HAL/UnrealMemory.h"
#include "Math/NumericLimits.h"
#include "Misc/CString.h"
namespace UE
{
namespace TraceAnalyzer
{
////////////////////////////////////////////////////////////////////////////////////////////////////
// FTextSerializer
////////////////////////////////////////////////////////////////////////////////////////////////////
FTextSerializer::FTextSerializer()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
FTextSerializer::~FTextSerializer()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void FTextSerializer::WriteValueInt64Auto(int64 Value)
{
constexpr int64 MinInt64Hex = -99'999'999;
constexpr int64 MaxInt64Hex = 999'999'999;
if (Value < MinInt64Hex)
{
if (Value == MIN_int64)
{
Append("MIN_int64");
}
else
{
AppendChar('-');
WriteValueHex64(uint64(-Value));
}
}
else if (Value > MaxInt64Hex)
{
if (Value == MAX_int64)
{
Append("MAX_int64");
}
else
{
WriteValueHex64(uint64(Value));
}
}
else
{
WriteValueInt64(Value);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void FTextSerializer::WriteValueUInt64Auto(uint64 Value)
{
constexpr uint64 MaxUInt64Hex = 999'999'999;
if (Value > MaxUInt64Hex)
{
if (Value == MAX_uint64)
{
Append("MAX_uint64");
}
else
{
WriteValueHex64(Value);
}
}
else
{
WriteValueUInt64(Value);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void FTextSerializer::WriteValueBinary(const void* Data, uint32 Size)
{
AppendChar('<');
const uint32 MaxNumElements = 100;
const uint8* Src = (const uint8*)Data;
for (uint32 Index = 0; Index < Size; ++Index, ++Src)
{
Appendf("%02X", *Src);
if (Index == MaxNumElements)
{
if (Size != MaxNumElements)
{
Append("...");
}
break;
}
}
if (Size == 1)
{
Append(" - 1 byte>");
}
else
{
Appendf(" - %d bytes>", Size);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// FStdoutTextSerializer
////////////////////////////////////////////////////////////////////////////////////////////////////
FStdoutTextSerializer::FStdoutTextSerializer()
{
#if UE_TRACE_ANALYSIS_DEBUG && (UE_TRACE_ANALYSIS_DEBUG_LOG_IMPL <= 2) && (UE_TRACE_ANALYSIS_DEBUG_LEVEL >= 2)
bWriteEventHeader = false;
#endif
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void FStdoutTextSerializer::AppendChar(const ANSICHAR Value)
{
printf("%c", Value);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void FStdoutTextSerializer::Append(const ANSICHAR* Text, int32 Len)
{
if (Len > 0)
{
printf("%.*s", Len, Text);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void FStdoutTextSerializer::Append(const ANSICHAR* Text)
{
printf("%s", Text);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void FStdoutTextSerializer::Appendf(const char* Format, ...)
{
va_list ArgPtr;
va_start(ArgPtr, Format);
vprintf(Format, ArgPtr);
va_end(ArgPtr);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
bool FStdoutTextSerializer::Commit()
{
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// FFileTextSerializer
////////////////////////////////////////////////////////////////////////////////////////////////////
FFileTextSerializer::FFileTextSerializer(FileHandle InHandle)
: Handle(InHandle)
{
Buffer = new uint8[BufferSize];
check(Buffer);
FormatBuffer = new uint8[FormatBufferSize];
check(FormatBuffer);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
FFileTextSerializer::~FFileTextSerializer()
{
delete[] FormatBuffer;
delete[] Buffer;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void FFileTextSerializer::AppendChar(const ANSICHAR Value)
{
*(char*)(GetPointer(sizeof(char))) = Value;
Used += sizeof(char);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void FFileTextSerializer::Append(const ANSICHAR* Text, int32 Len)
{
if (Len > 0)
{
ANSICHAR* Buff = (ANSICHAR*)GetPointer(Len * sizeof(ANSICHAR));
check(Buff);
FMemory::Memcpy(Buff, Text, Len * sizeof(ANSICHAR));
Used += Len * sizeof(ANSICHAR);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void FFileTextSerializer::Append(const ANSICHAR* Text)
{
int32 Len = FCStringAnsi::Strlen(Text);
Append(Text, Len);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void FFileTextSerializer::Appendf(const char* Format, ...)
{
va_list ArgPtr;
va_start(ArgPtr, Format);
const int32 Len = FCStringAnsi::GetVarArgs((ANSICHAR*)FormatBuffer, FormatBufferSize / sizeof(ANSICHAR), Format, ArgPtr);
va_end(ArgPtr);
check(Len >= 0);
Append((ANSICHAR*)FormatBuffer, Len);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
bool FFileTextSerializer::Commit()
{
return GetPointer(BufferSize) != nullptr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void* FFileTextSerializer::GetPointer(uint32 RequiredSize)
{
if (RequiredSize > BufferSize)
{
return nullptr;
}
uint32 NextUsed = Used + RequiredSize;
if (NextUsed > BufferSize)
{
int BytesOut = FileWrite(Handle, Buffer, Used);
if (BytesOut < 0 || BytesOut != Used)
{
return nullptr;
}
Used = 0;
}
return (uint8*)Buffer + Used;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
} // namespace TraceAnalyzer
} // namespace UE