diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index ee927e6db9..352e399d2a 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -325,6 +325,24 @@ SWITCH_DECLARE(switch_status_t) switch_channel_get_scope_variables(switch_channe SWITCH_DECLARE(const char *) switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup, int idx); #define switch_channel_get_variable(_c, _v) switch_channel_get_variable_dup(_c, _v, SWITCH_TRUE, -1) +/*! + \brief Retrieve a copy of a variable from a given channel. switch_safe_free() call will be required. + \param channel channel to retrieve variable from + \param varname the name of the variable + \return a strdup copy the value of the requested variable without using a memory pool. +*/ +SWITCH_DECLARE(const char *) switch_channel_get_variable_strdup(switch_channel_t *channel, const char *varname); + +/*! + \brief Retrieve a variable from a given channel to a pre-allocated buffer without using a memory pool. + \param channel channel to retrieve variable from + \param varname the name of the variable + \param buf a pre allocated buffer to put the value to + \param buflen size of the buffer + \return SWITCH_STATUS_SUCCESS if the value was copied to the buffer and it is not NULL, SWITCH_STATUS_FALSE otherwise. +*/ +SWITCH_DECLARE(switch_status_t) switch_channel_get_variable_buf(switch_channel_t *channel, const char *varname, char *buf, switch_size_t buflen); + SWITCH_DECLARE(switch_status_t) switch_channel_get_variables(switch_channel_t *channel, switch_event_t **event); SWITCH_DECLARE(switch_status_t) switch_channel_get_variables_prefix(switch_channel_t *channel, const char *prefix, switch_event_t **event); SWITCH_DECLARE(switch_status_t) switch_channel_pass_callee_id(switch_channel_t *channel, switch_channel_t *other_channel); diff --git a/src/switch_channel.c b/src/switch_channel.c index 6f0ad7a964..9c7b8e433d 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -1022,6 +1022,24 @@ SWITCH_DECLARE(const char *) switch_channel_get_variable_dup(switch_channel_t *c return r; } +SWITCH_DECLARE(const char *) switch_channel_get_variable_strdup(switch_channel_t *channel, const char *varname) +{ + const char *value = switch_channel_get_variable_dup(channel, varname, SWITCH_FALSE, -1); + + return value ? (const char *)strdup(value) : NULL; +} + +SWITCH_DECLARE(switch_status_t) switch_channel_get_variable_buf(switch_channel_t *channel, const char *varname, char *buf, switch_size_t buflen) +{ + const char *value = switch_channel_get_variable_dup(channel, varname, SWITCH_FALSE, -1); + + if (value && buf && buflen && switch_copy_string(buf, value, buflen)) { + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} + SWITCH_DECLARE(const char *) switch_channel_get_variable_partner(switch_channel_t *channel, const char *varname) { const char *uuid; diff --git a/tests/unit/switch_core.c b/tests/unit/switch_core.c index e51c4e2b1d..2aa0f10231 100644 --- a/tests/unit/switch_core.c +++ b/tests/unit/switch_core.c @@ -416,6 +416,42 @@ FST_CORE_BEGIN("./conf") fst_requires(hash == NULL); } FST_TEST_END() + + FST_SESSION_BEGIN(test_switch_channel_get_variable_strdup) + { + const char *val; + switch_channel_t *channel = switch_core_session_get_channel(fst_session); + + fst_check(channel); + + switch_channel_set_variable(channel, "test_var", "test_value"); + + fst_check(!switch_channel_get_variable_strdup(channel, "test_var_does_not_exist")); + + val = switch_channel_get_variable_strdup(channel, "test_var"); + + fst_check(val); + fst_check_string_equals(val, "test_value"); + + free((char *)val); + } + FST_SESSION_END() + + FST_SESSION_BEGIN(test_switch_channel_get_variable_buf) + { + char buf[16] = { 0 }; + switch_channel_t *channel = switch_core_session_get_channel(fst_session); + + fst_check(channel); + + switch_channel_set_variable(channel, "test_var", "test_value"); + + fst_check(switch_channel_get_variable_buf(channel, "test_var", buf, sizeof(buf)) == SWITCH_STATUS_SUCCESS); + fst_check_string_equals(buf, "test_value"); + + fst_check(switch_channel_get_variable_buf(channel, "test_var_does_not_exist", buf, sizeof(buf)) == SWITCH_STATUS_FALSE); + } + FST_SESSION_END() } FST_SUITE_END() }