b19c2db85d6004da3071040bfef194e83b39a75f
[senf.git] / Utils / Exception.hh
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Exception public header */
25
26 #ifndef HH_Exception_
27 #define HH_Exception_ 1
28
29 // Custom includes
30 #include <exception>
31 #include <string>
32 #include <boost/preprocessor/repeat.hpp>
33 #include <boost/preprocessor/cat.hpp>
34
35 //#include "Exception.mpp"
36 ///////////////////////////////hh.p////////////////////////////////////////
37
38 /** \defgroup exception System exceptions
39
40     The senf::SystemException class and it's derived class template senf::ErrnoException are used to
41     signal generic system failures based on \c errno codes. 
42
43     senf::SystemException is a generic \c errno based exception which carries an error number and
44     origin information. senf::ErrnoException is a derived class specialized for a specific error
45     code. This simplifies managing error conditions:
46
47     \code
48     try {
49         something.open(path);
50         // ...
51     }
52     catch (senf::ErrnoException<ENOFILE> & e) {
53         // Create new file
54     }
55     catch (senf::SystemException & e) {
56         // Catch all other system exceptions
57         std::cerr << "Error accessing '" << path << "': " << e.what() << std::endl;
58     }
59     \endcode
60
61     This exception is normally thrown using the senf::throwErrno() helper:
62
63     \code
64     if ((fd = ::open(path.c_str(), O_RDWR)) < 0)
65         senf::throwErrno("::open()");
66     \endcode
67
68     The senf::throwErrno() helper will throw the correct exception class based on some \c errno
69     value.
70  */
71
72 namespace senf {
73
74     /** \brief Exception handling standard UNIX errors (errno)
75
76         This exception is thrown to signal generic \c errno failures. In addition to the \c errno
77         number (the code()), this class manages optional origin information. This parameter should
78         be provided to further describe, in what context the exception was created.
79
80         This exception should not be used directly. Instead the derived class ErrnoException should
81         be thrown via one of the senf::throwErrno() helpers.
82
83         \see ErrnoException
84         \ingroup exception
85      */
86     class SystemException : public std::exception
87     {
88     public:
89         SystemException();              ///< SystemException without error location infor
90                                         /**< The error code is taken from the current value of the
91                                              global \c errno variable  */
92
93         explicit SystemException(int code); ///< SystemException without error location info
94                                         /**< \param[in] code error number (the \c errno value) */
95
96         explicit SystemException(char const * where); ///< SystemException with error location info
97                                         /**< The error code is taken from the current value of the
98                                              global \c errno variable 
99                                              \param[in] where description of error origin */
100
101         SystemException(char const * where, int code); ///< SystemException with error location info 
102                                         /**< \param[in] where description of error origin
103                                              \param[in] code error number (the \c errno value) */
104
105         virtual char const * what() const throw(); ///< Return verbose error description
106
107         char const * where() const;     ///< Error origin
108         int code() const;               ///< Error code (\c errno number)
109         char const * description() const; ///< Error description (strerror() value)
110
111         bool anyOf(int c0, int c1=0, int c2=0, int c3=0, int c4=0, int c5=0, 
112                    int c6=0, int c7=0, int c8=0, int c9=0);
113                                         ///< \c true, if code() is one of \a c0 ... \a c9
114
115         virtual ~SystemException() throw();
116
117     private:
118         void init();
119
120         char const * const where_;
121         int const code_;                // This must be const to make the derived ErrnoException
122                                         // class a valid derived class.
123         std::string buffer_;
124     };
125
126     /** \brief Error specific system exception
127
128         This template restricts the generic SystemException to a specific, compile-time constant
129         error number \p Code. This allows a specific \c errno number to be cached explicitly.
130
131         This exception is normally thrown via one of the senf::throwErrno() helpers. These helpers
132         take the numeric \c errno value (either from the \c errno variable or from their
133         argument) and will throw the corresponding ErrnoException:
134         \code
135         if ((fd = ::open(filename, O_RDWR)) < 0)
136              senf::throwErrno("open()");
137         \endcode
138         \ingroup exception
139      */
140     template <int Code>
141     class ErrnoException : public SystemException
142     {
143     public:
144         static int const fixed_code = Code;
145
146         ErrnoException();               ///< ErrnoException without error location information
147         explicit ErrnoException(char const * where);
148                                         ///< ErrnoException with error location information
149     };
150
151     
152     /** \brief Throw ErrnoException based on current \c errno value
153         \ingroup exception
154      */
155     void throwErrno();
156
157     /** \brief Throw ErrnoException based on current \c errno value (with location info)
158         \ingroup exception
159      */
160     void throwErrno(char const * where);
161
162     /** \brief Throw ErrnoException based on given \c errno value
163         \ingroup exception
164      */
165     void throwErrno(int code);
166
167     /** \brief Throw ErrnoException based on given \c errno value (with location info)
168         \ingroup exception
169      */
170     void throwErrno(char const * where, int code);
171
172     enum NoThrow_t { nothrow };
173
174 }
175
176 ///////////////////////////////hh.e////////////////////////////////////////
177 #include "Exception.cci"
178 //#include "Exception.ct"
179 #include "Exception.cti"
180 #endif
181
182 \f
183 // Local Variables:
184 // mode: c++
185 // fill-column: 100
186 // c-file-style: "senf"
187 // indent-tabs-mode: nil
188 // ispell-local-dictionary: "american"
189 // compile-command: "scons -u test"
190 // comment-column: 40
191 // End: