vrshoot

diff libs/assimp/DefaultLogger.cpp @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libs/assimp/DefaultLogger.cpp	Sat Feb 01 19:58:19 2014 +0200
     1.3 @@ -0,0 +1,423 @@
     1.4 +/*
     1.5 +---------------------------------------------------------------------------
     1.6 +Open Asset Import Library (assimp)
     1.7 +---------------------------------------------------------------------------
     1.8 +
     1.9 +Copyright (c) 2006-2012, assimp team
    1.10 +
    1.11 +All rights reserved.
    1.12 +
    1.13 +Redistribution and use of this software in source and binary forms, 
    1.14 +with or without modification, are permitted provided that the following 
    1.15 +conditions are met:
    1.16 +
    1.17 +* Redistributions of source code must retain the above
    1.18 +  copyright notice, this list of conditions and the
    1.19 +  following disclaimer.
    1.20 +
    1.21 +* Redistributions in binary form must reproduce the above
    1.22 +  copyright notice, this list of conditions and the
    1.23 +  following disclaimer in the documentation and/or other
    1.24 +  materials provided with the distribution.
    1.25 +
    1.26 +* Neither the name of the assimp team, nor the names of its
    1.27 +  contributors may be used to endorse or promote products
    1.28 +  derived from this software without specific prior
    1.29 +  written permission of the assimp team.
    1.30 +
    1.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    1.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    1.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    1.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    1.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
    1.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    1.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    1.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.42 +---------------------------------------------------------------------------
    1.43 +*/
    1.44 +
    1.45 +/** @file  DefaultLogger.cpp
    1.46 + *  @brief Implementation of DefaultLogger (and Logger)
    1.47 + */
    1.48 +
    1.49 +#include "AssimpPCH.h"
    1.50 +#include "DefaultIOSystem.h"
    1.51 +
    1.52 +// Default log streams
    1.53 +#include "Win32DebugLogStream.h"
    1.54 +#include "StdOStreamLogStream.h"
    1.55 +#include "FileLogStream.h"
    1.56 +
    1.57 +#ifndef ASSIMP_BUILD_SINGLETHREADED
    1.58 +#	include <boost/thread/thread.hpp>
    1.59 +#	include <boost/thread/mutex.hpp>
    1.60 +
    1.61 +boost::mutex loggerMutex;
    1.62 +#endif
    1.63 +
    1.64 +namespace Assimp	{
    1.65 +
    1.66 +// ----------------------------------------------------------------------------------
    1.67 +NullLogger DefaultLogger::s_pNullLogger;
    1.68 +Logger *DefaultLogger::m_pLogger = &DefaultLogger::s_pNullLogger;
    1.69 +
    1.70 +static const unsigned int SeverityAll = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;
    1.71 +
    1.72 +// ----------------------------------------------------------------------------------
    1.73 +// Represents a log-stream + its error severity
    1.74 +struct LogStreamInfo
    1.75 +{
    1.76 +	unsigned int m_uiErrorSeverity;
    1.77 +	LogStream *m_pStream;
    1.78 +
    1.79 +	// Constructor
    1.80 +	LogStreamInfo( unsigned int uiErrorSev, LogStream *pStream ) :
    1.81 +		m_uiErrorSeverity( uiErrorSev ),
    1.82 +		m_pStream( pStream )
    1.83 +	{
    1.84 +		// empty
    1.85 +	}
    1.86 +	
    1.87 +	// Destructor
    1.88 +	~LogStreamInfo()
    1.89 +	{
    1.90 +		delete m_pStream;
    1.91 +	}
    1.92 +};
    1.93 +
    1.94 +// ----------------------------------------------------------------------------------
    1.95 +// Construct a default log stream
    1.96 +LogStream* LogStream::createDefaultStream(aiDefaultLogStream	streams,
    1.97 +	const char* name /*= "AssimpLog.txt"*/,
    1.98 +	IOSystem* io		    /*= NULL*/)
    1.99 +{
   1.100 +	switch (streams)	
   1.101 +	{
   1.102 +		// This is a platform-specific feature
   1.103 +	case aiDefaultLogStream_DEBUGGER:
   1.104 +#ifdef WIN32
   1.105 +		return new Win32DebugLogStream();
   1.106 +#else
   1.107 +		return NULL;
   1.108 +#endif
   1.109 +
   1.110 +		// Platform-independent default streams
   1.111 +	case aiDefaultLogStream_STDERR:
   1.112 +		return new StdOStreamLogStream(std::cerr);
   1.113 +	case aiDefaultLogStream_STDOUT:
   1.114 +		return new StdOStreamLogStream(std::cout);
   1.115 +	case aiDefaultLogStream_FILE:
   1.116 +		return (name && *name ? new FileLogStream(name,io) : NULL);
   1.117 +	default:
   1.118 +		// We don't know this default log stream, so raise an assertion
   1.119 +		ai_assert(false);
   1.120 +
   1.121 +	};
   1.122 +
   1.123 +	// For compilers without dead code path detection
   1.124 +	return NULL;
   1.125 +}
   1.126 +
   1.127 +// ----------------------------------------------------------------------------------
   1.128 +//	Creates the only singleton instance
   1.129 +Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/,
   1.130 +	LogSeverity severity                       /*= NORMAL*/,
   1.131 +	unsigned int defStreams                    /*= aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE*/,
   1.132 +	IOSystem* io		                       /*= NULL*/)
   1.133 +{
   1.134 +	// enter the mutex here to avoid concurrency problems
   1.135 +#ifndef ASSIMP_BUILD_SINGLETHREADED
   1.136 +	boost::mutex::scoped_lock lock(loggerMutex);
   1.137 +#endif
   1.138 +
   1.139 +	if (m_pLogger && !isNullLogger() )
   1.140 +		delete m_pLogger;
   1.141 +
   1.142 +	m_pLogger = new DefaultLogger( severity );
   1.143 +
   1.144 +	// Attach default log streams
   1.145 +	// Stream the log to the MSVC debugger?
   1.146 +	if (defStreams & aiDefaultLogStream_DEBUGGER)
   1.147 +		m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_DEBUGGER));
   1.148 +
   1.149 +	// Stream the log to COUT?
   1.150 +	if (defStreams & aiDefaultLogStream_STDOUT)
   1.151 +		m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDOUT));
   1.152 +
   1.153 +	// Stream the log to CERR?
   1.154 +	if (defStreams & aiDefaultLogStream_STDERR)
   1.155 +		 m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDERR));
   1.156 +	
   1.157 +	// Stream the log to a file
   1.158 +	if (defStreams & aiDefaultLogStream_FILE && name && *name)
   1.159 +		m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_FILE,name,io));
   1.160 +
   1.161 +	return m_pLogger;
   1.162 +}
   1.163 +
   1.164 +// ----------------------------------------------------------------------------------
   1.165 +void Logger::debug(const char* message)	{
   1.166 +
   1.167 +	// SECURITY FIX: otherwise it's easy to produce overruns since
   1.168 +	// sometimes importers will include data from the input file
   1.169 +	// (i.e. node names) in their messages.
   1.170 +	if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
   1.171 +		ai_assert(false);
   1.172 +		return;
   1.173 +	}
   1.174 +	return OnDebug(message);
   1.175 +}
   1.176 +
   1.177 +// ----------------------------------------------------------------------------------
   1.178 +void Logger::info(const char* message)	{
   1.179 +	
   1.180 +	// SECURITY FIX: see above
   1.181 +	if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
   1.182 +		ai_assert(false);
   1.183 +		return;
   1.184 +	}
   1.185 +	return OnInfo(message);
   1.186 +}
   1.187 +	
   1.188 +// ----------------------------------------------------------------------------------
   1.189 +void Logger::warn(const char* message)	{
   1.190 +	
   1.191 +	// SECURITY FIX: see above
   1.192 +	if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
   1.193 +		ai_assert(false);
   1.194 +		return;
   1.195 +	}
   1.196 +	return OnWarn(message);
   1.197 +}
   1.198 +
   1.199 +// ----------------------------------------------------------------------------------
   1.200 +void Logger::error(const char* message)	{
   1.201 +	
   1.202 +	// SECURITY FIX: see above
   1.203 +	if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
   1.204 +		ai_assert(false);
   1.205 +		return;
   1.206 +	}
   1.207 +	return OnError(message);
   1.208 +}
   1.209 +
   1.210 +// ----------------------------------------------------------------------------------
   1.211 +void DefaultLogger::set( Logger *logger )
   1.212 +{
   1.213 +	// enter the mutex here to avoid concurrency problems
   1.214 +#ifndef ASSIMP_BUILD_SINGLETHREADED
   1.215 +	boost::mutex::scoped_lock lock(loggerMutex);
   1.216 +#endif
   1.217 +
   1.218 +	if (!logger)logger = &s_pNullLogger;
   1.219 +	if (m_pLogger && !isNullLogger() )
   1.220 +		delete m_pLogger;
   1.221 +
   1.222 +	DefaultLogger::m_pLogger = logger;
   1.223 +}
   1.224 +
   1.225 +// ----------------------------------------------------------------------------------
   1.226 +bool DefaultLogger::isNullLogger()
   1.227 +{
   1.228 +	return m_pLogger == &s_pNullLogger;
   1.229 +}
   1.230 +
   1.231 +// ----------------------------------------------------------------------------------
   1.232 +//	Singleton getter
   1.233 +Logger *DefaultLogger::get()
   1.234 +{
   1.235 +	return m_pLogger;
   1.236 +}
   1.237 +
   1.238 +// ----------------------------------------------------------------------------------
   1.239 +//	Kills the only instance
   1.240 +void DefaultLogger::kill()
   1.241 +{
   1.242 +	// enter the mutex here to avoid concurrency problems
   1.243 +#ifndef ASSIMP_BUILD_SINGLETHREADED
   1.244 +	boost::mutex::scoped_lock lock(loggerMutex);
   1.245 +#endif
   1.246 +
   1.247 +	if (m_pLogger == &s_pNullLogger)return;
   1.248 +	delete m_pLogger;
   1.249 +	m_pLogger = &s_pNullLogger;
   1.250 +}
   1.251 +
   1.252 +// ----------------------------------------------------------------------------------
   1.253 +//	Debug message
   1.254 +void DefaultLogger::OnDebug( const char* message )
   1.255 +{
   1.256 +	if ( m_Severity == Logger::NORMAL )
   1.257 +		return;
   1.258 +
   1.259 +	char msg[MAX_LOG_MESSAGE_LENGTH*2];
   1.260 +	::sprintf(msg,"Debug, T%i: %s", GetThreadID(), message );
   1.261 +
   1.262 +	WriteToStreams( msg, Logger::Debugging );
   1.263 +}
   1.264 +
   1.265 +// ----------------------------------------------------------------------------------
   1.266 +//	Logs an info
   1.267 +void DefaultLogger::OnInfo( const char* message )
   1.268 +{
   1.269 +	char msg[MAX_LOG_MESSAGE_LENGTH*2];
   1.270 +	::sprintf(msg,"Info,  T%i: %s", GetThreadID(), message );
   1.271 +
   1.272 +	WriteToStreams( msg , Logger::Info );
   1.273 +}
   1.274 +
   1.275 +// ----------------------------------------------------------------------------------
   1.276 +//	Logs a warning
   1.277 +void DefaultLogger::OnWarn( const char* message )
   1.278 +{
   1.279 +	char msg[MAX_LOG_MESSAGE_LENGTH*2];
   1.280 +	::sprintf(msg,"Warn,  T%i: %s", GetThreadID(), message );
   1.281 +
   1.282 +	WriteToStreams( msg, Logger::Warn );
   1.283 +}
   1.284 +
   1.285 +// ----------------------------------------------------------------------------------
   1.286 +//	Logs an error
   1.287 +void DefaultLogger::OnError( const char* message )
   1.288 +{
   1.289 +	char msg[MAX_LOG_MESSAGE_LENGTH*2];
   1.290 +	::sprintf(msg,"Error, T%i: %s", GetThreadID(), message );
   1.291 +
   1.292 +	WriteToStreams( msg, Logger::Err );
   1.293 +}
   1.294 +
   1.295 +// ----------------------------------------------------------------------------------
   1.296 +//	Will attach a new stream
   1.297 +bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
   1.298 +{
   1.299 +	if (!pStream)
   1.300 +		return false;
   1.301 +
   1.302 +	if (0 == severity)	{
   1.303 +		severity = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;
   1.304 +	}
   1.305 +
   1.306 +	for ( StreamIt it = m_StreamArray.begin();
   1.307 +		it != m_StreamArray.end();
   1.308 +		++it )
   1.309 +	{
   1.310 +		if ( (*it)->m_pStream == pStream )
   1.311 +		{
   1.312 +			(*it)->m_uiErrorSeverity |= severity;
   1.313 +			return true;
   1.314 +		}
   1.315 +	}
   1.316 +	
   1.317 +	LogStreamInfo *pInfo = new LogStreamInfo( severity, pStream );
   1.318 +	m_StreamArray.push_back( pInfo );
   1.319 +	return true;
   1.320 +}
   1.321 +
   1.322 +// ----------------------------------------------------------------------------------
   1.323 +//	Detatch a stream
   1.324 +bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
   1.325 +{
   1.326 +	if (!pStream)
   1.327 +		return false;
   1.328 +
   1.329 +	if (0 == severity)	{
   1.330 +		severity = SeverityAll;
   1.331 +	}
   1.332 +	
   1.333 +	for ( StreamIt it = m_StreamArray.begin();
   1.334 +		it != m_StreamArray.end();
   1.335 +		++it )
   1.336 +	{
   1.337 +		if ( (*it)->m_pStream == pStream )
   1.338 +		{
   1.339 +			(*it)->m_uiErrorSeverity &= ~severity;
   1.340 +			if ( (*it)->m_uiErrorSeverity == 0 )
   1.341 +			{
   1.342 +				// don't delete the underlying stream 'cause the caller gains ownership again
   1.343 +				(**it).m_pStream = NULL;
   1.344 +				delete *it;
   1.345 +				m_StreamArray.erase( it );
   1.346 +				break;
   1.347 +			}
   1.348 +			return true;
   1.349 +		}
   1.350 +	}
   1.351 +	return false;
   1.352 +}
   1.353 +
   1.354 +// ----------------------------------------------------------------------------------
   1.355 +//	Constructor
   1.356 +DefaultLogger::DefaultLogger(LogSeverity severity) 
   1.357 +
   1.358 +	:	Logger	( severity )
   1.359 +	,	noRepeatMsg	(false)
   1.360 +	,	lastLen( 0 )
   1.361 +{
   1.362 +	lastMsg[0] = '\0';
   1.363 +}
   1.364 +
   1.365 +// ----------------------------------------------------------------------------------
   1.366 +//	Destructor
   1.367 +DefaultLogger::~DefaultLogger()
   1.368 +{
   1.369 +	for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it ) {
   1.370 +		// also frees the underlying stream, we are its owner.
   1.371 +		delete *it;
   1.372 +	}
   1.373 +}
   1.374 +
   1.375 +// ----------------------------------------------------------------------------------
   1.376 +//	Writes message to stream
   1.377 +void DefaultLogger::WriteToStreams(const char *message, 
   1.378 +	ErrorSeverity ErrorSev )
   1.379 +{
   1.380 +	ai_assert(NULL != message);
   1.381 +
   1.382 +	// Check whether this is a repeated message
   1.383 +	if (! ::strncmp( message,lastMsg, lastLen-1))
   1.384 +	{
   1.385 +		if (!noRepeatMsg)
   1.386 +		{
   1.387 +			noRepeatMsg = true;
   1.388 +			message = "Skipping one or more lines with the same contents\n";
   1.389 +		}
   1.390 +		else return;
   1.391 +	}
   1.392 +	else
   1.393 +	{
   1.394 +		// append a new-line character to the message to be printed
   1.395 +		lastLen = ::strlen(message);
   1.396 +		::memcpy(lastMsg,message,lastLen+1);
   1.397 +		::strcat(lastMsg+lastLen,"\n");
   1.398 +
   1.399 +		message = lastMsg;
   1.400 +		noRepeatMsg = false;
   1.401 +		++lastLen;
   1.402 +	}
   1.403 +	for ( ConstStreamIt it = m_StreamArray.begin();
   1.404 +		it != m_StreamArray.end();
   1.405 +		++it)
   1.406 +	{
   1.407 +		if ( ErrorSev & (*it)->m_uiErrorSeverity )
   1.408 +			(*it)->m_pStream->write( message);
   1.409 +	}
   1.410 +}
   1.411 +
   1.412 +// ----------------------------------------------------------------------------------
   1.413 +//	Returns thread id, if not supported only a zero will be returned.
   1.414 +unsigned int DefaultLogger::GetThreadID()
   1.415 +{
   1.416 +	// fixme: we can get this value via boost::threads
   1.417 +#ifdef WIN32
   1.418 +	return (unsigned int)::GetCurrentThreadId();
   1.419 +#else
   1.420 +	return 0; // not supported
   1.421 +#endif
   1.422 +}
   1.423 +
   1.424 +// ----------------------------------------------------------------------------------
   1.425 +
   1.426 +} // !namespace Assimp