summaryrefslogtreecommitdiffstats
path: root/Whisper/Utils/Logger.cpp
diff options
context:
space:
mode:
authorKonstantin <const@const.me>2023-01-16 14:52:43 +0100
committerKonstantin <const@const.me>2023-01-16 14:52:43 +0100
commit8c4603c73675958efc960fbd4bb599a2909d106a (patch)
tree714dc6fc9a1672d5fd7f89676b97e10959662abc /Whisper/Utils/Logger.cpp
parent990a8d0dbaefc996244097397259e92758b15cce (diff)
Source codes
Diffstat (limited to 'Whisper/Utils/Logger.cpp')
-rw-r--r--Whisper/Utils/Logger.cpp240
1 files changed, 240 insertions, 0 deletions
diff --git a/Whisper/Utils/Logger.cpp b/Whisper/Utils/Logger.cpp
new file mode 100644
index 0000000..1b4b233
--- /dev/null
+++ b/Whisper/Utils/Logger.cpp
@@ -0,0 +1,240 @@
+#include "stdafx.h"
+#include "Logger.h"
+#include "../API/iContext.cl.h"
+#include <cstdarg>
+#include <atlstr.h>
+
+namespace
+{
+ wchar_t* formatMessage( HRESULT hr )
+ {
+ wchar_t* err;
+ if( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ hr,
+ MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
+ (LPTSTR)&err,
+ 0,
+ nullptr ) )
+ return err;
+ return nullptr;
+ }
+
+ class Utf
+ {
+ CStringA utf8;
+ CStringW utf16;
+
+ void appendError( HRESULT hr )
+ {
+ const wchar_t* err = formatMessage( hr );
+ if( nullptr != err )
+ {
+ utf16 += err;
+ LocalFree( (HLOCAL)err );
+ utf16.TrimRight();
+ }
+ else
+ utf16.AppendFormat( L"error code %i (0x%08X)", hr, hr );
+ }
+
+ public:
+ const char* print( const char* pszFormat, std::va_list va )
+ {
+ utf8.FormatV( pszFormat, va );
+ return utf8;
+ }
+ const wchar_t* print( const wchar_t* pszFormat, std::va_list va )
+ {
+ utf16.FormatV( pszFormat, va );
+ return utf16;
+ }
+ const wchar_t* upcast( const char* message, int len )
+ {
+ int count = MultiByteToWideChar( CP_UTF8, 0, message, len, nullptr, 0 );
+ if( count == 0 )
+ return nullptr;
+ wchar_t* b = utf16.GetBufferSetLength( len + 1 );
+ count = MultiByteToWideChar( CP_UTF8, 0, message, len, b, len );
+ utf16.ReleaseBuffer( count );
+ return utf16;
+ }
+ int utf8Length() const
+ {
+ return utf8.GetLength();
+ }
+ const wchar_t* printError( HRESULT hr, const char* pszFormat, std::va_list va )
+ {
+ print( pszFormat, va );
+ upcast( utf8, utf8.GetLength() );
+ utf16 += L": ";
+ appendError( hr );
+ return utf16;
+ }
+ const char* downcast()
+ {
+ int count = WideCharToMultiByte( CP_UTF8, 0, utf16, utf16.GetLength(), nullptr, 0, nullptr, nullptr );
+ char* s = utf8.GetBufferSetLength( count + 1 );
+ count = WideCharToMultiByte( CP_UTF8, 0, utf16, utf16.GetLength(), s, count, nullptr, nullptr );
+ utf8.ReleaseBufferSetLength( count );
+ return utf8;
+ }
+ };
+ thread_local Utf ts_utf;
+ using Whisper::eLoggerFlags;
+
+ class Logger : Whisper::sLoggerSetup
+ {
+ inline bool hasFlag( eLoggerFlags bit ) const
+ {
+ return 0 != ( (uint8_t)flags & (uint8_t)bit );
+ }
+
+ bool useStdError() const
+ {
+ return hasFlag( eLoggerFlags::UseStandardError );
+ }
+
+ static void writeStdError( Whisper::eLogLevel lvl, const char* message, int len )
+ {
+ const wchar_t* w = ts_utf.upcast( message, len );
+ if( nullptr != w )
+ fwprintf( stderr, L"%s\n", w );
+ }
+
+ public:
+ Logger()
+ {
+ memset( this, 0, sizeof( Logger ) );
+ }
+
+ bool willLog( Whisper::eLogLevel lvl ) const
+ {
+ if( (uint8_t)lvl > (uint8_t)level )
+ return false;
+ if( useStdError() )
+ return true;
+ return nullptr != sink;
+ }
+
+ void message( Whisper::eLogLevel lvl, const char8_t* pszFormat, std::va_list va ) const
+ {
+ const char* s = ts_utf.print( (const char*)pszFormat, va );
+ auto pfn = sink;
+ if( nullptr != pfn )
+ pfn( context, lvl, s );
+ if( useStdError() )
+ writeStdError( lvl, s, ts_utf.utf8Length() );
+ }
+ void message( Whisper::eLogLevel lvl, const wchar_t* pszFormat, std::va_list va ) const
+ {
+ Utf& u = ts_utf;
+ const wchar_t* w = u.print( pszFormat, va );
+ auto pfn = sink;
+ if( nullptr != pfn )
+ pfn( context, lvl, u.downcast() );
+ if( useStdError() )
+ fwprintf( stderr, L"%s\n", w );
+ }
+ void message( Whisper::eLogLevel lvl, HRESULT hr, const char* pszFormat, std::va_list va ) const
+ {
+ if( hasFlag( eLoggerFlags::SkipFormatMessage ) )
+ {
+ message( lvl, (const char8_t*)pszFormat, va );
+ return;
+ }
+ Utf& u = ts_utf;
+ const wchar_t* w = ts_utf.printError( hr, (const char*)pszFormat, va );
+ auto pfn = sink;
+ if( nullptr != pfn )
+ pfn( context, lvl, u.downcast() );
+ if( useStdError() )
+ fwprintf( stderr, L"%s\n", w );
+ }
+
+ void operator=( const sLoggerSetup& rsi )
+ {
+ sink = rsi.sink;
+ context = rsi.context;
+ level = rsi.level;
+ flags = rsi.flags;
+ }
+ };
+
+ static Logger s_logger;
+}
+
+bool willLogMessage( Whisper::eLogLevel lvl )
+{
+ return s_logger.willLog( lvl );
+}
+
+using Whisper::eLogLevel;
+
+#define LOG_MESSAGE_IMPL( lvl ) \
+ if( !s_logger.willLog( lvl ) ) \
+ return; \
+ std::va_list args; \
+ va_start( args, pszFormat ); \
+ s_logger.message( lvl, pszFormat, args ); \
+ va_end( args );
+
+void logError( const char8_t* pszFormat, ... )
+{
+ LOG_MESSAGE_IMPL( eLogLevel::Error );
+}
+void logError16( const wchar_t* pszFormat, ... )
+{
+ LOG_MESSAGE_IMPL( eLogLevel::Error );
+}
+void logWarning( const char8_t* pszFormat, ... )
+{
+ LOG_MESSAGE_IMPL( eLogLevel::Warning );
+}
+void logWarning16( const wchar_t* pszFormat, ... )
+{
+ LOG_MESSAGE_IMPL( eLogLevel::Warning );
+}
+void logInfo( const char8_t* pszFormat, ... )
+{
+ LOG_MESSAGE_IMPL( eLogLevel::Info );
+}
+void logInfo16( const wchar_t* pszFormat, ... )
+{
+ LOG_MESSAGE_IMPL( eLogLevel::Info );
+}
+void logDebug( const char8_t* pszFormat, ... )
+{
+ LOG_MESSAGE_IMPL( eLogLevel::Debug );
+}
+void logDebug16( const wchar_t* pszFormat, ... )
+{
+ LOG_MESSAGE_IMPL( eLogLevel::Debug );
+}
+#undef LOG_MESSAGE_IMPL
+
+#define LOG_MESSAGE_IMPL( lvl ) \
+ if( !s_logger.willLog( lvl ) ) \
+ return; \
+ std::va_list args; \
+ va_start( args, pszFormat ); \
+ s_logger.message( lvl, hr, (const char*)pszFormat, args ); \
+ va_end( args );
+
+void logErrorHr( long hr, const char8_t* pszFormat, ... )
+{
+ LOG_MESSAGE_IMPL( eLogLevel::Error );
+}
+void logWarningHr( long hr, const char8_t* pszFormat, ... )
+{
+ LOG_MESSAGE_IMPL( eLogLevel::Warning );
+}
+
+#undef LOG_MESSAGE_IMPL
+
+// DLL entry point
+HRESULT COMLIGHTCALL Whisper::setupLogger( const sLoggerSetup& setup )
+{
+ s_logger = setup;
+ return S_OK;
+} \ No newline at end of file