Browse code

pv: added {s.fmtlines,n,m} and {s.fmtlinet,n,m}

- format the value in lines of n characters, adding m spaces or tabs to
the start of each new line (not to first line)

Daniel-Constantin Mierla authored on 25/06/2021 08:58:23
Showing 2 changed files
... ...
@@ -189,7 +189,7 @@ static int getNumericValue(str sin) {
189 189
 int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype,
190 190
 		pv_value_t *val)
191 191
 {
192
-	int i, j, max;
192
+	int i, j, n, m, max;
193 193
 	char *p, *s;
194 194
 	char c;
195 195
 	str st, st2;
... ...
@@ -1446,6 +1446,88 @@ int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype,
1446 1446
 			val->rs.s[val->rs.len] = '\0';
1447 1447
 			break;
1448 1448
 
1449
+		case TR_S_FMTLINES:
1450
+		case TR_S_FMTLINET:
1451
+			if(tp==NULL || tp->next==NULL)
1452
+			{
1453
+				LM_ERR("substr invalid parameters (cfg line: %d)\n",
1454
+						get_cfg_crt_line());
1455
+				return -1;
1456
+			}
1457
+			if(!(val->flags&PV_VAL_STR))
1458
+				val->rs.s = int2str(val->ri, &val->rs.len);
1459
+			if(tp->type==TR_PARAM_NUMBER)
1460
+			{
1461
+				n = tp->v.n;
1462
+			} else {
1463
+				if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
1464
+						|| (!(v.flags&PV_VAL_INT)))
1465
+				{
1466
+					LM_ERR("fmtline cannot get p1 (cfg line: %d)\n",
1467
+							get_cfg_crt_line());
1468
+					return -1;
1469
+				}
1470
+				n = v.ri;
1471
+			}
1472
+			if(tp->next->type==TR_PARAM_NUMBER)
1473
+			{
1474
+				m = tp->next->v.n;
1475
+			} else {
1476
+				if(pv_get_spec_value(msg, (pv_spec_p)tp->next->v.data, &v)!=0
1477
+						|| (!(v.flags&PV_VAL_INT)))
1478
+				{
1479
+					LM_ERR("fmt cannot get p2 (cfg line: %d)\n",
1480
+							get_cfg_crt_line());
1481
+					return -1;
1482
+				}
1483
+				m = v.ri;
1484
+			}
1485
+			if(n<0 || m<0) {
1486
+				LM_ERR("substr negative offset (cfg line: %d)\n",
1487
+						get_cfg_crt_line());
1488
+				return -1;
1489
+			}
1490
+			if(n==0 || m>=val->rs.len) {
1491
+				if(val->rs.len>TR_BUFFER_SIZE-2) {
1492
+					LM_ERR("value too large: %d\n", val->rs.len);
1493
+					return -1;
1494
+				}
1495
+
1496
+				memcpy(_tr_buffer, val->rs.s, val->rs.len);
1497
+				val->flags = PV_VAL_STR;
1498
+				val->rs.s = _tr_buffer;
1499
+				val->rs.s[val->rs.len] = '\0';
1500
+			}
1501
+			if(val->rs.len + (((val->rs.len)/n)*(2+m)) > TR_BUFFER_SIZE-2) {
1502
+				LM_ERR("value too large: %d\n", val->rs.len);
1503
+				return -1;
1504
+			}
1505
+
1506
+			p = _tr_buffer;
1507
+			for(i=0; i<val->rs.len; i++) {
1508
+				if(i!=0 && (i/n)==0) {
1509
+					*p = '\r';
1510
+					p++;
1511
+					*p = '\n';
1512
+					p++;
1513
+					for(j=0; j<m; j++) {
1514
+						if(subtype==TR_S_FMTLINES) {
1515
+							*p = ' ';
1516
+						} else {
1517
+							*p = '\t';
1518
+						}
1519
+						p++;
1520
+					}
1521
+				}
1522
+				*p = val->rs.s[i];
1523
+				p++;
1524
+			}
1525
+			val->flags = PV_VAL_STR;
1526
+			val->rs.s = _tr_buffer;
1527
+			val->rs.len = p - _tr_buffer;
1528
+			val->rs.s[val->rs.len] = '\0';
1529
+			break;
1530
+
1449 1531
 		default:
1450 1532
 			LM_ERR("unknown subtype %d (cfg line: %d)\n",
1451 1533
 					subtype, get_cfg_crt_line());
... ...
@@ -3071,6 +3153,53 @@ char* tr_parse_string(str* in, trans_t *t)
3071 3153
 			goto error;
3072 3154
 		}
3073 3155
 		goto done;
3156
+	} else if(name.len==8 && (strncasecmp(name.s, "fmtlines", 8)==0
3157
+				|| strncasecmp(name.s, "fmtlinet", 8)==0)) {
3158
+		if(name.s[7]=='s' || name.s[7]=='S') {
3159
+			t->subtype = TR_S_FMTLINES;
3160
+		} else {
3161
+			t->subtype = TR_S_FMTLINET;
3162
+		}
3163
+		if(*p!=TR_PARAM_MARKER)
3164
+		{
3165
+			LM_ERR("invalid fmtline%c transformation: %.*s!\n", name.s[7],
3166
+					in->len, in->s);
3167
+			goto error;
3168
+		}
3169
+		p++;
3170
+		_tr_parse_nparam(p, p0, tp, spec, n, sign, in, s);
3171
+		if(tp->type==TR_PARAM_NUMBER && tp->v.n<0)
3172
+		{
3173
+			LM_ERR("fmtline%c negative line length value\n", name.s[7]);
3174
+			goto error;
3175
+		}
3176
+
3177
+		t->params = tp;
3178
+		tp = 0;
3179
+		while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
3180
+		if(*p!=TR_PARAM_MARKER)
3181
+		{
3182
+			LM_ERR("invalid fmtline%c transformation: %.*s!\n",
3183
+					 name.s[7], in->len, in->s);
3184
+			goto error;
3185
+		}
3186
+		p++;
3187
+		_tr_parse_nparam(p, p0, tp, spec, n, sign, in, s);
3188
+		if(tp->type==TR_PARAM_NUMBER && tp->v.n<0)
3189
+		{
3190
+			LM_ERR("fmtline%c negative padding lenght value\n", name.s[7]);
3191
+			goto error;
3192
+		}
3193
+		t->params->next = tp;
3194
+		tp = 0;
3195
+		while(is_in_str(p, in) && (*p==' ' || *p=='\t' || *p=='\n')) p++;
3196
+		if(*p!=TR_RBRACKET)
3197
+		{
3198
+			LM_ERR("invalid fmtline%c transformation: %.*s!!\n",
3199
+					name.s[7], in->len, in->s);
3200
+			goto error;
3201
+		}
3202
+		goto done;
3074 3203
 	}
3075 3204
 
3076 3205
 	LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
... ...
@@ -45,7 +45,7 @@ enum _tr_s_subtype {
45 45
 	TR_S_UNBRACKET, TR_S_COUNT, TR_S_ENCODEBASE64T, TR_S_DECODEBASE64T,
46 46
 	TR_S_ENCODEBASE64URL, TR_S_DECODEBASE64URL,
47 47
 	TR_S_ENCODEBASE64URLT, TR_S_DECODEBASE64URLT, TR_S_RMWS, TR_S_BEFORE,
48
-	TR_S_AFTER, TR_S_RBEFORE, TR_S_RAFTER
48
+	TR_S_AFTER, TR_S_RBEFORE, TR_S_RAFTER, TR_S_FMTLINES, TR_S_FMTLINET
49 49
 };
50 50
 enum _tr_uri_subtype {
51 51
 	TR_URI_NONE=0, TR_URI_USER, TR_URI_HOST, TR_URI_PASSWD, TR_URI_PORT,