Browse code

htable: iterator functions to set the value of current item

Daniel-Constantin Mierla authored on 11/10/2021 17:17:17
Showing 3 changed files
... ...
@@ -1878,6 +1878,106 @@ int ht_iterator_rm(str *iname)
1878 1878
 	return -2;
1879 1879
 }
1880 1880
 
1881
+int ht_iterator_sets(str *iname, str *sval)
1882
+{
1883
+	int k;
1884
+	ht_cell_t *itb;
1885
+	unsigned int hid;
1886
+	ht_cell_t *cell;
1887
+	int_str isvalue;
1888
+
1889
+	k = ht_iterator_find(iname);
1890
+	if(k==-1) {
1891
+		LM_ERR("iterator not found [%.*s]\n", iname->len, iname->s);
1892
+		return -1;
1893
+	}
1894
+	if(_ht_iterators[k].ht==NULL) {
1895
+		LM_ERR("iterator not initialized [%.*s]\n", iname->len, iname->s);
1896
+		return -1;
1897
+	}
1898
+	if(_ht_iterators[k].it==NULL) {
1899
+		LM_ERR("iterator not used [%.*s]\n", iname->len, iname->s);
1900
+		return -1;
1901
+	}
1902
+
1903
+	itb = _ht_iterators[k].it;
1904
+
1905
+	/* update value */
1906
+	if(itb->flags&AVP_VAL_STR) {
1907
+		if(itb->value.s.len >= sval->len) {
1908
+			/* copy */
1909
+			itb->value.s.len = sval->len;
1910
+			memcpy(itb->value.s.s, sval->s, sval->len);
1911
+			itb->value.s.s[itb->value.s.len] = '\0';
1912
+
1913
+			if(_ht_iterators[k].ht->updateexpire) {
1914
+				itb->expire = time(NULL) + _ht_iterators[k].ht->htexpire;
1915
+			}
1916
+			return 0;
1917
+		}
1918
+	}
1919
+	/* new */
1920
+	hid = ht_compute_hash(&itb->name);
1921
+
1922
+	isvalue.s = *sval;
1923
+
1924
+	cell = ht_cell_new(&itb->name, AVP_VAL_STR, &isvalue, hid);
1925
+	if(cell == NULL) {
1926
+		LM_ERR("cannot create new cell\n");
1927
+		return -1;
1928
+	}
1929
+	cell->next = itb->next;
1930
+	cell->prev = itb->prev;
1931
+	if(_ht_iterators[k].ht->updateexpire) {
1932
+		cell->expire = time(NULL) + _ht_iterators[k].ht->htexpire;
1933
+	} else {
1934
+		cell->expire = itb->expire;
1935
+	}
1936
+	if(itb->prev)
1937
+		itb->prev->next = cell;
1938
+	else
1939
+		_ht_iterators[k].ht->entries[_ht_iterators[k].slot].first = cell;
1940
+	if(itb->next)
1941
+		itb->next->prev = cell;
1942
+	ht_cell_free(itb);
1943
+	_ht_iterators[k].it = cell;
1944
+
1945
+	return 0;
1946
+}
1947
+
1948
+int ht_iterator_seti(str *iname, int ival)
1949
+{
1950
+	int k;
1951
+	ht_cell_t *itb;
1952
+
1953
+	k = ht_iterator_find(iname);
1954
+	if(k==-1) {
1955
+		LM_ERR("iterator not found [%.*s]\n", iname->len, iname->s);
1956
+		return -1;
1957
+	}
1958
+	if(_ht_iterators[k].ht==NULL) {
1959
+		LM_ERR("iterator not initialized [%.*s]\n", iname->len, iname->s);
1960
+		return -1;
1961
+	}
1962
+	if(_ht_iterators[k].it==NULL) {
1963
+		LM_ERR("iterator not used [%.*s]\n", iname->len, iname->s);
1964
+		return -1;
1965
+	}
1966
+
1967
+	itb = _ht_iterators[k].it;
1968
+
1969
+	/* update value */
1970
+	if(itb->flags&AVP_VAL_STR) {
1971
+		itb->flags &= ~AVP_VAL_STR;
1972
+	}
1973
+	itb->value.n = ival;
1974
+
1975
+	if(_ht_iterators[k].ht->updateexpire) {
1976
+		itb->expire = time(NULL) + _ht_iterators[k].ht->htexpire;
1977
+	}
1978
+	return 0;
1979
+}
1980
+
1881 1981
 ht_cell_t* ht_iterator_get_current(str *iname)
1882 1982
 {
1883 1983
 	int k;
... ...
@@ -130,6 +130,8 @@ int ht_iterator_start(str *iname, str *hname);
130 130
 int ht_iterator_next(str *iname);
131 131
 int ht_iterator_end(str *iname);
132 132
 int ht_iterator_rm(str *iname);
133
+int ht_iterator_sets(str *iname, str *sval);
134
+int ht_iterator_seti(str *iname, int ival);
133 135
 ht_cell_t* ht_iterator_get_current(str *iname);
134 136
 
135 137
 void ht_slot_lock(ht_t *ht, int idx);
... ...
@@ -81,6 +81,8 @@ static int w_ht_iterator_start(struct sip_msg* msg, char* iname, char* hname);
81 81
 static int w_ht_iterator_next(struct sip_msg* msg, char* iname, char* foo);
82 82
 static int w_ht_iterator_end(struct sip_msg* msg, char* iname, char* foo);
83 83
 static int w_ht_iterator_rm(struct sip_msg* msg, char* iname, char* foo);
84
+static int w_ht_iterator_sets(struct sip_msg* msg, char* iname, char* val);
85
+static int w_ht_iterator_seti(struct sip_msg* msg, char* iname, char* val);
84 86
 
85 87
 int ht_param(modparam_t type, void* val);
86 88
 
... ...
@@ -143,6 +145,11 @@ static cmd_export_t cmds[]={
143 145
 		ANY_ROUTE},
144 146
 	{"sht_iterator_rm",	(cmd_function)w_ht_iterator_rm,	1, fixup_spve_null, 0,
145 147
 		ANY_ROUTE},
148
+	{"sht_iterator_sets",	(cmd_function)w_ht_iterator_sets,	2, fixup_spve_spve,
149
+		fixup_free_spve_spve, ANY_ROUTE},
150
+	{"sht_iterator_seti",	(cmd_function)w_ht_iterator_seti,	2, fixup_spve_igp,
151
+		fixup_free_spve_igp, ANY_ROUTE},
152
+
146 153
 	{"bind_htable",     (cmd_function)bind_htable,     0, 0, 0,
147 154
 		ANY_ROUTE},
148 155
 	{0,0,0,0,0,0}
... ...
@@ -819,6 +826,70 @@ static int ki_ht_iterator_rm(sip_msg_t *msg, str *iname)
819 826
 	return (ret==0)?1:ret;
820 827
 }
821 828
 
829
+static int ki_ht_iterator_sets(sip_msg_t *msg, str *iname, str *sval)
830
+{
831
+	int ret;
832
+
833
+	if(iname==NULL || iname->s==NULL || iname->len<=0) {
834
+		LM_ERR("invalid parameters\n");
835
+		return -1;
836
+	}
837
+
838
+	ret = ht_iterator_sets(iname, sval);
839
+	return (ret==0)?1:ret;
840
+}
841
+
842
+static int w_ht_iterator_sets(struct sip_msg* msg, char* iname, char* val)
843
+{
844
+	str siname;
845
+	str sval;
846
+
847
+	if(fixup_get_svalue(msg, (gparam_t*)iname, &siname)<0)
848
+	{
849
+		LM_ERR("cannot get iterator name\n");
850
+		return -1;
851
+	}
852
+	if(fixup_get_svalue(msg, (gparam_t*)val, &sval)<0)
853
+	{
854
+		LM_ERR("cannot get value\n");
855
+		return -1;
856
+	}
857
+
858
+	return ki_ht_iterator_sets(msg, &siname, &sval);
859
+}
860
+
861
+static int ki_ht_iterator_seti(sip_msg_t *msg, str *iname, int ival)
862
+{
863
+	int ret;
864
+
865
+	if(iname==NULL || iname->s==NULL || iname->len<=0) {
866
+		LM_ERR("invalid parameters\n");
867
+		return -1;
868
+	}
869
+
870
+	ret = ht_iterator_seti(iname, ival);
871
+	return (ret==0)?1:ret;
872
+}
873
+
874
+static int w_ht_iterator_seti(struct sip_msg* msg, char* iname, char* val)
875
+{
876
+	str siname;
877
+	int ival;
878
+
879
+	if(fixup_get_svalue(msg, (gparam_t*)iname, &siname)<0 || siname.len<=0)
880
+	{
881
+		LM_ERR("cannot get iterator name\n");
882
+		return -1;
883
+	}
884
+	if(fixup_get_ivalue(msg, (gparam_t*)val, &ival)<0)
885
+	{
886
+		LM_ERR("cannot get value\n");
887
+		return -1;
888
+	}
889
+
890
+	return ki_ht_iterator_seti(msg, &siname, ival);
891
+}
892
+
822 893
 static int ki_ht_slot_xlock(sip_msg_t *msg, str *htname, str *skey, int lmode)
823 894
 {
824 895
 	ht_t *ht;
... ...
@@ -1907,6 +1978,16 @@ static sr_kemi_t sr_kemi_htable_exports[] = {
1907 1978
 		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1908 1979
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1909 1980
 	},
1981
+	{ str_init("htable"), str_init("sht_iterator_sets"),
1982
+		SR_KEMIP_INT, ki_ht_iterator_sets,
1983
+		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
1984
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1985
+	},
1986
+	{ str_init("htable"), str_init("sht_iterator_seti"),
1987
+		SR_KEMIP_INT, ki_ht_iterator_seti,
1988
+		{ SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
1989
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1990
+	},
1910 1991
 	{ str_init("htable"), str_init("sht_rm"),
1911 1992
 		SR_KEMIP_INT, ki_ht_rm,
1912 1993
 		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,