... | ... |
@@ -561,6 +561,36 @@ hf_iterator_end("i1"); |
561 | 561 |
} |
562 | 562 |
hf_iterator_end("i1"); |
563 | 563 |
... |
564 |
+</programlisting> |
|
565 |
+ </example> |
|
566 |
+ </section> |
|
567 |
+ <section id="textopsx.f.hf_iterator_prev"> |
|
568 |
+ <title> |
|
569 |
+ <function moreinfo="none">textopsx.f.hf_iterator_prev(iname)</function> |
|
570 |
+ </title> |
|
571 |
+ <para> |
|
572 |
+ Move the iterator to the previous header. It must |
|
573 |
+ be called also after sht_iterator_start() and sht_iterator_next(). |
|
574 |
+ </para> |
|
575 |
+ <para> |
|
576 |
+ The parameter can be dynamic string with variables. |
|
577 |
+ </para> |
|
578 |
+ <para> |
|
579 |
+ This function can be used from ANY_ROUTE. |
|
580 |
+ </para> |
|
581 |
+ <example> |
|
582 |
+ <title><function>hf_iterator_prev</function> usage</title> |
|
583 |
+ <programlisting format="linespecific"> |
|
584 |
+... |
|
585 |
+ hf_iterator_start("i1"); |
|
586 |
+ hf_iterator_next("i1"); |
|
587 |
+... |
|
588 |
+ hf_iterator_next("i1"); |
|
589 |
+... |
|
590 |
+ hf_iterator_prev("i1"); |
|
591 |
+... |
|
592 |
+ hf_iterator_end("i1"); |
|
593 |
+... |
|
564 | 594 |
</programlisting> |
565 | 595 |
</example> |
566 | 596 |
</section> |
... | ... |
@@ -75,6 +75,7 @@ static int assign_hf_value2_fixup(void **param, int param_no); |
75 | 75 |
|
76 | 76 |
static int w_hf_iterator_start(sip_msg_t *msg, char *piname, char *p2); |
77 | 77 |
static int w_hf_iterator_next(sip_msg_t *msg, char *piname, char *p2); |
78 |
+static int w_hf_iterator_prev(sip_msg_t *msg, char *piname, char *p2); |
|
78 | 79 |
static int w_hf_iterator_end(sip_msg_t *msg, char *piname, char *p2); |
79 | 80 |
static int w_hf_iterator_rm(sip_msg_t *msg, char *piname, char *p2); |
80 | 81 |
static int w_hf_iterator_append(sip_msg_t *msg, char *piname, char *phtext); |
... | ... |
@@ -137,6 +138,8 @@ static cmd_export_t cmds[] = { |
137 | 138 |
fixup_free_spve_null, ANY_ROUTE}, |
138 | 139 |
{"hf_iterator_next", w_hf_iterator_next, 1, fixup_spve_null, |
139 | 140 |
fixup_free_spve_null, ANY_ROUTE}, |
141 |
+ {"hf_iterator_prev", w_hf_iterator_prev, 1, fixup_spve_null, |
|
142 |
+ fixup_free_spve_null, ANY_ROUTE}, |
|
140 | 143 |
{"hf_iterator_end", w_hf_iterator_end, 1, fixup_spve_null, |
141 | 144 |
fixup_free_spve_null, ANY_ROUTE}, |
142 | 145 |
{"hf_iterator_rm", w_hf_iterator_rm, 1, fixup_spve_null, |
... | ... |
@@ -1836,6 +1839,7 @@ typedef struct hf_iterator { |
1836 | 1839 |
str name; |
1837 | 1840 |
char bname[HF_ITERATOR_NAME_SIZE]; |
1838 | 1841 |
hdr_field_t *it; |
1842 |
+ hdr_field_t *prev; |
|
1839 | 1843 |
int eoh; |
1840 | 1844 |
} hf_iterator_t; |
1841 | 1845 |
|
... | ... |
@@ -1886,6 +1890,7 @@ static int ki_hf_iterator_start(sip_msg_t *msg, str *iname) |
1886 | 1890 |
_hf_iterators[k].name.s = _hf_iterators[k].bname; |
1887 | 1891 |
} |
1888 | 1892 |
_hf_iterators[k].it = NULL; |
1893 |
+ _hf_iterators[k].prev = NULL; |
|
1889 | 1894 |
_hf_iterators[k].eoh = 0; |
1890 | 1895 |
if(parse_headers(msg, HDR_EOH_F, 0) == -1) { |
1891 | 1896 |
LM_ERR("failed parsing message\n"); |
... | ... |
@@ -1940,6 +1945,7 @@ static int ki_hf_iterator_next(sip_msg_t *msg, str *iname) |
1940 | 1945 |
if(_hf_iterators[k].it == NULL) { |
1941 | 1946 |
_hf_iterators[k].it = msg->headers; |
1942 | 1947 |
} else { |
1948 |
+ _hf_iterators[k].prev = _hf_iterators[k].it; |
|
1943 | 1949 |
_hf_iterators[k].it = _hf_iterators[k].it->next; |
1944 | 1950 |
} |
1945 | 1951 |
if(_hf_iterators[k].it == NULL) { |
... | ... |
@@ -1962,6 +1968,74 @@ static int w_hf_iterator_next(sip_msg_t *msg, char *piname, char *p2) |
1962 | 1968 |
return ki_hf_iterator_next(msg, &iname); |
1963 | 1969 |
} |
1964 | 1970 |
|
1971 |
+/** |
|
1972 |
+ * |
|
1973 |
+ */ |
|
1974 |
+static int ki_hf_iterator_prev(sip_msg_t *msg, str *iname) |
|
1975 |
+{ |
|
1976 |
+ hdr_field_t *hf; |
|
1977 |
+ int i; |
|
1978 |
+ int k; |
|
1979 |
+ |
|
1980 |
+ k = -1; |
|
1981 |
+ for(i=0; i<HF_ITERATOR_SIZE; i++) { |
|
1982 |
+ if(_hf_iterators[i].name.len>0) { |
|
1983 |
+ if(_hf_iterators[i].name.len==iname->len |
|
1984 |
+ && strncmp(_hf_iterators[i].name.s, iname->s, iname->len)==0) { |
|
1985 |
+ k = i; |
|
1986 |
+ break; |
|
1987 |
+ } |
|
1988 |
+ } |
|
1989 |
+ } |
|
1990 |
+ if(k==-1) { |
|
1991 |
+ LM_ERR("iterator not available [%.*s]\n", iname->len, iname->s); |
|
1992 |
+ return -1; |
|
1993 |
+ } |
|
1994 |
+ if(_hf_iterators[k].eoh == 1) { |
|
1995 |
+ return -1; |
|
1996 |
+ } |
|
1997 |
+ |
|
1998 |
+ if(_hf_iterators[k].prev==NULL) { |
|
1999 |
+ return ki_hf_iterator_start(msg, iname); |
|
2000 |
+ } |
|
2001 |
+ |
|
2002 |
+ if(_hf_iterators[k].prev!=_hf_iterators[k].it) { |
|
2003 |
+ _hf_iterators[k].it = _hf_iterators[k].prev; |
|
2004 |
+ return 1; |
|
2005 |
+ } |
|
2006 |
+ for(hf=msg->headers; hf; hf=hf->next) { |
|
2007 |
+ if(hf->next) { |
|
2008 |
+ if(hf->next->next) { |
|
2009 |
+ if(_hf_iterators[k].it==hf->next->next) { |
|
2010 |
+ _hf_iterators[k].it = hf->next; |
|
2011 |
+ _hf_iterators[k].prev = it; |
|
2012 |
+ return 1; |
|
2013 |
+ } |
|
2014 |
+ } else { |
|
2015 |
+ if(_hf_iterators[k].it==hf->next) { |
|
2016 |
+ _hf_iterators[k].it = hf; |
|
2017 |
+ _hf_iterators[k].prev = NULL; |
|
2018 |
+ return 1; |
|
2019 |
+ } |
|
2020 |
+ } |
|
2021 |
+ } |
|
2022 |
+ } |
|
2023 |
+ return ki_hf_iterator_start(msg, iname); |
|
2024 |
+} |
|
2025 |
+ |
|
2026 |
+/** |
|
2027 |
+ * |
|
2028 |
+ */ |
|
2029 |
+static int w_hf_iterator_prev(sip_msg_t *msg, char *piname, char *p2) |
|
2030 |
+{ |
|
2031 |
+ str iname = STR_NULL; |
|
2032 |
+ if(fixup_get_svalue(msg, (gparam_t*)piname, &iname)<0) { |
|
2033 |
+ LM_ERR("failed to get iterator name\n"); |
|
2034 |
+ return -1; |
|
2035 |
+ } |
|
2036 |
+ return ki_hf_iterator_prev(msg, &iname); |
|
2037 |
+} |
|
2038 |
+ |
|
1965 | 2039 |
/** |
1966 | 2040 |
* |
1967 | 2041 |
*/ |
... | ... |
@@ -2789,6 +2863,11 @@ static sr_kemi_t sr_kemi_textopsx_exports[] = { |
2789 | 2863 |
{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, |
2790 | 2864 |
SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } |
2791 | 2865 |
}, |
2866 |
+ { str_init("textopsx"), str_init("hf_iterator_prev"), |
|
2867 |
+ SR_KEMIP_INT, ki_hf_iterator_prev, |
|
2868 |
+ { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, |
|
2869 |
+ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } |
|
2870 |
+ }, |
|
2792 | 2871 |
{ str_init("textopsx"), str_init("hf_iterator_rm"), |
2793 | 2872 |
SR_KEMIP_INT, ki_hf_iterator_rm, |
2794 | 2873 |
{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, |