[sr-dev] git:master:5cdf195d: textops: added replace_str(match, repl, mode)

Daniel-Constantin Mierla miconda at gmail.com
Tue Jul 10 10:07:32 CEST 2018


Module: kamailio
Branch: master
Commit: 5cdf195d709dc0235170961af2003b70bcc2ecb6
URL: https://github.com/kamailio/kamailio/commit/5cdf195d709dc0235170961af2003b70bcc2ecb6

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date: 2018-07-10T09:56:02+02:00

textops: added replace_str(match, repl, mode)

- replace a string with another in the message buffer after the first
line. The parameter mode coltrols if first ("f") match or all ("a")
should be replaced
- alternative to replace() that avoids regexp overhead when bare string
can be matched

---

Modified: src/modules/textops/textops.c

---

Diff:  https://github.com/kamailio/kamailio/commit/5cdf195d709dc0235170961af2003b70bcc2ecb6.diff
Patch: https://github.com/kamailio/kamailio/commit/5cdf195d709dc0235170961af2003b70bcc2ecb6.patch

---

diff --git a/src/modules/textops/textops.c b/src/modules/textops/textops.c
index b4b3de4e11..c2c43ce284 100644
--- a/src/modules/textops/textops.c
+++ b/src/modules/textops/textops.c
@@ -88,6 +88,7 @@ MODULE_VERSION
 static int search_body_f(struct sip_msg*, char*, char*);
 static int search_hf_f(struct sip_msg*, char*, char*, char*);
 static int replace_f(struct sip_msg*, char*, char*);
+static int replace_str_f(struct sip_msg*, char*, char*, char*);
 static int replace_body_f(struct sip_msg*, char*, char*);
 static int replace_all_f(struct sip_msg*, char*, char*);
 static int replace_body_all_f(struct sip_msg*, char*, char*);
@@ -178,6 +179,9 @@ static cmd_export_t cmds[]={
 	{"replace",          (cmd_function)replace_f,         2,
 		fixup_regexp_none, fixup_free_regexp_none,
 		ANY_ROUTE},
+	{"replace_str",      (cmd_function)replace_str_f,     3,
+		fixup_spve_all, fixup_free_spve_all,
+		ANY_ROUTE},
 	{"replace_body",     (cmd_function)replace_body_f,    2,
 		fixup_regexp_none, fixup_free_regexp_none,
 		ANY_ROUTE},
@@ -779,6 +783,99 @@ static int ki_replace(sip_msg_t* msg, str* sre, str* sval)
 	return ret;
 }
 
+static char *textops_strfind(str *mbuf, str *mkey)
+{
+	char *sp;
+
+	// Sanity check
+	if(!(mbuf && mkey && mbuf->len >= mkey->len))
+		return NULL;
+
+	for(sp = mbuf->s; sp <= mbuf->s + mbuf->len - mkey->len; sp++) {
+		if(*sp == mkey->s[0] && strncmp(sp, mkey->s, mkey->len) == 0) {
+			return sp;
+		}
+	}
+
+	return NULL;
+}
+
+static int ki_replace_str(sip_msg_t* msg, str* mkey, str* rval, str *rmode)
+{
+	sr_lump_t* l;
+	char* s;
+	str mbuf;
+	char *mp;
+	char rpos;
+
+	if(mkey==NULL || rval==NULL) {
+		return -1;
+	}
+	if(mkey->s==NULL || mkey->len<=0) {
+		return 1;
+	}
+
+	if(rmode==NULL || rmode->s==NULL || rmode->s[0]=='f' || rmode->s[0]=='F') {
+		rpos = 'f';
+	} else {
+		rpos = 'a';
+	}
+
+	mbuf.s = get_header(msg);
+	mbuf.len = msg->len - (mbuf.s - msg->buf);
+
+	while((mp=textops_strfind(&mbuf, mkey))!=NULL) {
+
+		if ((l=del_lump(msg, mp - msg->buf, mkey->len, 0))==0) {
+			return -1;
+		}
+		s=pkg_malloc(rval->len+1);
+		if (s==0){
+			LM_ERR("memory allocation failure\n");
+			return -1;
+		}
+		memcpy(s, rval->s, rval->len);
+		if (insert_new_lump_after(l, s, rval->len, 0)==0){
+			LM_ERR("could not insert new lump\n");
+			pkg_free(s);
+			return -1;
+		}
+
+		if(rpos=='f') {
+			return 1;
+		}
+
+		mbuf.s = mp + mkey->len;
+		mbuf.len = msg->len - (mbuf.s - msg->buf);
+	}
+
+	return 1;
+}
+
+static int replace_str_f(sip_msg_t* msg, char* pmkey, char* prval, char* prmode)
+{
+	str mkey;
+	str rval;
+	str rmode;
+
+	if(fixup_get_svalue(msg, (gparam_t*)pmkey, &mkey)<0) {
+		LM_ERR("failed to get the matching string parameter\n");
+		return -1;
+	}
+
+	if(fixup_get_svalue(msg, (gparam_t*)prval, &rval)<0) {
+		LM_ERR("failed to get the replacement string parameter\n");
+		return -1;
+	}
+
+	if(fixup_get_svalue(msg, (gparam_t*)prmode, &rmode)<0) {
+		LM_ERR("failed to get the replacement mode parameter\n");
+		return -1;
+	}
+
+	return ki_replace_str(msg, &mkey, &rval, &rmode);
+}
+
 static int replace_body_helper(sip_msg_t* msg, regex_t *re, str *val)
 {
 	struct lump* l;
@@ -4243,6 +4340,11 @@ static sr_kemi_t sr_kemi_textops_exports[] = {
 		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
 	},
+	{ str_init("textops"), str_init("replace_str"),
+		SR_KEMIP_INT, ki_replace_str,
+		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
 	{ str_init("textops"), str_init("replace_all"),
 		SR_KEMIP_INT, ki_replace_all,
 		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,




More information about the sr-dev mailing list