/* $Revision: 37 $ $Date: 26/07/06 15:44 $ Copyright © 2001-2007, FSL Technologies Limited. Contact "http://fost.3.felspar.com". */ #include "stdafx.h" #include #include using namespace std; using namespace FSLib; using namespace FSLib::Exceptions; namespace { Revision c_revision( L"$Archive: /FOST.3/F3Util/exception.cpp $", __DATE__, L"$Revision: 37 $", L"$Date: 26/07/06 15:44 $" ); const wchar_t StructuredMsg[]=L"Windows Structured Exception"; const wchar_t OverflowMsg[]=L"An Overflow occured"; const wchar_t OutOfRangeStringMsg[]=L"Value outside of allowable range"; const wchar_t NotImplementedMsg[]=L"Feature not implemented"; const wchar_t ExternalProcessFailureMsg[]=L"External process exit code not zero"; const wchar_t FileErrorMsg[]=L"A File I/O error occured"; const Setting c_translate( L"$Archive: /FOST.3/F3Util/exception.cpp $", L"Exception", L"Translate", L"None", true ); } FSLib::wstring FSLib::formatLastError() { LPVOID lpMsgBuf; if (!FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL )) return L"FormatMessage() problem - Cannot generate error message"; FSLib::wstring ret( reinterpret_cast< LPCTSTR >( lpMsgBuf ) ); LocalFree( lpMsgBuf ); return ret; } class FSLib::Exceptions::StructureInformation { public: StructureInformation( _se_translator_function ofunc ) : m_oldFunc( ofunc ) { } StructureInformation( EXCEPTION_POINTERS *info ) : m_info( info ) { } public: EXCEPTION_POINTERS *m_info; _se_translator_function m_oldFunc; }; namespace { void __cdecl structured( unsigned int, EXCEPTION_POINTERS *info ) { if ( _wtoi( Structured::c_translate.value().c_str() ) ) { if ( info->ExceptionRecord->ExceptionCode != EXCEPTION_STACK_OVERFLOW && info->ExceptionRecord->ExceptionCode != DBG_CONTROL_C && info->ExceptionRecord->ExceptionCode != EXCEPTION_BREAKPOINT ) { throw FSLib::Exceptions::Structured( FSLib::Exceptions::StructureInformation( info ) ); } else { throw; } } else { throw; } } } StructuredHandler::StructuredHandler() : m_info( new StructureInformation( reinterpret_cast< _se_translator_function >( NULL ) ) ) { if ( _wtoi( Structured::c_translate.value().c_str() ) ) { m_info->m_oldFunc = _set_se_translator( structured ); } } StructuredHandler::~StructuredHandler() { if ( m_info->m_oldFunc ) { _set_se_translator( m_info->m_oldFunc ); } delete m_info; } void FSLib::absorbException() { // An exception is in the process of being thrown away. // We want to be very careful not to do anything that may throw again. #ifdef _DEBUG // This will allow all debug builds to attach to a debugger to offending run. // It's unclear what this may do with something like IIS... __asm int 3 #endif } /* FSLib::Exceptions::Exception */ Exception::Exception( const Exception &e ) : m_info() { m_info << e.info().str(); } Exception::Exception() : m_info() { } Exception::Exception( const FSLib::wstring &m ) : m_info() { m_info << m << endl; } Exception::~Exception() { } Exception &Exception::operator =( const Exception &e ) { typedef std::exception t_base; t_base::operator =( e ); m_info.clear(); m_whatString = boost::shared_array< char >(); m_info << e.info().str(); return *this; } const wstringstream &Exception::info() const { return m_info; } wstringstream &Exception::info() { return m_info; } const char *Exception::what() const { FSLib::string text; if ( c_translate.value() == L"HTML" ) { text = narrow( wstring( message() ) + L"

" + replaceAll( m_info.str(), L"\n", L"
" ) ); } else { text = narrow( wstring( message() ) + L"\n\n" + m_info.str() ); } m_whatString = boost::shared_array< char >( new char[ text.length() + 1 ] ); strcpy( m_whatString.get(), text.c_str() ); return m_whatString.get(); } __declspec( dllexport ) std::wostream &FSLib::Exceptions::Exception::printOn( wostream &o ) const { return o << message() << endl << m_info.str(); } wostream &FSLib::Exceptions::operator<<( wostream &o, const Exception &e) { return e.printOn( o ); } /* FSLib::Exceptions::Structured */ const FSLib::Setting FSLib::Exceptions::Structured::c_translate( L"$Archive: /FOST.3/F3Util/exception.cpp $", L"Exception", L"Translate structured", L"1", true ); FSLib::Exceptions::Structured::Structured( const StructureInformation &info ) : Exception () { switch ( info.m_info->ExceptionRecord->ExceptionCode ) { case EXCEPTION_ACCESS_VIOLATION: m_info << L"The thread tried to read from or write to a virtual address for which it does not have the appropriate access." << endl; break; case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: m_info << L"The thread tried to access an array element that is out of bounds and the underlying hardware supports bounds checking." << endl; break; case EXCEPTION_BREAKPOINT: m_info << L"A breakpoint was encountered." << endl; break; case EXCEPTION_DATATYPE_MISALIGNMENT: m_info << L"The thread tried to read or write data that is misaligned on hardware that does not provide alignment. For example, 16-bit values must be aligned on 2-byte boundaries; 32-bit values on 4-byte boundaries, and so on." << endl; break; case EXCEPTION_FLT_DENORMAL_OPERAND: m_info << L"One of the operands in a floating-point operation is denormal. A denormal value is one that is too small to represent as a standard floating-point value." << endl; break; case EXCEPTION_FLT_DIVIDE_BY_ZERO: m_info << L"The thread tried to divide a floating-point value by a floating-point divisor of zero." << endl; break; case EXCEPTION_FLT_INEXACT_RESULT: m_info << L"The result of a floating-point operation cannot be represented exactly as a decimal fraction." << endl; break; case EXCEPTION_FLT_INVALID_OPERATION: m_info << L"This exception represents any floating-point exception not included in this list." << endl; break; case EXCEPTION_FLT_OVERFLOW: m_info << L"The exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type." << endl; break; case EXCEPTION_FLT_STACK_CHECK: m_info << L"The stack overflowed or underflowed as the result of a floating-point operation." << endl; break; case EXCEPTION_FLT_UNDERFLOW: m_info << L"The exponent of a floating-point operation is less than the magnitude allowed by the corresponding type." << endl; break; case EXCEPTION_ILLEGAL_INSTRUCTION: m_info << L"The thread tried to execute an invalid instruction." << endl; break; case EXCEPTION_IN_PAGE_ERROR: m_info << L"The thread tried to access a page that was not present, and the system was unable to load the page. For example, this exception might occur if a network connection is lost while running a program over the network." << endl; break; case EXCEPTION_INT_DIVIDE_BY_ZERO: m_info << L"The thread tried to divide an integer value by an integer divisor of zero." << endl; break; case EXCEPTION_INT_OVERFLOW: m_info << L"The result of an integer operation caused a carry out of the most significant bit of the result." << endl; break; case EXCEPTION_INVALID_DISPOSITION: m_info << L"An exception handler returned an invalid disposition to the exception dispatcher. Programmers using a high-level language such as C should never encounter this exception." << endl; break; case EXCEPTION_NONCONTINUABLE_EXCEPTION: m_info << L"The thread tried to continue execution after a noncontinuable exception occurred." << endl; break; case EXCEPTION_PRIV_INSTRUCTION: m_info << L"The thread tried to execute an instruction whose operation is not allowed in the current machine mode." << endl; break; case EXCEPTION_SINGLE_STEP: m_info << L"A trace trap or other single-instruction mechanism signaled that one instruction has been executed." << endl; break; default: m_info << L"Unknown type of Structured Exception" << endl; } } const wchar_t * const FSLib::Exceptions::Structured::message() const { return StructuredMsg; } /* FSLib::Exceptions::Overflow */ Overflow::Overflow( const FSLib::wstring &message ) : Exception( message ) { } Overflow::Overflow( const FSLib::wstring &message, const FSLib::wstring &n, const FSLib::wstring &d, const FSLib::wstring &m ) : Exception( message ) { m_info << L"Attempting to calculate: " << n << L" * " << m << L" / " << d << endl; } Overflow::Overflow( const FSLib::wstring &n, const FSLib::wstring &d, const FSLib::wstring &m ) : Exception() { m_info << L"Attempting to calculate: " << n << L" * " << m << L" / " << d << endl; } const wchar_t * const Overflow::message() const { return OverflowMsg; } /* FSLib::Exceptions::OutOfRangeString */ OutOfRangeString::OutOfRangeString( const FSLib::wstring &mes, const FSLib::wstring &mn, const FSLib::wstring &mx, const FSLib::wstring &v ) : Exception( mes ) { m_info << L"Value: " << v << endl; m_info << L"Minimum: " << mn << endl; m_info << L"Maximum: " << mx << endl; } const wchar_t * const OutOfRangeString::message() const { return OutOfRangeStringMsg; } /* FSLib::Exceptions::NotImplemented */ NotImplemented::NotImplemented() : Exception() { } NotImplemented::NotImplemented( const FSLib::wstring &func ) : Exception( func ) { } NotImplemented::NotImplemented( const FSLib::wstring &func, const FSLib::wstring &mess ) : Exception( func ) { m_info << mess << endl; } NotImplemented::NotImplemented( const FSLib::wstring &func, const FSLib::wstring &mes, const FSLib::wstring &extra ) : Exception( func ) { m_info << mes << endl; m_info << extra << endl; } const wchar_t * const NotImplemented::message() const { return NotImplementedMsg; } /* FSLib::Exceptions::ExternalProcessFailure */ ExternalProcessFailure::ExternalProcessFailure() : Exception() { } ExternalProcessFailure::ExternalProcessFailure( const FSLib::wstring &command ) : Exception( command ) { } const wchar_t * const ExternalProcessFailure::message() const { return ExternalProcessFailureMsg; } /* FSLib::Exceptions::FileError */ FileError::FileError( const FSLib::wstring &message, const FSLib::wstring &filename ) : Exception( message ) { m_info << L"Filename: " << filename << std::endl; } const wchar_t * const FileError::message() const { return FileErrorMsg; }