/*---------------------------------------------------------------------------Open Asset Import Library (assimp)---------------------------------------------------------------------------Copyright (c) 2006-2022, assimp teamAll rights reserved.Redistribution and use of this software in source and binary forms,with or without modification, are permitted provided that the followingconditions are met:* Redistributions of source code must retain the abovecopyright notice, this list of conditions and thefollowing disclaimer.* Redistributions in binary form must reproduce the abovecopyright notice, this list of conditions and thefollowing disclaimer in the documentation and/or othermaterials provided with the distribution.* Neither the name of the assimp team, nor the names of itscontributors may be used to endorse or promote productsderived from this software without specific priorwritten permission of the assimp team.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOTLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANYTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USEOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.---------------------------------------------------------------------------*//** @file DefaultLogger.cpp* @brief Implementation of DefaultLogger (and Logger)*/// Default log streams#include "FileLogStream.h"#include "StdOStreamLogStream.h"#include "Win32DebugLogStream.h"#include <assimp/StringUtils.h>#include <assimp/DefaultIOSystem.h>#include <assimp/ai_assert.h>#include <stdio.h>#include <assimp/DefaultLogger.hpp>#include <assimp/NullLogger.hpp>#include <iostream>#ifndef ASSIMP_BUILD_SINGLETHREADED#include <mutex>#include <thread>std::mutex loggerMutex;#endifnamespace Assimp {// ----------------------------------------------------------------------------------NullLogger DefaultLogger::s_pNullLogger;Logger *DefaultLogger::m_pLogger = &DefaultLogger::s_pNullLogger;static const unsigned int SeverityAll = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;// ----------------------------------------------------------------------------------// Represents a log-stream + its error severitystruct LogStreamInfo {unsigned int m_uiErrorSeverity;LogStream *m_pStream;// ConstructorLogStreamInfo(unsigned int uiErrorSev, LogStream *pStream) :m_uiErrorSeverity(uiErrorSev),m_pStream(pStream) {// empty}// Destructor~LogStreamInfo() {delete m_pStream;}};// ----------------------------------------------------------------------------------// Construct a default log streamLogStream *LogStream::createDefaultStream(aiDefaultLogStream streams,const char *name /*= "AssimpLog.txt"*/,IOSystem *io /*= nullptr*/) {switch (streams) {// This is a platform-specific featurecase aiDefaultLogStream_DEBUGGER:#ifdef WIN32return new Win32DebugLogStream();#elsereturn nullptr;#endif// Platform-independent default streamscase aiDefaultLogStream_STDERR:return new StdOStreamLogStream(std::cerr);case aiDefaultLogStream_STDOUT:return new StdOStreamLogStream(std::cout);case aiDefaultLogStream_FILE:return (name && *name ? new FileLogStream(name, io) : nullptr);default:// We don't know this default log stream, so raise an assertionai_assert(false);};// For compilers without dead code path detectionreturn nullptr;}// ----------------------------------------------------------------------------------// Creates the only singleton instanceLogger *DefaultLogger::create(const char *name /*= "AssimpLog.txt"*/,LogSeverity severity /*= NORMAL*/,unsigned int defStreams /*= aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE*/,IOSystem *io /*= nullptr*/) {// enter the mutex here to avoid concurrency problems#ifndef ASSIMP_BUILD_SINGLETHREADEDstd::lock_guard<std::mutex> lock(loggerMutex);#endifif (m_pLogger && !isNullLogger()) {delete m_pLogger;}m_pLogger = new DefaultLogger(severity);// Attach default log streams// Stream the log to the MSVC debugger?if (defStreams & aiDefaultLogStream_DEBUGGER) {m_pLogger->attachStream(LogStream::createDefaultStream(aiDefaultLogStream_DEBUGGER));}// Stream the log to COUT?if (defStreams & aiDefaultLogStream_STDOUT) {m_pLogger->attachStream(LogStream::createDefaultStream(aiDefaultLogStream_STDOUT));}// Stream the log to CERR?if (defStreams & aiDefaultLogStream_STDERR) {m_pLogger->attachStream(LogStream::createDefaultStream(aiDefaultLogStream_STDERR));}// Stream the log to a fileif (defStreams & aiDefaultLogStream_FILE && name && *name) {m_pLogger->attachStream(LogStream::createDefaultStream(aiDefaultLogStream_FILE, name, io));}return m_pLogger;}// ----------------------------------------------------------------------------------void Logger::debug(const char *message) {// SECURITY FIX: otherwise it's easy to produce overruns since// sometimes importers will include data from the input file// (i.e. node names) in their messages.if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {return OnDebug("<fixme: long message discarded>");}return OnDebug(message);}// ----------------------------------------------------------------------------------void Logger::verboseDebug(const char *message) {// SECURITY FIX: see aboveif (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {return OnVerboseDebug("<fixme: long message discarded>");}return OnVerboseDebug(message);}// ----------------------------------------------------------------------------------void Logger::info(const char *message) {// SECURITY FIX: see aboveif (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {return OnInfo("<fixme: long message discarded>");}return OnInfo(message);}// ----------------------------------------------------------------------------------void Logger::warn(const char *message) {// SECURITY FIX: see aboveif (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {return OnWarn("<fixme: long message discarded>");}return OnWarn(message);}// ----------------------------------------------------------------------------------void Logger::error(const char *message) {// SECURITY FIX: see aboveif (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {return OnError("<fixme: long message discarded>");}return OnError(message);}// ----------------------------------------------------------------------------------void DefaultLogger::set(Logger *logger) {// enter the mutex here to avoid concurrency problems#ifndef ASSIMP_BUILD_SINGLETHREADEDstd::lock_guard<std::mutex> lock(loggerMutex);#endifif (nullptr == logger) {logger = &s_pNullLogger;}if (nullptr != m_pLogger && !isNullLogger()) {delete m_pLogger;}DefaultLogger::m_pLogger = logger;}// ----------------------------------------------------------------------------------bool DefaultLogger::isNullLogger() {return m_pLogger == &s_pNullLogger;}// ----------------------------------------------------------------------------------Logger *DefaultLogger::get() {return m_pLogger;}// ----------------------------------------------------------------------------------// Kills the only instancevoid DefaultLogger::kill() {// enter the mutex here to avoid concurrency problems#ifndef ASSIMP_BUILD_SINGLETHREADEDstd::lock_guard<std::mutex> lock(loggerMutex);#endifif (m_pLogger == &s_pNullLogger) {return;}delete m_pLogger;m_pLogger = &s_pNullLogger;}// ----------------------------------------------------------------------------------// Debug messagevoid DefaultLogger::OnDebug(const char *message) {if (m_Severity < Logger::DEBUGGING) {return;}static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;char msg[Size];ai_snprintf(msg, Size, "Debug, T%u: %s", GetThreadID(), message);WriteToStreams(msg, Logger::Debugging);}// Verbose debug messagevoid DefaultLogger::OnVerboseDebug(const char *message) {if (m_Severity < Logger::VERBOSE) {return;}static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;char msg[Size];ai_snprintf(msg, Size, "Debug, T%u: %s", GetThreadID(), message);WriteToStreams(msg, Logger::Debugging);}// ----------------------------------------------------------------------------------// Logs an infovoid DefaultLogger::OnInfo(const char *message) {static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;char msg[Size];ai_snprintf(msg, Size, "Info, T%u: %s", GetThreadID(), message);WriteToStreams(msg, Logger::Info);}// ----------------------------------------------------------------------------------// Logs a warningvoid DefaultLogger::OnWarn(const char *message) {static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;char msg[Size];ai_snprintf(msg, Size, "Warn, T%u: %s", GetThreadID(), message);WriteToStreams(msg, Logger::Warn);}// ----------------------------------------------------------------------------------// Logs an errorvoid DefaultLogger::OnError(const char *message) {static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;char msg[Size];ai_snprintf(msg, Size, "Error, T%u: %s", GetThreadID(), message);WriteToStreams(msg, Logger::Err);}// ----------------------------------------------------------------------------------// Will attach a new streambool DefaultLogger::attachStream(LogStream *pStream, unsigned int severity) {if (nullptr == pStream) {return false;}if (0 == severity) {severity = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;}for (StreamIt it = m_StreamArray.begin();it != m_StreamArray.end();++it) {if ((*it)->m_pStream == pStream) {(*it)->m_uiErrorSeverity |= severity;return true;}}LogStreamInfo *pInfo = new LogStreamInfo(severity, pStream);m_StreamArray.push_back(pInfo);return true;}// ----------------------------------------------------------------------------------// Detach a streambool DefaultLogger::detachStream(LogStream *pStream, unsigned int severity) {if (nullptr == pStream) {return false;}if (0 == severity) {severity = SeverityAll;}bool res(false);for (StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it) {if ((*it)->m_pStream == pStream) {(*it)->m_uiErrorSeverity &= ~severity;if ((*it)->m_uiErrorSeverity == 0) {// don't delete the underlying stream 'cause the caller gains ownership again(**it).m_pStream = nullptr;delete *it;m_StreamArray.erase(it);res = true;break;}return true;}}return res;}// ----------------------------------------------------------------------------------// ConstructorDefaultLogger::DefaultLogger(LogSeverity severity) :Logger(severity), noRepeatMsg(false), lastLen(0) {lastMsg[0] = '0円';}// ----------------------------------------------------------------------------------// DestructorDefaultLogger::~DefaultLogger() {for (StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it) {// also frees the underlying stream, we are its owner.delete *it;}}// ----------------------------------------------------------------------------------// Writes message to streamvoid DefaultLogger::WriteToStreams(const char *message, ErrorSeverity ErrorSev) {ai_assert(nullptr != message);// Check whether this is a repeated messageauto thisLen = ::strlen(message);if (thisLen == lastLen - 1 && !::strncmp(message, lastMsg, lastLen - 1)) {if (!noRepeatMsg) {noRepeatMsg = true;message = "Skipping one or more lines with the same contents\n";}return;} else {// append a new-line character to the message to be printedlastLen = thisLen;::memcpy(lastMsg, message, lastLen + 1);::strcat(lastMsg + lastLen, "\n");message = lastMsg;noRepeatMsg = false;++lastLen;}for (ConstStreamIt it = m_StreamArray.begin();it != m_StreamArray.end();++it) {if (ErrorSev & (*it)->m_uiErrorSeverity)(*it)->m_pStream->write(message);}}// ----------------------------------------------------------------------------------// Returns thread id, if not supported only a zero will be returned.unsigned int DefaultLogger::GetThreadID() {// fixme: we can get this value via std::threads// std::this_thread::get_id().hash() returns a (big) size_t, not sure if this is useful in this case.#ifdef WIN32return (unsigned int)::GetCurrentThreadId();#elsereturn 0; // not supported#endif}// ----------------------------------------------------------------------------------} // namespace Assimp
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。