summaryrefslogtreecommitdiff
path: root/pjlib
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-02-02 19:15:03 +0000
committerBenny Prijono <bennylp@teluu.com>2006-02-02 19:15:03 +0000
commit6cbba81e8937d6793705608e7e68e83ec950dd2a (patch)
treeefc1d00495b6e80bee2bfe02ef7a9951a40ca2c0 /pjlib
parent0d61adeb5f784b45f76d76dad9974f4111fb3c8c (diff)
Added framework for attaching custom error message handler
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@128 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib')
-rw-r--r--pjlib/include/pj/errno.h23
-rw-r--r--pjlib/src/pj/errno.c67
2 files changed, 85 insertions, 5 deletions
diff --git a/pjlib/include/pj/errno.h b/pjlib/include/pj/errno.h
index ffb72c19..83e0c800 100644
--- a/pjlib/include/pj/errno.h
+++ b/pjlib/include/pj/errno.h
@@ -106,6 +106,29 @@ PJ_DECL(void) pj_set_netos_error(pj_status_t code);
PJ_DECL(pj_str_t) pj_strerror( pj_status_t statcode,
char *buf, pj_size_t bufsize);
+/**
+ * Register strerror message handler for the specified error space.
+ * Application can register its own handler to supply the error message
+ * for the specified error code range. This handler will be called
+ * by #pj_strerror().
+ *
+ * @param start_code The starting error code where the handler should
+ * be called to retrieve the error message.
+ * @param err_space The size of error space. The error code range then
+ * will fall in start_code to start_code+err_space-1
+ * range.
+ * @param f The handler to be called when #pj_strerror() is
+ * supplied with error code that falls into this range.
+ *
+ * @return PJ_SUCCESS or the specified error code. The
+ * registration may fail when the error space has been
+ * occupied by other handler, or when there are too many
+ * handlers registered to PJLIB.
+ */
+PJ_DECL(pj_status_t) pj_register_strerror(pj_status_t start_code,
+ pj_status_t err_space,
+ pj_str_t (*f)(pj_status_t,char*,
+ pj_size_t));
/**
* @hideinitializer
diff --git a/pjlib/src/pj/errno.c b/pjlib/src/pj/errno.c
index d214d687..9c2d072f 100644
--- a/pjlib/src/pj/errno.c
+++ b/pjlib/src/pj/errno.c
@@ -18,6 +18,7 @@
*/
#include <pj/errno.h>
#include <pj/string.h>
+#include <pj/assert.h>
#include <pj/compat/sprintf.h>
/* Prototype for platform specific error message, which will be defined
@@ -26,6 +27,18 @@
extern int platform_strerror( pj_os_err_type code,
char *buf, pj_size_t bufsize );
+#define PJLIB_MAX_ERR_MSG_HANDLER 8
+
+/* Error message handler. */
+static unsigned err_msg_hnd_cnt;
+static struct err_msg_hnd
+{
+ pj_status_t begin;
+ pj_status_t end;
+ pj_str_t (*strerror)(pj_status_t, char*, pj_size_t);
+
+} err_msg_hnd[PJLIB_MAX_ERR_MSG_HANDLER];
+
/* PJLIB's own error codes/messages */
static const struct
{
@@ -76,6 +89,45 @@ static int pjlib_error(pj_status_t code, char *buf, pj_size_t size)
return 3;
}
+#define IN_RANGE(val,start,end) ((val)>=(start) && (val)<(end))
+
+/* Register strerror handle. */
+PJ_DECL(pj_status_t) pj_register_strerror(pj_status_t start,
+ pj_status_t space,
+ pj_str_t (*f)(pj_status_t,char*,
+ pj_size_t))
+{
+ unsigned i;
+
+ /* Check arguments. */
+ PJ_ASSERT_RETURN(start && space && f, PJ_EINVAL);
+
+ /* Check if there aren't too many handlers registered. */
+ PJ_ASSERT_RETURN(err_msg_hnd_cnt < PJ_ARRAY_SIZE(err_msg_hnd),
+ PJ_ETOOMANY);
+
+ /* Start error must be greater than PJ_ERRNO_START_USER */
+ PJ_ASSERT_RETURN(start >= PJ_ERRNO_START_USER, PJ_EEXISTS);
+
+ /* Check that no existing handler has covered the specified range. */
+ for (i=0; i<err_msg_hnd_cnt; ++i) {
+ if (IN_RANGE(start, err_msg_hnd[i].begin, err_msg_hnd[i].end) ||
+ IN_RANGE(start+space-1, err_msg_hnd[i].begin, err_msg_hnd[i].end))
+ {
+ return PJ_EEXISTS;
+ }
+ }
+
+ /* Register the handler. */
+ err_msg_hnd[err_msg_hnd_cnt].begin = start;
+ err_msg_hnd[err_msg_hnd_cnt].end = start + space;
+ err_msg_hnd[err_msg_hnd_cnt].strerror = f;
+
+ ++err_msg_hnd_cnt;
+
+ return PJ_SUCCESS;
+}
+
/*
* pj_strerror()
*/
@@ -85,6 +137,8 @@ PJ_DEF(pj_str_t) pj_strerror( pj_status_t statcode,
int len = -1;
pj_str_t errstr;
+ pj_assert(buf && bufsize);
+
if (statcode < PJ_ERRNO_START + PJ_ERRNO_SPACE_SIZE) {
len = pj_snprintf( buf, bufsize, "Unknown error %d", statcode);
@@ -94,12 +148,15 @@ PJ_DEF(pj_str_t) pj_strerror( pj_status_t statcode,
} else if (statcode < PJ_ERRNO_START_SYS + PJ_ERRNO_SPACE_SIZE) {
len = platform_strerror(PJ_STATUS_TO_OS(statcode), buf, bufsize);
- } else if (statcode < PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE) {
- len = pj_snprintf( buf, bufsize, "User error %d", statcode);
-
} else {
- len = pj_snprintf( buf, bufsize, "Invalid error %d", statcode);
-
+ unsigned i;
+
+ /* Find user handler to get the error message. */
+ for (i=0; i<err_msg_hnd_cnt; ++i) {
+ if (IN_RANGE(statcode, err_msg_hnd[i].begin, err_msg_hnd[i].end)) {
+ return (*err_msg_hnd[i].strerror)(statcode, buf, bufsize);
+ }
+ }
}
if (len < 1) {