]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
update on array patch
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 26 May 2011 14:55:41 +0000 (09:55 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Thu, 26 May 2011 15:00:06 +0000 (10:00 -0500)
libs/esl/src/esl.c
libs/esl/src/esl_event.c
libs/esl/src/include/esl_event.h
src/include/switch_event.h
src/switch_event.c

index 1a4d988a234f45b2e5f326edf2f74619f8d4a751..ef8d7c1cb1fa6f9dc235c6750ad4fa6071394c56 100644 (file)
@@ -1025,52 +1025,6 @@ static esl_ssize_t handle_recv(esl_handle_t *handle, void *data, esl_size_t data
        return recv(handle->sock, data, datalen, 0);
 }
 
-static int add_array(esl_event_t *event, const char *var, const char *val)
-{
-       char *data;
-       char **array;
-       int idx;
-       int max = 0;
-       int len;
-       const char *p;
-       int i;
-
-       if (strlen(val) < 8) {
-               return -1;
-       }
-
-       p = val + 7;
-
-       while((p = strstr(p, "::"))) {
-               max++;
-               p += 2;
-       }
-
-       if (!max) {
-               return -2;
-       }
-
-       data = strdup(val + 7);
-       
-       len = (sizeof(char *) * max) + 1;
-
-       array = malloc(len);
-       memset(array, 0, len);
-       
-       idx = esl_separate_string_string(data, "::", array, max);
-       
-       for(i = 0; i < max; i++) {
-               esl_event_add_header_string(event, ESL_STACK_PUSH, var, array[i]);
-       }
-
-       free(array);
-       free(data);
-
-       return 0;
-}
-
-
-
 ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_event_t **save_event)
 {
        char *c;
@@ -1135,7 +1089,7 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
                                                        esl_url_decode(hval);
                                                        esl_log(ESL_LOG_DEBUG, "RECV HEADER [%s] = [%s]\n", hname, hval);
                                                        if (!strncmp(hval, "ARRAY::", 7)) {
-                                                               add_array(revent, hname, hval);
+                                                               esl_event_add_array(revent, hname, hval);
                                                        } else {
                                                                esl_event_add_header_string(revent, ESL_STACK_BOTTOM, hname, hval);
                                                        }
@@ -1269,7 +1223,7 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
                                                }
 
                                                if (!strncmp(hval, "ARRAY::", 7)) {
-                                                       add_array(handle->last_ievent, hname, hval);
+                                                       esl_event_add_array(handle->last_ievent, hname, hval);
                                                } else {
                                                        esl_event_add_header_string(handle->last_ievent, ESL_STACK_BOTTOM, hname, hval);
                                                }
index 75d9cad8c96e4e0c01a72d3fbf93dc9257729326..e1b266399532f99813ead09f5d0af792b8eaa4e4 100644 (file)
@@ -338,30 +338,9 @@ ESL_DECLARE(esl_status_t) esl_event_del_header_val(esl_event_t *event, const cha
        return status;
 }
 
-static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t stack, const char *header_name, char *data)
+static esl_event_header_t *new_header(const char *header_name)
 {
-       esl_event_header_t *header = NULL;
-       esl_ssize_t hlen = -1;
-       int exists = 0;
-       
-       if ((stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT) || esl_test_flag(event, ESL_EF_CONTAINS_ARRAYS)) {
-
-               if ((header = esl_event_get_header_ptr(event, header_name))) {
-                       
-                       if (!(stack & ESL_STACK_PUSH) && !(stack & ESL_STACK_UNSHIFT) && header->idx) {
-                               stack |= ESL_STACK_PUSH;
-                       }
-
-                       if ((stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT)) {
-                               exists++;
-                               stack &= ~(ESL_STACK_TOP | ESL_STACK_BOTTOM);
-                       } else {
-                               header = NULL;
-                       }
-               }
-       }
-
-       if (!header) {
+       esl_event_header_t *header;
 
 #ifdef ESL_EVENT_RECYCLE
                void *pop;
@@ -373,16 +352,144 @@ static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t st
                        esl_assert(header);
 #ifdef ESL_EVENT_RECYCLE
                }
-#endif
+#endif 
+
+               memset(header, 0, sizeof(*header));
+               header->name = DUP(header_name);
+
+               return header;
+
+}
+
+ESL_DECLARE(int) esl_event_add_array(esl_event_t *event, const char *var, const char *val)
+{
+       char *data;
+       char **array;
+       int idx;
+       int max = 0;
+       int len;
+       const char *p;
+       int i;
+
+       if (strlen(val) < 8) {
+               return -1;
+       }
+
+       p = val + 7;
+
+       max = 1;
+
+       while((p = strstr(p, "|:"))) {
+               max++;
+               p += 2;
+       }
+
+       if (!max) {
+               return -2;
+       }
+
+       data = strdup(val + 7);
        
+       len = (sizeof(char *) * max) + 1;
+       array = malloc(len);
+       memset(array, 0, len);
+       
+       idx = esl_separate_string_string(data, "|:", array, max);
+       
+       for(i = 0; i < max; i++) {
+               esl_event_add_header_string(event, ESL_STACK_PUSH, var, array[i]);
+       }
+
+       free(array);
+       free(data);
 
+       return 0;
+}
+
+static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t stack, const char *header_name, char *data)
+{
+       esl_event_header_t *header = NULL;
+       esl_ssize_t hlen = -1;
+       int exists = 0, fly = 0;
+       char *index_ptr;
+       int index = 0;
+       char *real_header_name = NULL;
+
+       if ((index_ptr = strchr(header_name, '['))) {
+               index_ptr++;
+               index = atoi(index_ptr);
+               real_header_name = DUP(header_name);
+               if ((index_ptr = strchr(real_header_name, '['))) {
+                       *index_ptr++ = '\0';
+               }
+               header_name = real_header_name;
+       }
+       
+       if (index_ptr || (stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT)) {
+               
+               if (!(header = esl_event_get_header_ptr(event, header_name)) && index_ptr) {
+
+                       header = new_header(header_name);
+
+                       if (esl_test_flag(event, ESL_EF_UNIQ_HEADERS)) {
+                               esl_event_del_header(event, header_name);
+                       }
+
+                       fly++;
+               }
+               
+               if ((header = esl_event_get_header_ptr(event, header_name))) {
+                       
+                       if (index_ptr) {
+                               if (index > -1 && index <= 4000) {
+                                       if (index < header->idx) {
+                                               FREE(header->array[index]);
+                                               header->array[index] = DUP(data);
+                                       } else {
+                                               int i;
+                                               char **m;
+                                       
+                                               m = realloc(header->array, sizeof(char *) * (index + 1));
+                                               esl_assert(m);
+                                               header->array = m;
+                                               for (i = header->idx; i < index; i++) {
+                                                       m[i] = DUP("");
+                                               }
+                                               m[index] = DUP(data);
+                                               header->idx = index + 1;
+                                               if (!fly) {
+                                                       exists = 1;
+                                               }
+
+                                               goto redraw;
+                                       }
+                               }
+                               goto end;
+                       } else {
+                               if ((stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT)) {
+                                       exists++;
+                                       stack &= ~(ESL_STACK_TOP | ESL_STACK_BOTTOM);
+                               } else {
+                                       header = NULL;
+                               }
+                       }
+               }
+       }
+
+
+       if (!header) {
                if (esl_test_flag(event, ESL_EF_UNIQ_HEADERS)) {
                        esl_event_del_header(event, header_name);
                }
 
-               memset(header, 0, sizeof(*header));
+               if (strstr(data, "ARRAY::")) {
+                       esl_event_add_array(event, header_name, data);
+                       FREE(data);
+                       goto end;
+               }
 
-               header->name = DUP(header_name);
+
+               header = new_header(header_name);
        }
        
        if ((stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT)) {
@@ -391,8 +498,6 @@ static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t st
                char *hv;
                int i = 0, j = 0;
 
-               esl_set_flag(event, ESL_EF_CONTAINS_ARRAYS);
-
                if (header->value && !header->idx) {
                        m = malloc(sizeof(char *));
                        esl_assert(m);
@@ -419,6 +524,8 @@ static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t st
                header->idx++;          
                header->array = m;
 
+       redraw:
+               len = 0;
                for(j = 0; j < header->idx; j++) {
                        len += strlen(header->array[j]) + 2;
                }
@@ -428,9 +535,10 @@ static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t st
                        hv = realloc(header->value, len);
                        esl_assert(hv);
                        header->value = hv;
+
                        esl_snprintf(header->value, len, "ARRAY::");
                        for(j = 0; j < header->idx; j++) {
-                               esl_snprintf(header->value + strlen(header->value), len - strlen(header->value), "%s%s", j == 0 ? "" : "::", header->array[j]);
+                               esl_snprintf(header->value + strlen(header->value), len - strlen(header->value), "%s%s", j == 0 ? "" : "|:", header->array[j]);
                        }
                }
 
@@ -458,6 +566,10 @@ static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t st
                }
        }
 
+ end:
+
+       esl_safe_free(real_header_name);
+
        return ESL_SUCCESS;
 }
 
index 10af7264b9e4a52a31143d32889dd00ebd033583..d6be0470e88004d6dbb9427eedeb82e51c5ecc20 100644 (file)
@@ -180,8 +180,7 @@ struct esl_event {
 };
 
 typedef enum {
-       ESL_EF_UNIQ_HEADERS = (1 << 0),
-       ESL_EF_CONTAINS_ARRAYS = (1 << 1)
+       ESL_EF_UNIQ_HEADERS = (1 << 0)
 } esl_event_flag_t;
 
 
@@ -234,6 +233,8 @@ ESL_DECLARE(char *)esl_event_get_body(esl_event_t *event);
 ESL_DECLARE(esl_status_t) esl_event_add_header(esl_event_t *event, esl_stack_t stack,
                                                                                           const char *header_name, const char *fmt, ...); //PRINTF_FUNCTION(4, 5);
 
+ESL_DECLARE(int) esl_event_add_array(esl_event_t *event, const char *var, const char *val);
+
 /*!
   \brief Add a string header to an event
   \param event the event to add the header to
index 4c5a3be931273d3368784e204ed2fefd72b0ec13..c6b1d64c35ae8a44dca5d59a9623d9ad9ed09dfc 100644 (file)
@@ -103,8 +103,7 @@ struct switch_event {
 };
 
 typedef enum {
-       EF_UNIQ_HEADERS = (1 << 0),
-       EF_CONTAINS_ARRAYS = (1 << 1),
+       EF_UNIQ_HEADERS = (1 << 0)
 } switch_event_flag_t;
 
 
@@ -192,7 +191,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_add_header_string(switch_event_t *e
 
 SWITCH_DECLARE(switch_status_t) switch_event_del_header_val(switch_event_t *event, const char *header_name, const char *val);
 #define switch_event_del_header(_e, _h) switch_event_del_header_val(_e, _h, NULL)
-
+SWITCH_DECLARE(int) switch_event_add_array(switch_event_t *event, const char *var, const char *val);
 /*!
   \brief Destroy an event
   \param event pointer to the pointer to event to destroy
index c414107664edf5be43ec34be33b9ae86e4fc5a0a..5bff7a940041aa09be4688e7374842511d5cc6e0 100644 (file)
@@ -829,6 +829,74 @@ SWITCH_DECLARE(switch_status_t) switch_event_del_header_val(switch_event_t *even
        return status;
 }
 
+static switch_event_header_t *new_header(const char *header_name)
+{
+       switch_event_header_t *header;
+
+#ifdef SWITCH_EVENT_RECYCLE
+               void *pop;
+               if (switch_queue_trypop(EVENT_HEADER_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) {
+                       header = (switch_event_header_t *) pop;
+               } else {
+#endif
+                       header = ALLOC(sizeof(*header));
+                       switch_assert(header);
+#ifdef SWITCH_EVENT_RECYCLE
+               }
+#endif 
+
+               memset(header, 0, sizeof(*header));
+               header->name = DUP(header_name);
+
+               return header;
+
+}
+
+SWITCH_DECLARE(int) switch_event_add_array(switch_event_t *event, const char *var, const char *val)
+{
+       char *data;
+       char **array;
+       int idx;
+       int max = 0;
+       int len;
+       const char *p;
+       int i;
+
+       if (strlen(val) < 8) {
+               return -1;
+       }
+
+       p = val + 7;
+
+       max = 1;
+
+       while((p = strstr(p, "|:"))) {
+               max++;
+               p += 2;
+       }
+
+       if (!max) {
+               return -2;
+       }
+
+       data = strdup(val + 7);
+       
+       len = (sizeof(char *) * max) + 1;
+       array = malloc(len);
+       memset(array, 0, len);
+       
+       idx = switch_separate_string_string(data, "|:", array, max);
+       
+       for(i = 0; i < max; i++) {
+               switch_event_add_header_string(event, SWITCH_STACK_PUSH, var, array[i]);
+       }
+
+       free(array);
+       free(data);
+
+       return 0;
+}
+
 static switch_status_t switch_event_base_add_header(switch_event_t *event, switch_stack_t stack, const char *header_name, char *data)
 {
        switch_event_header_t *header = NULL;
@@ -848,19 +916,19 @@ static switch_status_t switch_event_base_add_header(switch_event_t *event, switc
                header_name = real_header_name;
        }
        
-       if (index_ptr || (stack & SWITCH_STACK_PUSH) || (stack & SWITCH_STACK_UNSHIFT) || switch_test_flag(event, EF_CONTAINS_ARRAYS)) {
+       if (index_ptr || (stack & SWITCH_STACK_PUSH) || (stack & SWITCH_STACK_UNSHIFT)) {
                
                if (!(header = switch_event_get_header_ptr(event, header_name)) && index_ptr) {
-                       header = ALLOC(sizeof(*header));
-                       switch_assert(header);
-                       memset(header, 0, sizeof(*header));
-                       header->name = DUP(header_name);
+
+                       header = new_header(header_name);
+
                        if (switch_test_flag(event, EF_UNIQ_HEADERS)) {
                                switch_event_del_header(event, header_name);
                        }
+
                        fly++;
                }
-
+               
                if ((header = switch_event_get_header_ptr(event, header_name))) {
                        
                        if (index_ptr) {
@@ -889,11 +957,6 @@ static switch_status_t switch_event_base_add_header(switch_event_t *event, switc
                                }
                                goto end;
                        } else {
-                       
-                               if (!(stack & SWITCH_STACK_PUSH) && !(stack & SWITCH_STACK_UNSHIFT) && header->idx) {
-                                       stack |= SWITCH_STACK_PUSH;
-                               }
-                               
                                if ((stack & SWITCH_STACK_PUSH) || (stack & SWITCH_STACK_UNSHIFT)) {
                                        exists++;
                                        stack &= ~(SWITCH_STACK_TOP | SWITCH_STACK_BOTTOM);
@@ -904,28 +967,20 @@ static switch_status_t switch_event_base_add_header(switch_event_t *event, switc
                }
        }
 
-       if (!header) {
-
-#ifdef SWITCH_EVENT_RECYCLE
-               void *pop;
-               if (switch_queue_trypop(EVENT_HEADER_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) {
-                       header = (switch_event_header_t *) pop;
-               } else {
-#endif
-                       header = ALLOC(sizeof(*header));
-                       switch_assert(header);
-#ifdef SWITCH_EVENT_RECYCLE
-               }
-#endif
-       
 
+       if (!header) {
                if (switch_test_flag(event, EF_UNIQ_HEADERS)) {
                        switch_event_del_header(event, header_name);
                }
 
-               memset(header, 0, sizeof(*header));
+               if (strstr(data, "ARRAY::")) {
+                       switch_event_add_array(event, header_name, data);
+                       FREE(data);
+                       goto end;
+               }
 
-               header->name = DUP(header_name);
+
+               header = new_header(header_name);
        }
        
        if ((stack & SWITCH_STACK_PUSH) || (stack & SWITCH_STACK_UNSHIFT)) {
@@ -934,8 +989,6 @@ static switch_status_t switch_event_base_add_header(switch_event_t *event, switc
                char *hv;
                int i = 0, j = 0;
 
-               switch_set_flag(event, EF_CONTAINS_ARRAYS);
-
                if (header->value && !header->idx) {
                        m = malloc(sizeof(char *));
                        switch_assert(m);
@@ -976,7 +1029,7 @@ static switch_status_t switch_event_base_add_header(switch_event_t *event, switc
 
                        switch_snprintf(header->value, len, "ARRAY::");
                        for(j = 0; j < header->idx; j++) {
-                               switch_snprintf(header->value + strlen(header->value), len - strlen(header->value), "%s%s", j == 0 ? "" : "::", header->array[j]);
+                               switch_snprintf(header->value + strlen(header->value), len - strlen(header->value), "%s%s", j == 0 ? "" : "|:", header->array[j]);
                        }
                }