Main Page   Compound List   File List   Compound Members   File Members   Related Pages  

NSXException.h

Go to the documentation of this file.
00001 /****************************************************************************************
00002     NSXException.h $Revision: 1.4 $
00003     
00004     Copyright (c) 2002 Red Shed Software. All rights reserved.
00005     by Jonathan 'Wolf' Rentzsch (jon * redshed * net)
00006     
00007     ************************************************************************************/
00008 
00009 /************************************************************************************/
00030 #ifndef     _NSXException_
00031 #define     _NSXException_
00032 
00033 #include    <Cocoa/Cocoa.h>
00034 #include    <exception>
00035 #include    <typeinfo>
00036 
00037 /****************************************************************************************
00038 *   
00039 *   Classes
00040 *   
00041 ****************************************************************************************/
00042 #pragma mark    (Classes)
00043 
00044 /************************************************************************************/
00049 class   NSXException : public std::exception {
00050 public:
00052     NSXException(
00053         NSException *nsexception )
00054     :   nsexception_( nsexception ){}
00055     
00057         NSException*
00058     nsexception() const
00059     {   return nsexception_; }
00060     
00062         void
00063     raise() const {
00064         [nsexception_ raise];
00065     }
00066     
00068         virtual
00069         const char*
00070     what() const throw() {
00071         return "NSXException";
00072     }
00073     
00074     /************************************************************************************/
00085         static
00086         NSException*
00087     NSExceptionForException(
00088         const   std::exception  *cppException )
00089     {
00090         const NSXException *nsxexception = dynamic_cast<const NSXException*>( cppException );
00091         if( nsxexception ) {
00092             //  It's a wrapped NSException -- unwrap it.
00093             return nsxexception->nsexception();
00094         } else {
00095             //  It's a C++ exception -- wrap it in an NSException.
00096             NSData *cppExceptionWrapper = [NSData dataWithBytes:&cppException length:sizeof(cppException)];
00097             NSDictionary *userInfo = [NSDictionary
00098                                         dictionaryWithObject: cppExceptionWrapper
00099                                         forKey:@"std::exception"];
00100             NSString *reason = [NSString stringWithFormat:@"%s: %s", typeid(cppException).name(), cppException->what()];
00101             return [NSException
00102                     exceptionWithName:@"NSException-wrapped std::exception"
00103                     reason:reason
00104                     userInfo:userInfo];
00105         }
00106     }
00107 
00108     /************************************************************************************/
00115         static
00116         void
00117     Raise(
00118         const   std::exception  *cppException )
00119     {
00120         [NSXException::NSExceptionForException( cppException ) raise];
00121     }
00122     
00123     /************************************************************************************/
00130         static
00131         void
00132     Throw(
00133         NSException *objCException )
00134     {
00135         NSDictionary *userInfo = [objCException userInfo];
00136         NSData *cppException = [userInfo valueForKey:@"std::exception"];
00137         if( cppException ) {
00138             std::exception *exception;
00139             [cppException getBytes:&exception];
00140             throw exception;
00141         } else {
00142             throw new NSXException( objCException );
00143         }
00144     }
00145 private:
00146     NSException *nsexception_;
00147 };
00148 
00149 /************************************************************************************/
00162 class   AutoNSExceptionHandler : public _NSHandler2 {
00163 public:
00165     AutoNSExceptionHandler()
00166     :   installed_( true ) {
00167         _NSAddHandler2( this );
00168     }
00169     
00172     ~AutoNSExceptionHandler() {
00173         if( installed_ ) {
00174             _NSRemoveHandler2( this );
00175             installed_ = false;
00176         }
00177     }
00178     
00182     NSException* localException() {
00183         installed_ = false;
00184         return _NSExceptionObjectFromHandler2( this );
00185     }
00186 private:
00187     bool    installed_;
00188 };
00189 
00190 /************************************************************************************/
00216 class   NSXRaisingDestructor    {
00217 public:
00219     NSXRaisingDestructor()
00220     :   nsexception_( nil ){}
00221     
00223     ~NSXRaisingDestructor() {
00224         if( nsexception_ != nil )
00225             [nsexception_ raise];
00226     }
00227     
00229     void arm( NSException *exception ) {
00230         nsexception_ = exception;
00231     }
00232     
00235     void arm( const std::exception *exception ) {
00236         nsexception_ = NSXException::NSExceptionForException( exception );
00237     }
00238 private:
00239     NSException *nsexception_;
00240 };
00241 
00242 /****************************************************************************************
00243 *   
00244 *   Multiline Exception Morphing
00245 *   
00246 ****************************************************************************************/
00247 #pragma mark    -
00248 #pragma mark    (Multiline Exception Morphing Macros)
00249 
00250 /************************************************************************************/
00284 #define NSX_THROW                                   \
00285     {                                               \
00286         AutoNSExceptionHandler  handler_;           \
00287         if( !_NSSETJMP( handler_._state, 0 ) ) {
00288 
00289 /************************************************************************************/
00296 #define NSX_ENDTHROW                                            \
00297         } else {                                                \
00298             NSXException::Throw( handler_.localException() );   \
00299         }                                                       \
00300     }
00301 
00302 /************************************************************************************/
00326 #define NSX_RAISE                                   \
00327     {                                               \
00328         NSXRaisingDestructor raisingDestructor;     \
00329         try {
00330 
00331 /************************************************************************************/
00338 #define NSX_ENDRAISE                            \
00339         } catch( const std::exception *x ) {    \
00340             raisingDestructor.arm( x );         \
00341         }                                       \
00342     }
00343 
00344 /****************************************************************************************
00345 *   
00346 *   Single-line Exception Morphing Macros
00347 *   
00348 ****************************************************************************************/
00349 #pragma mark    -
00350 #pragma mark    (Single-line Exception Morphing Macros)
00351 
00352 /************************************************************************************/
00377 #define ThrowNSX( CODE )                                        \
00378     {                                                           \
00379         AutoNSExceptionHandler  handler_;                       \
00380         if( !_NSSETJMP( handler_._state, 0 ) ) {                \
00381             CODE;                                               \
00382         } else {                                                \
00383             NSXException::Throw( handler_.localException() );   \
00384         }                                                       \
00385     }
00386 
00387 /************************************************************************************/
00410 #define RaiseNSX( CODE )                        \
00411     {                                           \
00412         NSXRaisingDestructor raisingDestructor; \
00413         try {                                   \
00414             CODE;                               \
00415         } catch( const std::exception *x ) {    \
00416             raisingDestructor.arm( x );         \
00417         }                                       \
00418     }
00419 
00420 /****************************************************************************************
00421 *   
00422 *   Scope-Aware Version of NS_DURING. Typically you should use NSX_THROW instead.
00423 *   
00424 ****************************************************************************************/
00425 #pragma mark    -
00426 #pragma mark    (Scope-Aware Version of NS_DURING)
00427 
00428 /************************************************************************************/
00436 #define NSX_DURING                                                      \
00437     {                                                                   \
00438         AutoNSExceptionHandler  handler_;                               \
00439         if( !_NSSETJMP( handler_._state, 0 ) ) {                        
00440 
00441 /************************************************************************************/
00448 #define NSX_HANDLER                                                     \
00449         } else {                                                        \
00450             NSException *localException = handler_.localException();    
00451 
00452 /************************************************************************************/
00459 #define NSX_ENDHANDLER                                                  \
00460             localException = localException;                            \
00461         }                                                               \
00462     }   
00463         
00464 #endif  //  _NSXException_

Generated on Wed Mar 5 09:57:47 2003 for TempFile by doxygen1.2.17