Merge pull request #4775 from jmarshallnz/empty_episode_playcount
[vuplus_xbmc] / xbmc / commons / Exception.h
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #pragma once
22
23 //---------------------------------------------------------
24 // This include should be moved to commons but even as it is,
25 // it wont cause a linker circular dependency since it's just
26 // a header.
27 #include "utils/StringUtils.h"
28 #include "utils/StdString.h"
29 //---------------------------------------------------------
30 #include "ilog.h"
31
32 #ifdef __GNUC__
33 // The 'this' pointer counts as a parameter on member methods.
34 #define XBMCCOMMONS_ATTRIB_EXCEPTION_FORMAT __attribute__((format(printf,2,3)))
35 #else
36 #define XBMCCOMMONS_ATTRIB_EXCEPTION_FORMAT
37 #endif
38
39 #define XBMCCOMMONS_COPYVARARGS(fmt) va_list argList; va_start(argList, fmt); Set(fmt, argList); va_end(argList)
40 #define XBMCCOMMONS_STANDARD_EXCEPTION(E) \
41   class E : public XbmcCommons::Exception \
42   { \
43   public: \
44     inline E(const char* message,...) XBMCCOMMONS_ATTRIB_EXCEPTION_FORMAT : Exception(#E) { XBMCCOMMONS_COPYVARARGS(message); } \
45     \
46     inline E(const E& other) : Exception(other) {} \
47   }
48
49 namespace XbmcCommons
50 {
51   /**
52    * This class a superclass for exceptions that want to utilize some
53    * utility functionality including autologging with the specific
54    * exception name.
55    */
56   class Exception
57   {
58   private:
59
60     std::string classname;
61     CStdString message;
62
63   protected:
64     static ILogger* logger;
65
66     inline Exception(const char* classname_) : classname(classname_) { }
67     inline Exception(const char* classname_, const char* message_) : classname(classname_), message(message_) { }
68     inline Exception(const Exception& other) : classname(other.classname), message(other.message) { }
69
70     /**
71      * This method is called from the constructor of subclasses. It
72      * will set the message from varargs as well as call log message
73      */
74     inline void Set(const char* fmt, va_list& argList)
75     {
76       message = StringUtils::FormatV(fmt, argList);
77     }
78
79     /**
80      * This message can be called from the constructor of subclasses.
81      * It will set the message and log the throwing.
82      */
83     inline void SetMessage(const char* fmt, ...) XBMCCOMMONS_ATTRIB_EXCEPTION_FORMAT
84     {
85       // calls 'set'
86       XBMCCOMMONS_COPYVARARGS(fmt);
87     }
88
89     inline void setClassname(const char* cn) { classname = cn; }
90
91   public:
92     virtual ~Exception();
93
94     inline virtual void LogThrowMessage(const char* prefix = NULL) const
95     {
96       if (logger)
97         logger->Log(LOGERROR,"EXCEPTION Thrown (%s) : %s", classname.c_str(), message.c_str());
98     }
99
100     inline virtual const char* GetMessage() const { return message.c_str(); }
101
102     inline static void SetLogger(ILogger* exceptionLogger) { logger = exceptionLogger; }
103   };
104
105   /**
106    * This class forms the base class for unchecked exceptions. Unchecked exceptions
107    * are those that really shouldn't be handled explicitly. For example, on windows
108    * when a access violaton is converted to a win32_exception, there's nothing
109    * that can be done in most code. The outer most stack frame might try to 
110    * do some error logging prior to shutting down, but that's really it.
111    */
112   XBMCCOMMONS_STANDARD_EXCEPTION(UncheckedException);
113
114 /**
115  * In cases where you catch(...){} you will (may) inadvertently be 
116  * catching UncheckedException's. Therefore this macro will allow 
117  * you to do something equivalent to:
118  *    catch (anything except UncheckedException) {}
119  *
120  * In order to avoid catching UncheckedException, use the macro as follows:
121  *
122  *    try { ... }
123  *    XBMCCOMMONS_HANDLE_UNCHECKED
124  *    catch(...){ ... }
125  */
126 // Yes. I recognize that the name of this macro is an oxymoron.
127 #define  XBMCCOMMONS_HANDLE_UNCHECKED \
128   catch (const XbmcCommons::UncheckedException& ) { throw; } \
129   catch (const XbmcCommons::UncheckedException* ) { throw; }
130
131 }
132