Browse code

posops: functions for getting the position by reverse search

Daniel-Constantin Mierla authored on 23/09/2021 07:25:43
Showing 2 changed files
... ...
@@ -264,7 +264,7 @@ $var(idx) = pos_find_str("100", "kamailio");
264 264
 				</programlisting>
265 265
 			</example>
266 266
 		</section>
267
-		<section id="posops.f.pos_find_str">
267
+		<section id="posops.f.pos_findi_str">
268 268
 			<title>
269 269
 				<function moreinfo="none">pos_findi_str(idx, val)</function>
270 270
 			</title>
... ...
@@ -289,6 +289,64 @@ $var(idx) = pos_find_str("100", "kamailio");
289 289
 				<programlisting format="linespecific">
290 290
 ...
291 291
 $var(idx) = pos_findi_str("100", "kamailio");
292
+...
293
+				</programlisting>
294
+			</example>
295
+		</section>
296
+		<section id="posops.f.pos_rfind_str">
297
+			<title>
298
+				<function moreinfo="none">pos_rfind_str(idx, val)</function>
299
+			</title>
300
+			<para>
301
+			Return the last position of the val in message buffer starting at idx
302
+			(reverse search). In case of not finding it or error, the return code
303
+			is negative. If val is at index 0, it returns the value specified
304
+			by modparam idx0.
305
+			</para>
306
+			<para>
307
+			The idx can be an integer value or a variable holding an integer. If
308
+			the value is negative, the position is counted from the end of the buffer.
309
+			</para>
310
+			<para>
311
+			The val can be a static string or variables.
312
+			</para>
313
+			<para>
314
+			This function can be used from ANY_ROUTE.
315
+			</para>
316
+			<example>
317
+				<title><function>pos_find_str()</function> usage</title>
318
+				<programlisting format="linespecific">
319
+...
320
+$var(idx) = pos_rfind_str("100", "kamailio");
321
+...
322
+				</programlisting>
323
+			</example>
324
+		</section>
325
+		<section id="posops.f.pos_rfindi_str">
326
+			<title>
327
+				<function moreinfo="none">pos_rfindi_str(idx, val)</function>
328
+			</title>
329
+			<para>
330
+			Return the last position of the val (matching case insensitive) in message
331
+			buffer starting at idx (reverse search). In case of not finding it
332
+			or error, the return code is negative. If val is at index 0, it
333
+			returns the value specified by modparam idx0.
334
+			</para>
335
+			<para>
336
+			The idx can be an integer value or a variable holding an integer. If
337
+			the value is negative, the position is counted from the end of the buffer.
338
+			</para>
339
+			<para>
340
+			The val can be a static string or variables.
341
+			</para>
342
+			<para>
343
+			This function can be used from ANY_ROUTE.
344
+			</para>
345
+			<example>
346
+				<title><function>pos_rfindi_str()</function> usage</title>
347
+				<programlisting format="linespecific">
348
+...
349
+$var(idx) = pos_rfindi_str("100", "kamailio");
292 350
 ...
293 351
 				</programlisting>
294 352
 			</example>
... ...
@@ -47,6 +47,8 @@ static int w_posops_pos_body_start(sip_msg_t* msg, char* p1, char* p2);
47 47
 static int w_posops_pos_body_end(sip_msg_t* msg, char* p1, char* p2);
48 48
 static int w_posops_pos_find_str(sip_msg_t* msg, char* p1idx, char* p2val);
49 49
 static int w_posops_pos_findi_str(sip_msg_t* msg, char* p1idx, char* p2val);
50
+static int w_posops_pos_rfind_str(sip_msg_t* msg, char* p1idx, char* p2val);
51
+static int w_posops_pos_rfindi_str(sip_msg_t* msg, char* p1idx, char* p2val);
50 52
 
51 53
 typedef struct posops_data {
52 54
 	int ret;
... ...
@@ -90,6 +92,10 @@ static cmd_export_t cmds[]={
90 92
 		fixup_free_igp_spve, ANY_ROUTE},
91 93
 	{"pos_findi_str", (cmd_function)w_posops_pos_findi_str, 2, fixup_igp_spve,
92 94
 		fixup_free_igp_spve, ANY_ROUTE},
95
+	{"pos_rfind_str", (cmd_function)w_posops_pos_rfind_str, 2, fixup_igp_spve,
96
+		fixup_free_igp_spve, ANY_ROUTE},
97
+	{"pos_rfindi_str", (cmd_function)w_posops_pos_rfindi_str, 2, fixup_igp_spve,
98
+		fixup_free_igp_spve, ANY_ROUTE},
93 99
 
94 100
 	{0, 0, 0, 0, 0, 0}
95 101
 };
... ...
@@ -522,6 +528,111 @@ static int w_posops_pos_findi_str(sip_msg_t* msg, char* p1idx, char* p2val)
522 528
 	return ki_posops_pos_findi_str(msg, idx, &val);
523 529
 }
524 530
 
531
+
532
+
533
+/**
534
+ *
535
+ */
536
+static int ki_posops_pos_rfind_str(sip_msg_t *msg, int idx, str *val)
537
+{
538
+	char *p;
539
+	str text;
540
+
541
+	if(val==NULL || val->s==NULL || val->len<=0) {
542
+		return -1;
543
+	}
544
+	if(idx<0) {
545
+		idx += msg->len;
546
+	}
547
+	if(idx<0 || idx > msg->len - val->len) {
548
+		return -1;
549
+	}
550
+	text.s = msg->buf + idx;
551
+	text.len = msg->len - idx;
552
+	p = str_rsearch(&text, val);
553
+	if(p==NULL) {
554
+		return -1;
555
+	}
556
+
557
+	_posops_data.idx = (int)(p - msg->buf);
558
+	_posops_data.ret = (_posops_data.idx==0)?posops_idx0:_posops_data.idx;
559
+
560
+	return _posops_data.ret;
561
+}
562
+
563
+/**
564
+ *
565
+ */
566
+static int w_posops_pos_rfind_str(sip_msg_t* msg, char* p1idx, char* p2val)
567
+{
568
+	int idx = 0;
569
+	str val = STR_NULL;
570
+
571
+	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
572
+		LM_ERR("unable to get idx parameter\n");
573
+		return -1;
574
+	}
575
+
576
+	if(fixup_get_svalue(msg, (gparam_t*)p2val, &val)!=0) {
577
+		LM_ERR("unable to get val parameter\n");
578
+		return -1;
579
+	}
580
+
581
+	return ki_posops_pos_rfind_str(msg, idx, &val);
582
+}
583
+
584
+/**
585
+ *
586
+ */
587
+static int ki_posops_pos_rfindi_str(sip_msg_t *msg, int idx, str *val)
588
+{
589
+	char *p;
590
+	str text;
591
+
592
+	if(val==NULL || val->s==NULL || val->len<=0) {
593
+		return -1;
594
+	}
595
+	if(idx<0) {
596
+		idx += msg->len;
597
+	}
598
+	if(idx<0 || idx > msg->len - val->len) {
599
+		return -1;
600
+	}
601
+
602
+	text.s = msg->buf + idx;
603
+	text.len = msg->len - idx;
604
+	p = str_rcasesearch(&text, val);
605
+	if(p==NULL) {
606
+		return -1;
607
+	}
608
+
609
+	_posops_data.idx = (int)(p - msg->buf);
610
+	_posops_data.ret = (_posops_data.idx==0)?posops_idx0:_posops_data.idx;
611
+
612
+	return _posops_data.ret;
613
+}
614
+
615
+/**
616
+ *
617
+ */
618
+static int w_posops_pos_rfindi_str(sip_msg_t* msg, char* p1idx, char* p2val)
619
+{
620
+	int idx = 0;
621
+	str val = STR_NULL;
622
+
623
+	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
624
+		LM_ERR("unable to get idx parameter\n");
625
+		return -1;
626
+	}
627
+
628
+	if(fixup_get_svalue(msg, (gparam_t*)p2val, &val)!=0) {
629
+		LM_ERR("unable to get val parameter\n");
630
+		return -1;
631
+	}
632
+
633
+	return ki_posops_pos_rfindi_str(msg, idx, &val);
634
+}
635
+
525 636
 /**
526 637
  *
527 638
  */
... ...
@@ -614,6 +725,16 @@ static sr_kemi_t sr_kemi_posops_exports[] = {
614 725
 		{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
615 726
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
616 727
 	},
728
+	{ str_init("posops"), str_init("pos_rfind_str"),
729
+		SR_KEMIP_INT, ki_posops_pos_rfind_str,
730
+		{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
731
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
732
+	},
733
+	{ str_init("posops"), str_init("pos_rfindi_str"),
734
+		SR_KEMIP_INT, ki_posops_pos_rfindi_str,
735
+		{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
736
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
737
+	},
617 738
 
618 739
 	{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
619 740
 };