1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-07 19:18:19 +02:00
Beef/BeefySysLib/util/MemLogger.cpp
2025-04-01 15:37:03 -04:00

161 lines
3.6 KiB
C++

#include "MemLogger.h"
USING_NS_BF;
struct MemLogger_Header
{
public:
int mHead;
int mTail;
int mSize;
};
MemLogger::MemLogger()
{
mFileMap = NULL;
mMemBuffer = NULL;
mBufferSize = 0;
mTotalWriteSize = 0;
}
MemLogger::~MemLogger()
{
if (mMemBuffer != NULL)
::UnmapViewOfFile(mMemBuffer);
if (mFileMap != NULL)
::CloseHandle(mFileMap);
}
void MemLogger::Write(const void* ptr, int size)
{
if (mMemBuffer == NULL)
return;
if (size == 0)
return;
int dataSize = mBufferSize - sizeof(MemLogger_Header);
void* dataPtr = (uint8*)mMemBuffer + sizeof(MemLogger_Header);
MemLogger_Header* header = (MemLogger_Header*)mMemBuffer;
bool wasWrapped = header->mHead < header->mTail;
int writeSize = BF_MIN(size, dataSize - header->mHead);
memcpy((char*)dataPtr + header->mHead, ptr, writeSize);
size -= writeSize;
header->mHead += writeSize;
while (header->mHead >= dataSize)
header->mHead -= dataSize;
if (size > 0)
{
int writeSize2 = BF_MIN(size, dataSize - header->mHead);
memcpy((char*)dataPtr + header->mHead, (char*)ptr + writeSize, writeSize2);
header->mHead += writeSize2;
while (header->mHead >= dataSize)
header->mHead -= dataSize;
}
mTotalWriteSize += writeSize;
if (mTotalWriteSize >= dataSize)
{
header->mTail = header->mHead + 1;
if (header->mTail > dataSize)
header->mTail -= dataSize;
}
}
bool Beefy::MemLogger::Create(const StringImpl& memName, int size)
{
String sharedName = "MemLogger_" + memName;
HANDLE hMapFile = CreateFileMappingA(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
size, // maximum object size (low-order DWORD)
sharedName.c_str()); // name of mapping object
if (hMapFile == NULL)
return false;
mMemBuffer = MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
size);
if (mMemBuffer == NULL)
return false;
mBufferSize = size;
MemLogger_Header* header = (MemLogger_Header*)mMemBuffer;
header->mHead = 0;
header->mTail = 0;
header->mSize = size;
return true;
}
bool Beefy::MemLogger::Get(const StringImpl& memName, String& outStr)
{
String sharedName = "MemLogger_" + memName;
HANDLE hMapFile = ::OpenFileMappingA(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, sharedName.c_str());
if (hMapFile == NULL)
return false;
void* memPtr = MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
sizeof(MemLogger_Header));
MemLogger_Header* header = (MemLogger_Header*)(memPtr);
int size = header->mSize;
UnmapViewOfFile(memPtr);
memPtr = MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
size);
if (memPtr == NULL)
return false;
::CloseHandle(hMapFile);
header = (MemLogger_Header*)(memPtr);
int dataSize = header->mSize - sizeof(MemLogger_Header);
void* dataPtr = (uint8*)memPtr + sizeof(MemLogger_Header);
if (header->mHead >= header->mTail)
{
// Not wrapped around
outStr.Insert(outStr.mLength, (char*)dataPtr + header->mTail, header->mHead - header->mTail);
}
else
{
outStr.Insert(outStr.mLength, (char*)dataPtr + header->mTail, dataSize - header->mTail);
outStr.Insert(outStr.mLength, (char*)dataPtr, header->mHead);
}
return true;
}
void Beefy::MemLogger::Log(const char* fmt ...)
{
if (mMemBuffer == NULL)
return;
StringT<4096> str;
va_list argList;
va_start(argList, fmt);
vformat(str, fmt, argList);
va_end(argList);
Write(str.c_str(), str.mLength);
}