exception.cpp
00001 /* 00002 Copyright (c) 2009 Volker Krause <vkrause@kde.org> 00003 00004 This library is free software; you can redistribute it and/or modify it 00005 under the terms of the GNU Library General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or (at your 00007 option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, but WITHOUT 00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00012 License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to the 00016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00017 02110-1301, USA. 00018 */ 00019 00020 #include "exception.h" 00021 00022 #include <KDebug> 00023 #include <QString> 00024 00025 #include <memory> 00026 00027 using namespace Akonadi; 00028 00029 class Exception::Private 00030 { 00031 public: 00032 QByteArray what; 00033 QByteArray assembledWhat; 00034 }; 00035 00036 Exception::Exception(const char* what) throw() : 00037 d( 0 ) 00038 { 00039 try { 00040 std::auto_ptr<Private> nd( new Private ); 00041 nd->what = what; 00042 d = nd.release(); 00043 } catch ( ... ) {} 00044 } 00045 00046 Exception::Exception(const QByteArray& what) throw() : 00047 d( 0 ) 00048 { 00049 try { 00050 std::auto_ptr<Private> nd( new Private ); 00051 nd->what = what; 00052 d = nd.release(); 00053 } catch ( ... ) {} 00054 } 00055 00056 Exception::Exception(const QString& what) throw() : 00057 d( 0 ) 00058 { 00059 try { 00060 std::auto_ptr<Private> nd( new Private ); 00061 nd->what = what.toUtf8(); 00062 d = nd.release(); 00063 } catch ( ... ) {} 00064 } 00065 00066 Exception::Exception(const Akonadi::Exception& other) throw() : 00067 std::exception( other ), d( 0 ) 00068 { 00069 if ( !other.d ) 00070 return; 00071 try { 00072 std::auto_ptr<Private> nd( new Private( *other.d ) ); 00073 d = nd.release(); 00074 } catch ( ... ) {} 00075 } 00076 00077 Exception::~Exception() throw() 00078 { 00079 delete d; 00080 } 00081 00082 QByteArray Exception::type() const throw() 00083 { 00084 static const char mytype[] = "Akonadi::Exception"; 00085 try { 00086 return QByteArray::fromRawData( "Akonadi::Exception", sizeof(mytype)-1 ); 00087 } catch ( ... ) { 00088 return QByteArray(); 00089 } 00090 } 00091 00092 const char* Exception::what() const throw() 00093 { 00094 static const char fallback[] = "<some exception was thrown during construction: message lost>"; 00095 if ( !d ) 00096 return fallback; 00097 if ( d->assembledWhat.isEmpty() ) 00098 try { 00099 d->assembledWhat = QByteArray( type() + ": " + d->what ); 00100 } catch ( ... ) { 00101 return "caught some exception while assembling Akonadi::Exception::what() return value"; 00102 } 00103 return d->assembledWhat.constData(); 00104 } 00105 00106 #define AKONADI_EXCEPTION_IMPLEMENT_TRIVIAL_INSTANCE( classname ) \ 00107 Akonadi::classname::~classname() throw() {} \ 00108 QByteArray Akonadi::classname::type() const throw() { \ 00109 static const char mytype[] = "Akonadi::" #classname ; \ 00110 try { \ 00111 return QByteArray::fromRawData( mytype, sizeof(mytype)-1 ); \ 00112 } catch ( ... ) { \ 00113 return QByteArray(); \ 00114 } \ 00115 } 00116 00117 AKONADI_EXCEPTION_IMPLEMENT_TRIVIAL_INSTANCE( PayloadException ) 00118 00119 #undef AKONADI_EXCEPTION_IMPLEMENT_TRIVIAL_INSTANCE