[Freeswitch-svn] [commit] r7312 - in freeswitch/trunk/src: . include
Freeswitch SVN
anthm at freeswitch.org
Mon Jan 21 13:17:12 EST 2008
Author: anthm
Date: Mon Jan 21 13:17:12 2008
New Revision: 7312
Modified:
freeswitch/trunk/src/include/switch_event.h
freeswitch/trunk/src/switch_event.c
Log:
add func to expand event headers from a template string
Modified: freeswitch/trunk/src/include/switch_event.h
==============================================================================
--- freeswitch/trunk/src/include/switch_event.h (original)
+++ freeswitch/trunk/src/include/switch_event.h Mon Jan 21 13:17:12 2008
@@ -283,6 +283,7 @@
\note the body parameter can be shadowed by the switch_event_reserve_subclass_detailed function
*/
SWITCH_DECLARE(switch_status_t) switch_event_add_body(switch_event_t *event, const char *fmt, ...) PRINTF_FUNCTION(2, 3);
+SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const char *in);
SWITCH_DECLARE(switch_status_t) switch_event_create_pres_in_detailed(_In_z_ char *file, _In_z_ char *func, _In_ int line,
_In_z_ const char *proto, _In_z_ const char *login,
Modified: freeswitch/trunk/src/switch_event.c
==============================================================================
--- freeswitch/trunk/src/switch_event.c (original)
+++ freeswitch/trunk/src/switch_event.c Mon Jan 21 13:17:12 2008
@@ -1007,6 +1007,267 @@
return SWITCH_STATUS_MEMERR;
}
+
+#define resize(l) {\
+char *dp;\
+olen += (len + l + block);\
+cpos = c - data;\
+if ((dp = realloc(data, olen))) {\
+ data = dp;\
+ c = data + cpos;\
+ memset(c, 0, olen - cpos);\
+ }} \
+
+SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const char *in)
+{
+ char *p, *c = NULL;
+ char *data, *indup;
+ size_t sp = 0, len = 0, olen = 0, vtype = 0, br = 0, cpos, block = 128;
+ const char *q, *sub_val = NULL;
+ char *cloned_sub_val = NULL;
+ char *func_val = NULL;
+ int nv = 0;
+
+ q = in;
+ while(q && *q) {
+ if (!(p = strchr(q, '$'))) {
+ break;
+ }
+
+ if (*(p-1) == '\\') {
+ q = p + 1;
+ continue;
+ }
+
+ if (*(p+1) != '{') {
+ q = p + 1;
+ continue;
+ }
+
+ nv = 1;
+ break;
+ }
+
+ if (!nv) {
+ return (char *)in;
+ }
+
+ nv = 0;
+ olen = strlen(in) + 1;
+ indup = strdup(in);
+
+ if ((data = malloc(olen))) {
+ memset(data, 0, olen);
+ c = data;
+ for (p = indup; p && *p; p++) {
+ vtype = 0;
+
+ if (*p == '\\') {
+ if (*(p + 1) == '$') {
+ nv = 1;
+ } else if (*(p + 1) == '\\') {
+ *c++ = *p++;
+ len++;
+ continue;
+ }
+ p++;
+ }
+
+ if (*p == '$' && !nv) {
+ if (*(p+1)) {
+ if (*(p+1) == '{') {
+ vtype = 1;
+ } else {
+ nv = 1;
+ }
+ } else {
+ nv = 1;
+ }
+ }
+
+ if (nv) {
+ *c++ = *p;
+ len++;
+ nv = 0;
+ continue;
+ }
+
+ if (vtype) {
+ char *s = p, *e, *vname, *vval = NULL;
+ size_t nlen;
+
+ s++;
+
+ if (vtype == 1 && *s == '{') {
+ br = 1;
+ s++;
+ }
+
+ e = s;
+ vname = s;
+ while (*e) {
+ if (br == 1 && *e == '}') {
+ br = 0;
+ *e++ = '\0';
+ break;
+ }
+
+ if (br > 0) {
+ if (e != s && *e == '{') {
+ br++;
+ } else if (br > 1 && *e == '}') {
+ br--;
+ }
+ }
+
+ e++;
+ }
+ p = e;
+
+ if ((vval = strchr(vname, '('))) {
+ e = vval - 1;
+ *vval++ = '\0';
+ while(*e == ' ') {
+ *e-- = '\0';
+ }
+ e = vval;
+ br = 1;
+ while(e && *e) {
+ if (*e == '(') {
+ br++;
+ } else if (br > 1 && *e == ')') {
+ br--;
+ } else if (br == 1 && *e == ')') {
+ *e = '\0';
+ break;
+ }
+ e++;
+ }
+
+ vtype = 2;
+ }
+
+ if (vtype == 1) {
+ char *expanded = NULL;
+ int offset = 0;
+ int ooffset = 0;
+ char *ptr;
+
+ if ((expanded = switch_event_expand_headers(event, (char *)vname)) == vname) {
+ expanded = NULL;
+ } else {
+ vname = expanded;
+ }
+ if ((ptr = strchr(vname, ':'))) {
+ *ptr++ = '\0';
+ offset = atoi(ptr);
+ if ((ptr = strchr(ptr, ':'))) {
+ ptr++;
+ ooffset = atoi(ptr);
+ }
+ }
+
+ if (!(sub_val = switch_event_get_header(event, vname))) {
+ sub_val = switch_core_get_variable(vname);
+ }
+
+ if (offset || ooffset) {
+ cloned_sub_val = strdup(sub_val);
+ switch_assert(cloned_sub_val);
+ sub_val = cloned_sub_val;
+ }
+
+ if (offset >= 0) {
+ sub_val += offset;
+ } else if ((size_t)abs(offset) <= strlen(sub_val)) {
+ sub_val = cloned_sub_val + (strlen(cloned_sub_val) + offset);
+ }
+
+ if (ooffset > 0 && (size_t)ooffset < strlen(sub_val)) {
+ if ((ptr = (char *)sub_val + ooffset)) {
+ *ptr = '\0';
+ }
+ }
+
+ switch_safe_free(expanded);
+ } else {
+ switch_stream_handle_t stream = { 0 };
+ char *expanded = NULL;
+
+ SWITCH_STANDARD_STREAM(stream);
+
+ if (stream.data) {
+ char *expanded_vname = NULL;
+
+ if ((expanded_vname = switch_event_expand_headers(event, (char *)vname)) == vname) {
+ expanded_vname = NULL;
+ } else {
+ vname = expanded_vname;
+ }
+
+ if ((expanded = switch_event_expand_headers(event, vval)) == vval) {
+ expanded = NULL;
+ } else {
+ vval = expanded;
+ }
+
+ if (switch_api_execute(vname, vval, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
+ func_val = stream.data;
+ sub_val = func_val;
+ } else {
+ free(stream.data);
+ }
+
+ switch_safe_free(expanded);
+ switch_safe_free(expanded_vname);
+
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+ free(data);
+ free(indup);
+ return (char *)in;
+ }
+ }
+ if ((nlen = sub_val ? strlen(sub_val) : 0)) {
+ if (len + nlen >= olen) {
+ resize(nlen);
+ }
+
+ len += nlen;
+ strcat(c, sub_val);
+ c += nlen;
+ }
+
+ switch_safe_free(func_val);
+ switch_safe_free(cloned_sub_val);
+ sub_val = NULL;
+ vname = NULL;
+ vtype = 0;
+ br = 0;
+ }
+ if (len + 1 >= olen) {
+ resize(1);
+ }
+
+ if (sp) {
+ *c++ = ' ';
+ sp = 0;
+ len++;
+ }
+
+ if (*p == '$') {
+ p--;
+ } else {
+ *c++ = *p;
+ len++;
+ }
+ }
+ }
+ free(indup);
+
+ return data;
+}
+
/* For Emacs:
* Local Variables:
* mode:c
More information about the Freeswitch-svn
mailing list