/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: IPCSink.cpp Date: 2022-6-16 Author: Reece ***/ #include #include "IPCSink.hpp" namespace Aurora::Logging::Sinks { IPCSink::IPCSink(const AuSPtr &pipe, bool lengthPrefixed) : pipe_(pipe), lengthPrefixed_(lengthPrefixed) { } bool IPCSink::Init() { this->logMutex_ = AuThreadPrimitives::MutexUnique(); return static_cast(this->pipe_) && static_cast(this->logMutex_); } AuSPtr IPCSink::ToPipe() { return this->pipe_; } void IPCSink::OnMessageBlocking(AuUInt8 level, const ConsoleMessage &msg) { AU_LOCK_GUARD(this->logMutex_); auto str = msg.ToPersistentString(); auto startOffset = this->logBuffer_.GetWriteOffset(); if (this->lengthPrefixed_) { if (this->logBuffer_.base == this->logBuffer_.writePtr) { this->logBuffer_.Write(0); } } msg.Write(this->logBuffer_); if (!this->logBuffer_) { this->logBuffer_.writePtr = this->logBuffer_.base + startOffset; } } bool IPCSink::OnMessageNonblocking(AuUInt8 level, const ConsoleMessage &msg) { return true; } void IPCSink::OnFlush() { if (!this->logMutex_) { return; } AU_LOCK_GUARD(this->logMutex_); if (!this->logBuffer_.RemainingBytes()) { return; } auto len = this->logBuffer_.writePtr - this->logBuffer_.base; if (this->lengthPrefixed_) { this->logBuffer_.writePtr = this->logBuffer_.base; this->logBuffer_.Write(len); } this->pipe_->Write(AuMemoryViewStreamRead(this->logBuffer_.base, this->logBuffer_.base + len)); this->logBuffer_.ResetPositions(); } IIPCLogger *NewIPCSinkNew(const AuString &str, bool lengthPrefixed) { auto pipe = AuIPC::ImportPipe(str); if (!pipe) { return nullptr; } auto logger = _new IPCSink(pipe, lengthPrefixed); if (!logger) { return nullptr; } if (!logger->Init()) { return nullptr; } return logger; } void NewIPCSinkRelease(IIPCLogger *logger) { AuSafeDelete(logger); } }