Browse code

core expr: new internal operators

- added RVE_STRLEN_OP, RVE_STREMPTY_OP and RVE_DEFINED_OP

Andrei Pelinescu-Onciul authored on 24/04/2009 12:45:36
Showing 2 changed files
... ...
@@ -23,6 +23,7 @@
23 23
  * History:
24 24
  * --------
25 25
  *  2008-12-01  initial version (andrei)
26
+ *  2009-04-24  added support for defined, strempty, strlen (andrei)
26 27
  */
27 28
 
28 29
 #include "rvalue.h"
... ...
@@ -390,6 +391,9 @@ enum rval_type rve_guess_type( struct rval_expr* rve)
390 391
 		case RVE_EQ_OP:
391 392
 		case RVE_DIFF_OP:
392 393
 		case RVE_IPLUS_OP:
394
+		case RVE_STRLEN_OP:
395
+		case RVE_STREMPTY_OP:
396
+		case RVE_DEFINED_OP:
393 397
 			return RV_INT;
394 398
 		case RVE_PLUS_OP:
395 399
 			/* '+' evaluates to the type of the left operand */
... ...
@@ -429,6 +433,9 @@ int rve_is_constant(struct rval_expr* rve)
429 433
 		case RVE_UMINUS_OP:
430 434
 		case RVE_BOOL_OP:
431 435
 		case RVE_LNOT_OP:
436
+		case RVE_STRLEN_OP:
437
+		case RVE_STREMPTY_OP:
438
+		case RVE_DEFINED_OP:
432 439
 			return rve_is_constant(rve->left.rve);
433 440
 		case RVE_MINUS_OP:
434 441
 		case RVE_MUL_OP:
... ...
@@ -478,6 +485,9 @@ static int rve_op_unary(enum rval_expr_op op)
478 485
 		case RVE_UMINUS_OP:
479 486
 		case RVE_BOOL_OP:
480 487
 		case RVE_LNOT_OP:
488
+		case RVE_STRLEN_OP:
489
+		case RVE_STREMPTY_OP:
490
+		case RVE_DEFINED_OP:
481 491
 			return 1;
482 492
 		case RVE_MINUS_OP:
483 493
 		case RVE_MUL_OP:
... ...
@@ -610,6 +620,7 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
610 620
 					return 1;
611 621
 				}
612 622
 			}
623
+			break;
613 624
 		case RVE_CONCAT_OP:
614 625
 			*type=RV_STR;
615 626
 			if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
... ...
@@ -632,6 +643,21 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
632 643
 					return 1;
633 644
 				}
634 645
 			}
646
+			break;
647
+		case RVE_STRLEN_OP:
648
+		case RVE_STREMPTY_OP:
649
+		case RVE_DEFINED_OP:
650
+			*type=RV_INT;
651
+			if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
652
+				if (type1==RV_INT){
653
+					if (bad_rve) *bad_rve=rve->left.rve;
654
+					if (bad_t) *bad_t=type1;
655
+					if (exp_t) *exp_t=RV_STR;
656
+					return 0;
657
+				}
658
+				return 1;
659
+			}
660
+			break;
635 661
 		case RVE_NONE_OP:
636 662
 			break;
637 663
 	}
... ...
@@ -974,7 +1000,7 @@ inline static int int_intop1(int* res, enum rval_expr_op op, int v)
974 1000
 
975 1001
 
976 1002
 
977
-/** integer operation: *res= op v.
1003
+/** integer operation: *res= v1 op v2
978 1004
   * @return 0 on succes, \<0 on error
979 1005
   */
980 1006
 inline static int int_intop2(int* res, enum rval_expr_op op, int v1, int v2)
... ...
@@ -1054,6 +1080,27 @@ inline static int bool_strop2( enum rval_expr_op op, int* res,
1054 1080
 
1055 1081
 
1056 1082
 
1083
+/** integer returning operation on string: *res= op str (returns integer)
1084
+  * @return 0 on succes, \<0 on error
1085
+  */
1086
+inline static int int_strop1(int* res, enum rval_expr_op op, str* s1)
1087
+{
1088
+	switch(op){
1089
+		case RVE_STRLEN_OP:
1090
+			*res=s1->len;
1091
+			break;
1092
+		case RVE_STREMPTY_OP:
1093
+			*res=(s1->len==0);
1094
+			break;
1095
+		default:
1096
+			BUG("rv unsupported int_strop1 %d\n", op);
1097
+			return -1;
1098
+	}
1099
+	return 0;
1100
+}
1101
+
1102
+
1103
+
1057 1104
 /** integer operation: ret= op v (returns a rvalue).
1058 1105
  * @return rvalue on success, 0 on error
1059 1106
  */
... ...
@@ -1306,6 +1353,107 @@ error:
1306 1353
 
1307 1354
 
1308 1355
 
1356
+/** integer operation on rval evaluated as string.
1357
+ * Can use cached rvalues (c1 & c2).
1358
+ * @return 0 success, -1 on error
1359
+ */
1360
+inline static int rval_int_strop1(struct run_act_ctx* h,
1361
+						 struct sip_msg* msg,
1362
+						 int* res,
1363
+						 enum rval_expr_op op,
1364
+						 struct rvalue* l,
1365
+						 struct rval_cache* c1)
1366
+{
1367
+	struct rvalue* rv1;
1368
+	int ret;
1369
+	
1370
+	rv1=0;
1371
+	ret=0;
1372
+	if ((rv1=rval_convert(h, msg, RV_STR, l, c1))==0)
1373
+		goto error;
1374
+	ret=int_strop1(res, op, &rv1->v.s);
1375
+	rval_destroy(rv1); 
1376
+	return ret;
1377
+error:
1378
+	rval_destroy(rv1); 
1379
+	return 0;
1380
+}
1381
+
1382
+
1383
+
1384
+/** checks if rv is defined.
1385
+ * @return 1 defined, 0 not defined, -1 on error
1386
+ * Can use cached rvalues (c1).
1387
+ * Note: a rv can be undefined if it's an undefined avp or pvar or
1388
+ * if it's NONE
1389
+ */
1390
+inline static int rv_defined(struct run_act_ctx* h,
1391
+						 struct sip_msg* msg,
1392
+						 struct rvalue* rv, struct rval_cache* cache)
1393
+{
1394
+	avp_t* r_avp;
1395
+	int_str avp_val;
1396
+	pv_value_t pval;
1397
+	int ret;
1398
+	
1399
+	ret=1;
1400
+	switch(rv->type){
1401
+		case RV_AVP:
1402
+			if (unlikely(cache && cache->cache_type==RV_CACHE_AVP)){
1403
+				if (cache->val_type==RV_NONE)
1404
+					ret=0;
1405
+			}else{
1406
+				r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
1407
+											&avp_val, rv->v.avps.index);
1408
+				if (unlikely(r_avp==0)){
1409
+					ret=0;
1410
+				}
1411
+			}
1412
+			break;
1413
+		case RV_PVAR:
1414
+			/* PV_VAL_NULL or pv_get_spec_value error => undef */
1415
+			if (unlikely(cache && cache->cache_type==RV_CACHE_PVAR)){
1416
+				if (cache->val_type==RV_NONE)
1417
+					ret=0;
1418
+			}else{
1419
+				memset(&pval, 0, sizeof(pval));
1420
+				if (likely(pv_get_spec_value(msg, &rv->v.pvs, &pval)==0)){
1421
+					if ((pval.flags & PV_VAL_NULL) &&
1422
+							! (pval.flags & (PV_VAL_INT|PV_VAL_STR))){
1423
+						ret=0;
1424
+					}
1425
+					pv_value_destroy(&pval);
1426
+				}else{
1427
+					ret=0; /* in case of error, consider it undef */
1428
+				}
1429
+			}
1430
+			break;
1431
+		case RV_NONE:
1432
+			ret=0;
1433
+			break;
1434
+		default:
1435
+			break;
1436
+	}
1437
+	return 1; /* defined */
1438
+}
1439
+
1440
+
1441
+/** defined (integer) operation on rve.
1442
+ * @return 1 defined, 0 not defined, -1 on error
1443
+ */
1444
+inline static int int_rve_defined(struct run_act_ctx* h,
1445
+						 struct sip_msg* msg,
1446
+						 struct rval_expr* rve)
1447
+{
1448
+	/* only a rval can be undefined, any expression consisting on more
1449
+	   then one rval => defined */
1450
+	if (likely(rve->op==RVE_RVAL_OP))
1451
+		return rv_defined(h, msg, &rve->left.rval, 0);
1452
+	return 1;
1453
+}
1454
+
1455
+
1456
+
1309 1457
 /** evals an integer expr  to an int.
1310 1458
  * 
1311 1459
  *  *res=(int)eval(rve)
... ...
@@ -1431,6 +1579,18 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
1431 1579
 			*res=0;
1432 1580
 			ret=-1;
1433 1581
 			break;
1582
+		case RVE_DEFINED_OP:
1583
+			ret=int_rve_defined(h, msg, rve->left.rve);
1584
+			break;
1585
+		case RVE_STRLEN_OP:
1586
+		case RVE_STREMPTY_OP:
1587
+			if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
1588
+					ret=-1;
1589
+					break;
1590
+			}
1591
+			ret=rval_int_strop1(h, msg, res, rve->op, rv1, 0);
1592
+			rval_destroy(rv1);
1593
+			break;
1434 1594
 		case RVE_NONE_OP:
1435 1595
 		/*default:*/
1436 1596
 			BUG("invalid rval int expression operation %d\n", rve->op);
... ...
@@ -1503,6 +1663,9 @@ int rval_expr_eval_rvint(			   struct run_act_ctx* h,
1503 1663
 		case RVE_EQ_OP:
1504 1664
 		case RVE_DIFF_OP:
1505 1665
 		case RVE_IPLUS_OP:
1666
+		case RVE_STRLEN_OP:
1667
+		case RVE_STREMPTY_OP:
1668
+		case RVE_DEFINED_OP:
1506 1669
 			/* operator forces integer type */
1507 1670
 			ret=rval_expr_eval_int(h, msg, res_i, rve);
1508 1671
 			*res_rv=0;
... ...
@@ -1560,7 +1723,7 @@ error:
1560 1723
  * WARNING: result must be rval_destroy()'ed if non-null (it might be
1561 1724
  * a reference to another rval). The result can be modified only
1562 1725
  * if rv_chg_in_place() returns true.
1563
- * @result rvalue on success, 0 on error
1726
+ * @return rvalue on success, 0 on error
1564 1727
  */
1565 1728
 struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
1566 1729
 								struct rval_expr* rve)
... ...
@@ -1598,6 +1761,9 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
1598 1761
 		case RVE_EQ_OP:
1599 1762
 		case RVE_DIFF_OP:
1600 1763
 		case RVE_IPLUS_OP:
1764
+		case RVE_STRLEN_OP:
1765
+		case RVE_STREMPTY_OP:
1766
+		case RVE_DEFINED_OP:
1601 1767
 			/* operator forces integer type */
1602 1768
 			r=rval_expr_eval_int(h, msg, &i, rve);
1603 1769
 			if (likely(r==0)){
... ...
@@ -1800,6 +1966,9 @@ struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
1800 1966
 		case RVE_UMINUS_OP:
1801 1967
 		case RVE_BOOL_OP:
1802 1968
 		case RVE_LNOT_OP:
1969
+		case RVE_STRLEN_OP:
1970
+		case RVE_STREMPTY_OP:
1971
+		case RVE_DEFINED_OP:
1803 1972
 			break;
1804 1973
 		default:
1805 1974
 			BUG("unsupported unary operator %d\n", op);
... ...
@@ -1874,6 +2043,9 @@ static int rve_op_is_assoc(enum rval_expr_op op)
1874 2043
 		case RVE_UMINUS_OP:
1875 2044
 		case RVE_BOOL_OP:
1876 2045
 		case RVE_LNOT_OP:
2046
+		case RVE_STRLEN_OP:
2047
+		case RVE_STREMPTY_OP:
2048
+		case RVE_DEFINED_OP:
1877 2049
 			/* one operand expression => cannot be assoc. */
1878 2050
 			return 0;
1879 2051
 		case RVE_DIV_OP:
... ...
@@ -1911,6 +2083,9 @@ static int rve_op_is_commutative(enum rval_expr_op op, enum rval_type type)
1911 2083
 		case RVE_UMINUS_OP:
1912 2084
 		case RVE_BOOL_OP:
1913 2085
 		case RVE_LNOT_OP:
2086
+		case RVE_STRLEN_OP:
2087
+		case RVE_STREMPTY_OP:
2088
+		case RVE_DEFINED_OP:
1914 2089
 			/* one operand expression => cannot be commut. */
1915 2090
 			return 0;
1916 2091
 		case RVE_DIV_OP:
... ...
@@ -64,8 +64,12 @@ enum rval_expr_op{
64 64
 	RVE_PLUS_OP,  /* generic plus (int or str) returns left + right */
65 65
 	RVE_EQ_OP,    /*  2 members, returns left == right  (int)*/
66 66
 	RVE_DIFF_OP,  /*  2 members, returns left != right  (int)*/
67
-	RVE_CONCAT_OP,/* string concatenation, returns left . right */
68 67
 	/* str only */
68
+	RVE_CONCAT_OP,/* 2 members, string concat, returns left . right (str)*/
69
+	RVE_STRLEN_OP, /* one member, string length:, returns strlen(val) (int)*/
70
+	RVE_STREMPTY_OP, /* one member, returns val=="" (bool) */
71
+	/* avp, pvars a.s.o */
72
+	RVE_DEFINED_OP, /* one member, returns is_defined(val) (bool) */
69 73
 };
70 74
 
71 75