Browse code

textopsx: added hf_iterator_prev() function

Daniel-Constantin Mierla authored on 30/07/2021 07:10:16
Showing 2 changed files
... ...
@@ -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,