⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 except.h

📁 基于sip协议的网络电话源码
💻 H
字号:
/* $Id: except.h 974 2007-02-19 01:13:53Z bennylp $ *//*  * Copyright (C)2003-2007 Benny Prijono <benny@prijono.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  */#ifndef __PJ_EXCEPTION_H__#define __PJ_EXCEPTION_H__/** * @file except.h * @brief Exception Handling in C. */#include <pj/types.h>#include <pj/compat/setjmp.h>PJ_BEGIN_DECL/** * @defgroup PJ_EXCEPT Exception Handling * @ingroup PJ_MISC * @{ * * \section pj_except_sample_sec Quick Example * * For the impatient, take a look at some examples: *  - @ref page_pjlib_samples_except_c *  - @ref page_pjlib_exception_test * * \section pj_except_except Exception Handling * * This module provides exception handling syntactically similar to C++ in * C language. In Win32 systems, it uses Windows Structured Exception * Handling (SEH) if macro PJ_EXCEPTION_USE_WIN32_SEH is non-zero. * Otherwise it will use setjmp() and longjmp(). * * On some platforms where setjmp/longjmp is not available, setjmp/longjmp  * implementation is provided. See <pj/compat/setjmp.h> for compatibility. * * The exception handling mechanism is completely thread safe, so the exception * thrown by one thread will not interfere with other thread. * * CAVEATS: *  - unlike C++ exception, the scheme here won't call destructors of local *    objects if exception is thrown. Care must be taken when a function *    hold some resorce such as pool or mutex etc. *  - You CAN NOT make nested exception in one single function without using *    a nested PJ_USE_EXCEPTION. *  - You can not provide more than PJ_CATCH or PJ_CATCH_ANY nor use PJ_CATCH *    and PJ_CATCH_ANY for a single PJ_TRY. *  - Exceptions will always be caught by the first handler (unlike C++ where *    exception is only caught if the type matches. * * The exception handling constructs are similar to C++. The blocks will be * constructed similar to the following sample: * * \verbatim   #define NO_MEMORY     1   #define SYNTAX_ERROR  2     int sample1()   {      PJ_USE_EXCEPTION;  // declare local exception stack.        PJ_TRY {        ...// do something..      }      PJ_CATCH(NO_MEMORY) {        ... // handle exception 1      }      PJ_END;   }   int sample2()   {      PJ_USE_EXCEPTION;  // declare local exception stack.        PJ_TRY {        ...// do something..      }      PJ_CATCH_ANY {         if (PJ_GET_EXCEPTION() == NO_MEMORY)	    ...; // handle no memory situation	 else if (PJ_GET_EXCEPTION() == SYNTAX_ERROR)	    ...; // handle syntax error      }      PJ_END;   }   \endverbatim * * The above sample uses hard coded exception ID. It is @b strongly * recommended that applications request a unique exception ID instead * of hard coded value like above. * * \section pj_except_reg Exception ID Allocation * * To ensure that exception ID (number) are used consistently and to * prevent ID collisions in an application, it is strongly suggested that  * applications allocate an exception ID for each possible exception * type. As a bonus of this process, the application can identify * the name of the exception when the particular exception is thrown. * * Exception ID management are performed with the following APIs: *  - #pj_exception_id_alloc(). *  - #pj_exception_id_free(). *  - #pj_exception_id_name(). * * * PJLIB itself automatically allocates one exception id, i.e. * #PJ_NO_MEMORY_EXCEPTION which is declared in <pj/pool.h>. This exception * ID is raised by default pool policy when it fails to allocate memory. * * \section PJ_EX_KEYWORDS Keywords * * \subsection PJ_THROW PJ_THROW(expression) * Throw an exception. The expression thrown is an integer as the result of * the \a expression. This keyword can be specified anywhere within the  * program. * * \subsection PJ_USE_EXCEPTION PJ_USE_EXCEPTION * Specify this in the variable definition section of the function block  * (or any blocks) to specify that the block has \a PJ_TRY/PJ_CATCH exception  * block.  * Actually, this is just a macro to declare local variable which is used to * push the exception state to the exception stack. * Note: you must specify PJ_USE_EXCEPTION as the last statement in the * local variable declarations, since it may evaluate to nothing. * * \subsection PJ_TRY PJ_TRY * The \a PJ_TRY keyword is typically followed by a block. If an exception is * thrown in this block, then the execution will resume to the \a PJ_CATCH  * handler. * * \subsection PJ_CATCH PJ_CATCH(expression) * The \a PJ_CATCH is normally followed by a block. This block will be executed * if the exception being thrown is equal to the expression specified in the * \a PJ_CATCH. * * \subsection PJ_CATCH_ANY PJ_CATCH_ANY * The \a PJ_CATCH is normally followed by a block. This block will be executed * if any exception was raised in the TRY block. * * \subsection PJ_END PJ_END * Specify this keyword to mark the end of \a PJ_TRY / \a PJ_CATCH blocks. * * \subsection PJ_GET_EXCEPTION PJ_GET_EXCEPTION(void) * Get the last exception thrown. This macro is normally called inside the * \a PJ_CATCH or \a PJ_CATCH_ANY block, altough it can be used anywhere where * the \a PJ_USE_EXCEPTION definition is in scope. * *  * \section pj_except_examples_sec Examples * * For some examples on how to use the exception construct, please see: *  - @ref page_pjlib_samples_except_c *  - @ref page_pjlib_exception_test *//** * Allocate a unique exception id. * Applications don't have to allocate a unique exception ID before using * the exception construct. However, by doing so it ensures that there is * no collisions of exception ID. * * As a bonus, when exception number is acquired through this function, * the library can assign name to the exception (only if  * PJ_HAS_EXCEPTION_NAMES is enabled (default is yes)) and find out the * exception name when it catches an exception. * * @param name      Name to be associated with the exception ID. * @param id        Pointer to receive the ID. * * @return          PJ_SUCCESS on success or PJ_ETOOMANY if the library  *                  is running out out ids. */PJ_DECL(pj_status_t) pj_exception_id_alloc(const char *name,                                           pj_exception_id_t *id);/** * Free an exception id. * * @param id        The exception ID. * * @return          PJ_SUCCESS or the appropriate error code. */PJ_DECL(pj_status_t) pj_exception_id_free(pj_exception_id_t id);/** * Retrieve name associated with the exception id. * * @param id        The exception ID. * * @return          The name associated with the specified ID. */PJ_DECL(const char*) pj_exception_id_name(pj_exception_id_t id);/** @} */#if defined(PJ_EXCEPTION_USE_WIN32_SEH) && PJ_EXCEPTION_USE_WIN32_SEH != 0/***************************************************************************** ** ** IMPLEMENTATION OF EXCEPTION USING WINDOWS SEH ** ****************************************************************************/#define WIN32_LEAN_AND_MEAN#include <windows.h>PJ_IDECL_NO_RETURN(void)pj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN{    RaiseException(id,1,0,NULL);}#define PJ_USE_EXCEPTION    #define PJ_TRY		    __try#define PJ_CATCH(id)	    __except(GetExceptionCode()==id ? \				      EXCEPTION_EXECUTE_HANDLER : \				      EXCEPTION_CONTINUE_SEARCH)#define PJ_CATCH_ANY	    __except(EXCEPTION_EXECUTE_HANDLER)#define PJ_END		    #define PJ_THROW(id)	    pj_throw_exception_(id)#define PJ_GET_EXCEPTION()  GetExceptionCode()#else/***************************************************************************** ** ** IMPLEMENTATION OF EXCEPTION USING GENERIC SETJMP/LONGJMP ** ****************************************************************************//** * This structure (which should be invisible to user) manages the TRY handler * stack. */struct pj_exception_state_t{    struct pj_exception_state_t *prev;  /**< Previous state in the list. */    pj_jmp_buf state;                   /**< jmp_buf.                    */};/** * Throw exception. * @param id    Exception Id. */PJ_DECL_NO_RETURN(void) pj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN;/** * Push exception handler. */PJ_DECL(void) pj_push_exception_handler_(struct pj_exception_state_t *rec);/** * Pop exception handler. */PJ_DECL(void) pj_pop_exception_handler_(void);/** * Declare that the function will use exception. * @hideinitializer */#define PJ_USE_EXCEPTION    struct pj_exception_state_t pj_x_except__; int pj_x_code__/** * Start exception specification block. * @hideinitializer */#define PJ_TRY		    if (1) { \				pj_push_exception_handler_(&pj_x_except__); \				pj_x_code__ = pj_setjmp(pj_x_except__.state); \				if (pj_x_code__ == 0)/** * Catch the specified exception Id. * @param id    The exception number to catch. * @hideinitializer */#define PJ_CATCH(id)	    else if (pj_x_code__ == (id))/** * Catch any exception number. * @hideinitializer */#define PJ_CATCH_ANY	    else/** * End of exception specification block. * @hideinitializer */#define PJ_END			pj_pop_exception_handler_(); \			    } else {}/** * Throw exception. * @param exception_id  The exception number. * @hideinitializer */#define PJ_THROW(exception_id)	pj_throw_exception_(exception_id)/** * Get current exception. * @return      Current exception code. * @hideinitializer */#define PJ_GET_EXCEPTION()	(pj_x_code__)#endif	/* PJ_EXCEPTION_USE_WIN32_SEH */PJ_END_DECL#endif	/* __PJ_EXCEPTION_H__ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -