File indexing completed on 2024-11-10 04:40:40

0001 /*
0002     SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "exceptionbase.h"
0008 
0009 #include <QString>
0010 
0011 #include <memory>
0012 
0013 using namespace Akonadi;
0014 
0015 class Akonadi::ExceptionPrivate
0016 {
0017 public:
0018     explicit ExceptionPrivate(const QByteArray &what)
0019         : what(what)
0020     {
0021     }
0022 
0023     QByteArray what;
0024     QByteArray assembledWhat;
0025 };
0026 
0027 Exception::Exception(const char *what)
0028 {
0029     try {
0030         d = std::make_unique<ExceptionPrivate>(what);
0031     } catch (...) {
0032     }
0033 }
0034 
0035 Exception::Exception(const QByteArray &what)
0036 {
0037     try {
0038         d = std::make_unique<ExceptionPrivate>(what);
0039     } catch (...) {
0040     }
0041 }
0042 
0043 Exception::Exception(const QString &what)
0044 {
0045     try {
0046         d = std::make_unique<ExceptionPrivate>(what.toUtf8());
0047     } catch (...) {
0048     }
0049 }
0050 
0051 Exception::Exception(Exception &&) noexcept = default;
0052 
0053 Exception::~Exception() = default;
0054 
0055 QByteArray Exception::type() const
0056 {
0057     static constexpr char mytype[] = "Akonadi::Exception";
0058     try {
0059         return QByteArray::fromRawData("Akonadi::Exception", sizeof(mytype) - 1);
0060     } catch (...) {
0061         return QByteArray();
0062     }
0063 }
0064 
0065 const char *Exception::what() const noexcept
0066 {
0067     static constexpr char fallback[] = "<some exception was thrown during construction: message lost>";
0068     if (!d) {
0069         return fallback;
0070     }
0071     if (d->assembledWhat.isEmpty()) {
0072         try {
0073             d->assembledWhat = QByteArray(type() + ": " + d->what);
0074         } catch (...) {
0075             return "caught some exception while assembling Akonadi::Exception::what() return value";
0076         }
0077     }
0078     return d->assembledWhat.constData();
0079 }
0080 
0081 #define AKONADI_EXCEPTION_IMPLEMENT_TRIVIAL_INSTANCE(classname)                                                                                                \
0082     Akonadi::classname::~classname() = default;                                                                                                                \
0083     QByteArray Akonadi::classname::type() const                                                                                                                \
0084     {                                                                                                                                                          \
0085         static constexpr char mytype[] = "Akonadi::" #classname;                                                                                               \
0086         try {                                                                                                                                                  \
0087             return QByteArray::fromRawData(mytype, sizeof(mytype) - 1);                                                                                        \
0088         } catch (...) {                                                                                                                                        \
0089             return QByteArray();                                                                                                                               \
0090         }                                                                                                                                                      \
0091     }
0092 
0093 AKONADI_EXCEPTION_IMPLEMENT_TRIVIAL_INSTANCE(PayloadException)
0094 
0095 #undef AKONADI_EXCEPTION_IMPLEMENT_TRIVIAL_INSTANCE