AuroraRuntime/Source/Logging/Sinks/StreamSink.cpp
2024-04-10 11:05:00 +01:00

120 lines
3.1 KiB
C++

/***
Copyright (C) 2024 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: StreamSink.cpp
Date: 2024-4-10
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "StreamSink.hpp"
namespace Aurora::Logging::Sinks
{
StreamSink::StreamSink(const AuSPtr<Aurora::IO::IStreamWriter> &pPipe,
bool bText,
bool bLengthPrefixed) :
pPipe_(pPipe),
bText_(bText),
bLengthPrefixed_(bLengthPrefixed)
{
}
void StreamSink::OnMessageBlocking(AuUInt8 uLevel, const ConsoleMessage &msg)
{
AU_LOCK_GUARD(this->logMutex_);
auto startOffset = this->logBuffer_.GetWriteOffset();
if (this->bLengthPrefixed_)
{
if (this->logBuffer_.readPtr != this->logBuffer_.base)
{
SysPushErrorConcurrentAborted();
return;
}
if (this->logBuffer_.base == this->logBuffer_.writePtr)
{
this->logBuffer_.Write<AuUInt32>(0);
}
}
if (this->bText_)
{
auto str = this->FormatMessageHelper(uLevel, msg, false, true, false);
this->logBuffer_.Write(str.data(), str.size());
#if defined(AURORA_IS_MODERNNT_DERIVED)
this->logBuffer_.Write("\r\n", 2);
#else
this->logBuffer_.Write("\n", 1);
#endif
}
else
{
msg.Write(this->logBuffer_);
}
if (!this->logBuffer_)
{
this->logBuffer_.writePtr = this->logBuffer_.base + startOffset;
}
}
bool StreamSink::OnMessageNonblocking(AuUInt8 level, const ConsoleMessage &msg)
{
return true;
}
void StreamSink::OnFlush()
{
AU_LOCK_GUARD(this->logMutex_);
if (!this->logBuffer_.RemainingBytes())
{
return;
}
if (this->bLengthPrefixed_ &&
this->logBuffer_.readPtr == this->logBuffer_.base)
{
auto len = this->logBuffer_.writePtr - this->logBuffer_.base;
this->logBuffer_.writePtr = this->logBuffer_.base;
this->logBuffer_.Write<AuUInt32>(len);
this->logBuffer_.writePtr = this->logBuffer_.base + len;
}
AuUInt uWritten {};
this->pPipe_->Write(AuMemoryViewStreamRead(this->logBuffer_, uWritten));
this->logBuffer_.readPtr += uWritten;
if (this->logBuffer_.readPtr == this->logBuffer_.writePtr)
{
this->logBuffer_.ResetPositions();
}
this->pPipe_->Flush();
}
void NewStreamSinkRelease(IFormattedSink *pLogger)
{
AuSafeDelete<StreamSink *>(pLogger);
}
IFormattedSink *NewStreamSinkNew(const AuSPtr<Aurora::IO::IStreamWriter> &pPipe,
bool bText,
bool bLengthPrefixed)
{
if (!pPipe)
{
SysPushErrorArg();
return {};
}
return _new StreamSink(pPipe,
bText,
bLengthPrefixed);
}
}