浏览代码

pv: new transformation {num.name}

- number related transformation
Daniel-Constantin Mierla 2 月之前
父节点
当前提交
80213de15b
共有 3 个文件被更改,包括 122 次插入3 次删除
  1. 1 0
      src/modules/pv/pv.c
  2. 112 0
      src/modules/pv/pv_trans.c
  3. 9 3
      src/modules/pv/pv_trans.h

+ 1 - 0
src/modules/pv/pv.c

@@ -61,6 +61,7 @@ static tr_export_t mod_trans[] = {
 	{{"line", sizeof("line") - 1}, tr_parse_line}, /* line class */
 	{{"urialias", sizeof("urialias") - 1}, tr_parse_urialias}, /* uri alias class */
 	{{"val", sizeof("val") - 1}, tr_parse_val}, /* val class */
+	{{"num", sizeof("num") - 1}, tr_parse_num}, /* num class */
 
 	{{0, 0}, 0}
 };

+ 112 - 0
src/modules/pv/pv_trans.c

@@ -2639,6 +2639,70 @@ int tr_eval_val(
 }
 
 
+/*!
+ * \brief Evaluate num transformations
+ * \param msg SIP message
+ * \param tp transformation
+ * \param subtype transformation type
+ * \param val pseudo-variable
+ * \return 0 on success, -1 on error
+ */
+int tr_eval_num(
+		struct sip_msg *msg, tr_param_t *tp, int subtype, pv_value_t *val)
+{
+	if(val == NULL)
+		return -1;
+
+	switch(subtype) {
+		case TR_NUM_FDIGIT:
+			tr_set_crt_buffer();
+			val->rs.s = _tr_buffer;
+			if(!(val->flags & PV_VAL_INT)) {
+				val->ri = 0;
+				val->rs.s[0] = '0';
+				val->rs.s[1] = '\0';
+				val->rs.len = 1;
+				val->flags = PV_TYPE_INT | PV_VAL_INT | PV_VAL_STR;
+				return 0;
+			}
+			if(val->ri < 0) {
+				val->ri = -val->ri;
+			}
+			while(val->ri >= 10) {
+				val->ri /= 10;
+			}
+			val->rs.s[0] = '0' + val->ri;
+			val->rs.s[1] = '\0';
+			val->rs.len = 1;
+			val->flags = PV_TYPE_INT | PV_VAL_INT | PV_VAL_STR;
+			break;
+		case TR_NUM_LDIGIT:
+			tr_set_crt_buffer();
+			val->rs.s = _tr_buffer;
+			if(!(val->flags & PV_VAL_INT)) {
+				val->ri = 0;
+				val->rs.s[0] = '0';
+				val->rs.s[1] = '\0';
+				val->rs.len = 1;
+				val->flags = PV_TYPE_INT | PV_VAL_INT | PV_VAL_STR;
+				return 0;
+			}
+			val->ri = val->ri % 10;
+			val->rs.s[0] = '0' + val->ri;
+			val->rs.s[1] = '\0';
+			val->rs.len = 1;
+			val->flags = PV_TYPE_INT | PV_VAL_INT | PV_VAL_STR;
+			break;
+
+		default:
+			LM_ERR("unknown subtype %d\n", subtype);
+			return -1;
+	}
+
+	return 0;
+}
+
+
 #define _tr_parse_nparam(_p, _p0, _tp, _spec, _n, _sign, _in, _s)              \
 	while(is_in_str(_p, _in) && (*_p == ' ' || *_p == '\t' || *_p == '\n'))    \
 		_p++;                                                                  \
@@ -3873,6 +3937,54 @@ char *tr_parse_val(str *in, trans_t *t)
 	}
 
 
+	LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s, name.len,
+			name.s, name.len);
+error:
+	return NULL;
+
+done:
+	t->name = name;
+	return p;
+}
+
+/*!
+ * \brief Helper function to parse num transformation
+ * \param in parsed string
+ * \param t transformation
+ * \return pointer to the end of the transformation in the string - '}', null on error
+ */
+char *tr_parse_num(str *in, trans_t *t)
+{
+	char *p;
+	str name;
+
+	if(in == NULL || t == NULL)
+		return NULL;
+
+	p = in->s;
+	name.s = in->s;
+	t->type = TR_NUM;
+	t->trf = tr_eval_num;
+
+	/* find next token */
+	while(is_in_str(p, in) && *p != TR_PARAM_MARKER && *p != TR_RBRACKET)
+		p++;
+	if(*p == '\0') {
+		LM_ERR("invalid transformation: %.*s\n", in->len, in->s);
+		goto error;
+	}
+	name.len = p - name.s;
+	trim(&name);
+
+	if(name.len == 6 && strncasecmp(name.s, "fdigit", 6) == 0) {
+		t->subtype = TR_NUM_FDIGIT;
+		goto done;
+	} else if(name.len == 6 && strncasecmp(name.s, "ldigit", 6) == 0) {
+		t->subtype = TR_NUM_LDIGIT;
+		goto done;
+	}
+
+
 	LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s, name.len,
 			name.s, name.len);
 error:

+ 9 - 3
src/modules/pv/pv_trans.h

@@ -41,7 +41,8 @@ enum _tr_type
 	TR_TOBODY,
 	TR_LINE,
 	TR_URIALIAS,
-	TR_VAL
+	TR_VAL,
+	TR_NUM
 };
 enum _tr_s_subtype
 {
@@ -170,7 +171,6 @@ enum _tr_urialias_subtype
 	TR_URIALIAS_ENCODE,
 	TR_URIALIAS_DECODE
 };
-
 enum _tr_val_subtype
 {
 	TR_VAL_NONE = 0,
@@ -179,7 +179,12 @@ enum _tr_val_subtype
 	TR_VAL_JSON,
 	TR_VAL_JSONQE
 };
-
+enum _tr_num_subtype
+{
+	TR_NUM_NONE = 0,
+	TR_NUM_FDIGIT,
+	TR_NUM_LDIGIT
+};
 
 char *tr_parse_string(str *in, trans_t *tr);
 char *tr_parse_uri(str *in, trans_t *tr);
@@ -189,6 +194,7 @@ char *tr_parse_tobody(str *in, trans_t *t);
 char *tr_parse_line(str *in, trans_t *t);
 char *tr_parse_urialias(str *in, trans_t *t);
 char *tr_parse_val(str *in, trans_t *t);
+char *tr_parse_num(str *in, trans_t *t);
 
 int tr_init_buffers(void);