/*** Copyright (C) 2024 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: StreamSink.cpp Date: 2024-4-10 Author: Reece ***/ #include #include "StreamSink.hpp" namespace Aurora::Logging::Sinks { StreamSink::StreamSink(const AuSPtr &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(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(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(pLogger); } IFormattedSink *NewStreamSinkNew(const AuSPtr &pPipe, bool bText, bool bLengthPrefixed) { if (!pPipe) { SysPushErrorArg(); return {}; } return _new StreamSink(pPipe, bText, bLengthPrefixed); } }