Line data Source code
1 : // 2 : // Copyright 2024 OpenModelViewer Authors 3 : // 4 : // Licensed under the Apache License, Version 2.0 (the "License"); 5 : // you may not use this file except in compliance with the License. 6 : // You may obtain a copy of the License at 7 : // 8 : // http://www.apache.org/licenses/LICENSE-2.0 9 : // 10 : // Unless required by applicable law or agreed to in writing, software 11 : // distributed under the License is distributed on an "AS IS" BASIS, 12 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 : // See the License for the specific language governing permissions and 14 : // limitations under the License. 15 : // 16 : 17 : #include "openmodelviewer/core/log/sinks/file_sink.hpp" 18 : #include "openmodelviewer/core/io.hpp" 19 : 20 : #include <stdexcept> 21 : 22 : using namespace openmodelviewer::core::io; 23 : 24 : namespace openmodelviewer::core::log::sinks 25 : { 26 7 : FileSink::FileSink(const std::filesystem::path& filePath, std::string_view format, bool truncate, bool autoFlush) : 27 7 : m_format(format), 28 14 : m_autoFlush(autoFlush) 29 : { 30 7 : if (!rotate(filePath, truncate)) 31 : { 32 0 : throw std::runtime_error("FileSink error: Failed to open or create file '" + filePath.string() + "'"); 33 : } 34 7 : } 35 : 36 0 : const std::filesystem::path& FileSink::path() const noexcept 37 : { 38 0 : return m_path; 39 : } 40 : 41 0 : const std::string& FileSink::format() const noexcept 42 : { 43 0 : return m_format; 44 : } 45 : 46 9 : bool FileSink::reopen() 47 : { 48 9 : std::lock_guard<std::mutex> lock(m_fileMutex); 49 : 50 9 : if (m_fileStream.is_open()) 51 : { 52 1 : m_fileStream.close(); // flush() implicite 53 : } 54 : 55 18 : return (OFile::openOutFileStream(m_path, m_openMode, m_fileStream) == IOResult::Success); 56 9 : } 57 : 58 8 : bool FileSink::rotate(const std::filesystem::path& filePath, bool truncate) 59 : { 60 8 : m_openMode = truncate ? FileOpenMode::OverwriteAlways : FileOpenMode::AppendAlways; 61 8 : m_path = filePath; 62 : 63 8 : return this->reopen(); // contient déjà le lock 64 : } 65 : 66 10 : void FileSink::close() 67 : { 68 10 : std::lock_guard<std::mutex> lock(m_fileMutex); 69 : 70 10 : if (m_fileStream.is_open()) 71 : { 72 8 : m_fileStream.close(); 73 : } 74 10 : } 75 : 76 2 : bool FileSink::isOpen() const noexcept 77 : { 78 2 : std::lock_guard<std::mutex> lock(m_fileMutex); 79 2 : return m_fileStream.is_open(); 80 2 : } 81 : 82 8 : void FileSink::log(const LogEntry& entry) 83 : { 84 8 : std::lock_guard<std::mutex> lock(m_fileMutex); 85 8 : m_fileStream << entry.format(m_format); 86 : 87 8 : if (!m_fileStream) 88 : { 89 0 : this->close(); 90 0 : return; 91 : } 92 : 93 8 : if (m_autoFlush) 94 : { 95 1 : m_fileStream.flush(); 96 : } 97 8 : } 98 : 99 5 : void FileSink::flush() 100 : { 101 5 : std::lock_guard<std::mutex> lock(m_fileMutex); 102 : 103 5 : if (m_fileStream.is_open()) 104 : { 105 4 : m_fileStream.flush(); 106 : } 107 5 : } 108 : 109 7 : FileSink::~FileSink() 110 : { 111 7 : this->close(); 112 7 : } 113 : }