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 390
 		case RVE_EQ_OP:
391 391
 		case RVE_DIFF_OP:
392 392
 		case RVE_IPLUS_OP:
393
+		case RVE_STRLEN_OP:
394
+		case RVE_STREMPTY_OP:
395
+		case RVE_DEFINED_OP:
393 396
 			return RV_INT;
394 397
 		case RVE_PLUS_OP:
395 398
 			/* '+' evaluates to the type of the left operand */
... ...
@@ -429,6 +433,9 @@ int rve_is_constant(struct rval_expr* rve)
429 429
 		case RVE_UMINUS_OP:
430 430
 		case RVE_BOOL_OP:
431 431
 		case RVE_LNOT_OP:
432
+		case RVE_STRLEN_OP:
433
+		case RVE_STREMPTY_OP:
434
+		case RVE_DEFINED_OP:
432 435
 			return rve_is_constant(rve->left.rve);
433 436
 		case RVE_MINUS_OP:
434 437
 		case RVE_MUL_OP:
... ...
@@ -478,6 +485,9 @@ static int rve_op_unary(enum rval_expr_op op)
478 478
 		case RVE_UMINUS_OP:
479 479
 		case RVE_BOOL_OP:
480 480
 		case RVE_LNOT_OP:
481
+		case RVE_STRLEN_OP:
482
+		case RVE_STREMPTY_OP:
483
+		case RVE_DEFINED_OP:
481 484
 			return 1;
482 485
 		case RVE_MINUS_OP:
483 486
 		case RVE_MUL_OP:
... ...
@@ -610,6 +620,7 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
610 610
 					return 1;
611 611
 				}
612 612
 			}
613
+			break;
613 614
 		case RVE_CONCAT_OP:
614 615
 			*type=RV_STR;
615 616
 			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 632
 					return 1;
633 633
 				}
634 634
 			}
635
+			break;
636
+		case RVE_STRLEN_OP:
637
+		case RVE_STREMPTY_OP:
638
+		case RVE_DEFINED_OP:
639
+			*type=RV_INT;
640
+			if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
641
+				if (type1==RV_INT){
642
+					if (bad_rve) *bad_rve=rve->left.rve;
643
+					if (bad_t) *bad_t=type1;
644
+					if (exp_t) *exp_t=RV_STR;
645
+					return 0;
646
+				}
647
+				return 1;
648
+			}
649
+			break;
635 650
 		case RVE_NONE_OP:
636 651
 			break;
637 652
 	}
... ...
@@ -974,7 +1000,7 @@ inline static int int_intop1(int* res, enum rval_expr_op op, int v)
974 974
 
975 975
 
976 976
 
977
-/** integer operation: *res= op v.
977
+/** integer operation: *res= v1 op v2
978 978
   * @return 0 on succes, \<0 on error
979 979
   */
980 980
 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 1054
 
1055 1055
 
1056 1056
 
1057
+/** integer returning operation on string: *res= op str (returns integer)
1058
+  * @return 0 on succes, \<0 on error
1059
+  */
1060
+inline static int int_strop1(int* res, enum rval_expr_op op, str* s1)
1061
+{
1062
+	switch(op){
1063
+		case RVE_STRLEN_OP:
1064
+			*res=s1->len;
1065
+			break;
1066
+		case RVE_STREMPTY_OP:
1067
+			*res=(s1->len==0);
1068
+			break;
1069
+		default:
1070
+			BUG("rv unsupported int_strop1 %d\n", op);
1071
+			return -1;
1072
+	}
1073
+	return 0;
1074
+}
1075
+
1076
+
1077
+
1057 1078
 /** integer operation: ret= op v (returns a rvalue).
1058 1079
  * @return rvalue on success, 0 on error
1059 1080
  */
... ...
@@ -1306,6 +1353,107 @@ error:
1306 1306
 
1307 1307
 
1308 1308
 
1309
+/** integer operation on rval evaluated as string.
1310
+ * Can use cached rvalues (c1 & c2).
1311
+ * @return 0 success, -1 on error
1312
+ */
1313
+inline static int rval_int_strop1(struct run_act_ctx* h,
1314
+						 struct sip_msg* msg,
1315
+						 int* res,
1316
+						 enum rval_expr_op op,
1317
+						 struct rvalue* l,
1318
+						 struct rval_cache* c1)
1319
+{
1320
+	struct rvalue* rv1;
1321
+	int ret;
1322
+	
1323
+	rv1=0;
1324
+	ret=0;
1325
+	if ((rv1=rval_convert(h, msg, RV_STR, l, c1))==0)
1326
+		goto error;
1327
+	ret=int_strop1(res, op, &rv1->v.s);
1328
+	rval_destroy(rv1); 
1329
+	return ret;
1330
+error:
1331
+	rval_destroy(rv1); 
1332
+	return 0;
1333
+}
1334
+
1335
+
1336
+
1337
+/** checks if rv is defined.
1338
+ * @return 1 defined, 0 not defined, -1 on error
1339
+ * Can use cached rvalues (c1).
1340
+ * Note: a rv can be undefined if it's an undefined avp or pvar or
1341
+ * if it's NONE
1342
+ */
1343
+inline static int rv_defined(struct run_act_ctx* h,
1344
+						 struct sip_msg* msg,
1345
+						 struct rvalue* rv, struct rval_cache* cache)
1346
+{
1347
+	avp_t* r_avp;
1348
+	int_str avp_val;
1349
+	pv_value_t pval;
1350
+	int ret;
1351
+	
1352
+	ret=1;
1353
+	switch(rv->type){
1354
+		case RV_AVP:
1355
+			if (unlikely(cache && cache->cache_type==RV_CACHE_AVP)){
1356
+				if (cache->val_type==RV_NONE)
1357
+					ret=0;
1358
+			}else{
1359
+				r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
1360
+											&avp_val, rv->v.avps.index);
1361
+				if (unlikely(r_avp==0)){
1362
+					ret=0;
1363
+				}
1364
+			}
1365
+			break;
1366
+		case RV_PVAR:
1367
+			/* PV_VAL_NULL or pv_get_spec_value error => undef */
1368
+			if (unlikely(cache && cache->cache_type==RV_CACHE_PVAR)){
1369
+				if (cache->val_type==RV_NONE)
1370
+					ret=0;
1371
+			}else{
1372
+				memset(&pval, 0, sizeof(pval));
1373
+				if (likely(pv_get_spec_value(msg, &rv->v.pvs, &pval)==0)){
1374
+					if ((pval.flags & PV_VAL_NULL) &&
1375
+							! (pval.flags & (PV_VAL_INT|PV_VAL_STR))){
1376
+						ret=0;
1377
+					}
1378
+					pv_value_destroy(&pval);
1379
+				}else{
1380
+					ret=0; /* in case of error, consider it undef */
1381
+				}
1382
+			}
1383
+			break;
1384
+		case RV_NONE:
1385
+			ret=0;
1386
+			break;
1387
+		default:
1388
+			break;
1389
+	}
1390
+	return 1; /* defined */
1391
+}
1392
+
1393
+
1394
+/** defined (integer) operation on rve.
1395
+ * @return 1 defined, 0 not defined, -1 on error
1396
+ */
1397
+inline static int int_rve_defined(struct run_act_ctx* h,
1398
+						 struct sip_msg* msg,
1399
+						 struct rval_expr* rve)
1400
+{
1401
+	/* only a rval can be undefined, any expression consisting on more
1402
+	   then one rval => defined */
1403
+	if (likely(rve->op==RVE_RVAL_OP))
1404
+		return rv_defined(h, msg, &rve->left.rval, 0);
1405
+	return 1;
1406
+}
1407
+
1408
+
1409
+
1309 1410
 /** evals an integer expr  to an int.
1310 1411
  * 
1311 1412
  *  *res=(int)eval(rve)
... ...
@@ -1431,6 +1579,18 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
1431 1431
 			*res=0;
1432 1432
 			ret=-1;
1433 1433
 			break;
1434
+		case RVE_DEFINED_OP:
1435
+			ret=int_rve_defined(h, msg, rve->left.rve);
1436
+			break;
1437
+		case RVE_STRLEN_OP:
1438
+		case RVE_STREMPTY_OP:
1439
+			if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
1440
+					ret=-1;
1441
+					break;
1442
+			}
1443
+			ret=rval_int_strop1(h, msg, res, rve->op, rv1, 0);
1444
+			rval_destroy(rv1);
1445
+			break;
1434 1446
 		case RVE_NONE_OP:
1435 1447
 		/*default:*/
1436 1448
 			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 1503
 		case RVE_EQ_OP:
1504 1504
 		case RVE_DIFF_OP:
1505 1505
 		case RVE_IPLUS_OP:
1506
+		case RVE_STRLEN_OP:
1507
+		case RVE_STREMPTY_OP:
1508
+		case RVE_DEFINED_OP:
1506 1509
 			/* operator forces integer type */
1507 1510
 			ret=rval_expr_eval_int(h, msg, res_i, rve);
1508 1511
 			*res_rv=0;
... ...
@@ -1560,7 +1723,7 @@ error:
1560 1560
  * WARNING: result must be rval_destroy()'ed if non-null (it might be
1561 1561
  * a reference to another rval). The result can be modified only
1562 1562
  * if rv_chg_in_place() returns true.
1563
- * @result rvalue on success, 0 on error
1563
+ * @return rvalue on success, 0 on error
1564 1564
  */
1565 1565
 struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
1566 1566
 								struct rval_expr* rve)
... ...
@@ -1598,6 +1761,9 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
1598 1598
 		case RVE_EQ_OP:
1599 1599
 		case RVE_DIFF_OP:
1600 1600
 		case RVE_IPLUS_OP:
1601
+		case RVE_STRLEN_OP:
1602
+		case RVE_STREMPTY_OP:
1603
+		case RVE_DEFINED_OP:
1601 1604
 			/* operator forces integer type */
1602 1605
 			r=rval_expr_eval_int(h, msg, &i, rve);
1603 1606
 			if (likely(r==0)){
... ...
@@ -1800,6 +1966,9 @@ struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
1800 1800
 		case RVE_UMINUS_OP:
1801 1801
 		case RVE_BOOL_OP:
1802 1802
 		case RVE_LNOT_OP:
1803
+		case RVE_STRLEN_OP:
1804
+		case RVE_STREMPTY_OP:
1805
+		case RVE_DEFINED_OP:
1803 1806
 			break;
1804 1807
 		default:
1805 1808
 			BUG("unsupported unary operator %d\n", op);
... ...
@@ -1874,6 +2043,9 @@ static int rve_op_is_assoc(enum rval_expr_op op)
1874 1874
 		case RVE_UMINUS_OP:
1875 1875
 		case RVE_BOOL_OP:
1876 1876
 		case RVE_LNOT_OP:
1877
+		case RVE_STRLEN_OP:
1878
+		case RVE_STREMPTY_OP:
1879
+		case RVE_DEFINED_OP:
1877 1880
 			/* one operand expression => cannot be assoc. */
1878 1881
 			return 0;
1879 1882
 		case RVE_DIV_OP:
... ...
@@ -1911,6 +2083,9 @@ static int rve_op_is_commutative(enum rval_expr_op op, enum rval_type type)
1911 1911
 		case RVE_UMINUS_OP:
1912 1912
 		case RVE_BOOL_OP:
1913 1913
 		case RVE_LNOT_OP:
1914
+		case RVE_STRLEN_OP:
1915
+		case RVE_STREMPTY_OP:
1916
+		case RVE_DEFINED_OP:
1914 1917
 			/* one operand expression => cannot be commut. */
1915 1918
 			return 0;
1916 1919
 		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