/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: FileSink.cpp Date: 2022-1-24 Author: Reece ***/ #include #include "FileSink.hpp" namespace Aurora::Logging::Sinks { FIOSink::FIOSink(const AuString &path, bool binary) : path_(path), binary_(binary) { } bool FIOSink::Init() { this->logMutex_ = AuThreadPrimitives::MutexUnique(); this->file_ = AuIOFS::OpenWriteUnique(this->path_); return static_cast(this->file_) && static_cast(this->logMutex_); } void FIOSink::OnMessageBlocking(AuUInt8 level, const ConsoleMessage &msg) { AU_LOCK_GUARD(this->logMutex_); auto str = msg.ToPersistentString(); auto startOffset = this->logBuffer_.GetWriteOffset(); if (this->binary_) { msg.Write(this->logBuffer_); } else { this->logBuffer_.reserve(this->logBuffer_.size() + str.size() + 2); 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 } if (!this->logBuffer_) { this->logBuffer_.writePtr = this->logBuffer_.base + startOffset; } } bool FIOSink::OnMessageNonblocking(AuUInt8 level, const ConsoleMessage &msg) { return true; } void FIOSink::OnFlush() { if (!this->logMutex_) { return; } AU_LOCK_GUARD(this->logMutex_); if (!this->logBuffer_.RemainingBytes()) { return; } this->file_->Write(AuMemoryViewStreamRead(this->logBuffer_)); this->logBuffer_.ResetPositions(); } IBasicSink *NewFileSinkNew(const AuString &str, bool binary) { try { auto logger = _new FIOSink(str, binary); if (!logger) { return nullptr; } if (!logger->Init()) { return nullptr; } return logger; } catch (...) { return {}; } } void NewFileSinkRelease(IBasicSink *logger) { AuSafeDelete(logger); } }