Module: sip-router
Branch: andrei/rve_f_params
Commit: e5fa2eb3563d532ff88b8c42aa2baa307804b4ee
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=e5fa2eb…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Wed Mar 17 20:09:29 2010 +0100
core: rval - don't use static buffer for int conversions
- don't use static buffers for string conversions
(rval_get_tmp_str())
- extended rval_cache with enough space to store an int converted
to string
- switched to signed ints (until now all ints where treated as
unsigned)
---
rvalue.c | 46 ++++++++++++++++++++++++++++++++--------------
rvalue.h | 6 +++++-
2 files changed, 37 insertions(+), 15 deletions(-)
diff --git a/rvalue.c b/rvalue.c
index d02b194..921edb4 100644
--- a/rvalue.c
+++ b/rvalue.c
@@ -1062,12 +1062,14 @@ error:
* if rv == undefined select, avp or pvar, return "".
* if an error occurs while evaluating a select, avp or pvar, behave as
* for the undefined case (and return success).
- * The result points either to a temporary string or inside
- * new_cache. new_cache must be non zero, initialized previously,
- * and it _must_ be rval_cache_clean(...)'ed when done.
- * WARNING: it's not intended for general use, it might return a pointer
- * to a static buffer (int2str) so use the result a.s.a.p, make a copy.
- * or use rval_get_str() instead.
+ * The result points either inside the passed rv, inside
+ * new_cache or inside an avp. new_cache must be non zero,
+ * initialized previously and it _must_ be rval_cache_clean(...)'ed when
+ * done.
+ * WARNING: it's not intended for general use. It might return a pointer
+ * inside rv so the result _must_ be treated as read-only. rv and new_cache
+ * must not be released/freed until the result is no longer needed.
+ * For general use see rval_get_str().
* @param h - script context handle
* @param msg - sip msg
* @param tmpv - str return value (pointer to a str struct that will be
@@ -1089,7 +1091,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
switch(rv->type){
case RV_INT:
- tmpv->s=int2str(rv->v.l, &tmpv->len);
+ tmpv->s=sint2strbuf(rv->v.l, tmp_cache->i2s,
+ sizeof(tmp_cache->i2s), &tmpv->len);
+ tmp_cache->cache_type = RV_CACHE_INT2STR;
break;
case RV_STR:
*tmpv=rv->v.s;
@@ -1099,16 +1103,22 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
i=(run_actions(h, rv->v.action, msg)>0);
else
i=0;
- tmpv->s=int2str(i, &tmpv->len);
+ tmpv->s=sint2strbuf(i, tmp_cache->i2s,
+ sizeof(tmp_cache->i2s), &tmpv->len);
+ tmp_cache->cache_type = RV_CACHE_INT2STR;
break;
case RV_BEXPR:
i=eval_expr(h, rv->v.bexpr, msg);
if (i==EXPR_DROP){
i=0; /* false */
- tmpv->s=int2str(i, &tmpv->len);
+ tmpv->s=sint2strbuf(i, tmp_cache->i2s,
+ sizeof(tmp_cache->i2s), &tmpv->len);
+ tmp_cache->cache_type = RV_CACHE_INT2STR;
return EXPR_DROP;
}
- tmpv->s=int2str(i, &tmpv->len);
+ tmpv->s=sint2strbuf(i, tmp_cache->i2s, sizeof(tmp_cache->i2s),
+ &tmpv->len);
+ tmp_cache->cache_type = RV_CACHE_INT2STR;
break;
case RV_SEL:
i=run_select(tmpv, &rv->v.sel, msg);
@@ -1126,7 +1136,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
*tmpv=cache->c.avp_val.s;
}else if (cache->val_type==RV_INT){
i=cache->c.avp_val.n;
- tmpv->s=int2str(i, &tmpv->len);
+ tmpv->s=sint2strbuf(i, tmp_cache->i2s,
+ sizeof(tmp_cache->i2s), &tmpv->len);
+ tmp_cache->cache_type = RV_CACHE_INT2STR;
}else if (cache->val_type==RV_NONE){
goto undef;
}else goto error_cache;
@@ -1141,7 +1153,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
*tmpv=tmp_cache->c.avp_val.s;
}else{
i=tmp_cache->c.avp_val.n;
- tmpv->s=int2str(i, &tmpv->len);
+ tmpv->s=sint2strbuf(i, tmp_cache->i2s,
+ sizeof(tmp_cache->i2s), &tmpv->len);
+ tmp_cache->cache_type = RV_CACHE_INT2STR;
}
}else goto undef;
}
@@ -1152,7 +1166,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
*tmpv=cache->c.pval.rs;
}else if (cache->val_type==RV_INT){
i=cache->c.pval.ri;
- tmpv->s=int2str(i, &tmpv->len);
+ tmpv->s=sint2strbuf(i, tmp_cache->i2s,
+ sizeof(tmp_cache->i2s), &tmpv->len);
+ tmp_cache->cache_type = RV_CACHE_INT2STR;
}else if (cache->val_type==RV_NONE){
goto undef;
}else goto error_cache;
@@ -1170,7 +1186,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
}else if (likely(tmp_cache->c.pval.flags & PV_VAL_INT)){
i=tmp_cache->c.pval.ri;
pv_value_destroy(&tmp_cache->c.pval);
- tmpv->s=int2str(i, &tmpv->len);
+ tmpv->s=sint2strbuf(i, tmp_cache->i2s,
+ sizeof(tmp_cache->i2s), &tmpv->len);
+ tmp_cache->cache_type = RV_CACHE_INT2STR;
}else{
/* no PV_VAL_STR and no PV_VAL_INT => undef
(PV_VAL_NULL) */
diff --git a/rvalue.h b/rvalue.h
index f658c5e..90c02b3 100644
--- a/rvalue.h
+++ b/rvalue.h
@@ -26,12 +26,14 @@
* 2009-04-28 added string and interger versions for the EQ and DIFF
* operators (andrei)
* 2009-05-05 casts operator for int & string (andrei)
+ * 2010-03-16 space for an int2str result inside rval_cache (andrei)
*/
#ifndef _rvalue_h_
#define _rvalue_h_
#include "str.h"
+#include "ut.h"
#include "usr_avp.h"
#include "select.h"
#include "pvar.h"
@@ -138,7 +140,8 @@ enum rval_cache_type{
RV_CACHE_EMPTY,
RV_CACHE_PVAR,
RV_CACHE_AVP,
- RV_CACHE_SELECT
+ RV_CACHE_SELECT,
+ RV_CACHE_INT2STR
};
/** value cache for a rvalue struct.
@@ -152,6 +155,7 @@ struct rval_cache{
int_str avp_val; /**< avp value */
pv_value_t pval; /**< pvar value */
}c;
+ char i2s[INT2STR_MAX_LEN]; /**< space for converting an int to string*/
};