MINOR: sample: add sample_process_cnv() function

split sample_process() in 2 parts in order to be able to only process
the converter part of a sample expression from an existing input sample
struct passed as parameter.
This commit is contained in:
Aurelien DARRAGON 2023-08-23 17:22:37 +02:00 committed by Christopher Faulet
parent 08767e162d
commit 7251344748
2 changed files with 36 additions and 21 deletions

View File

@ -39,6 +39,7 @@ struct sample_conv *find_sample_conv(const char *kw, int len);
struct sample *sample_process(struct proxy *px, struct session *sess,
struct stream *strm, unsigned int opt,
struct sample_expr *expr, struct sample *p);
int sample_process_cnv(struct sample_expr *expr, struct sample *p);
struct sample *sample_fetch_as_type(struct proxy *px, struct session *sess,
struct stream *strm, unsigned int opt,
struct sample_expr *expr, int smp_type);

View File

@ -1285,6 +1285,39 @@ struct sample_expr *sample_parse_expr(char **str, int *idx, const char *file, in
goto out;
}
/*
* Helper function to process the converter list of a given sample expression
* <expr> using the sample <p> (which is assumed to be properly initialized)
* as input.
*
* Returns 1 on success and 0 on failure.
*/
int sample_process_cnv(struct sample_expr *expr, struct sample *p)
{
struct sample_conv_expr *conv_expr;
list_for_each_entry(conv_expr, &expr->conv_exprs, list) {
/* we want to ensure that p->type can be casted into
* conv_expr->conv->in_type. We have 3 possibilities :
* - NULL => not castable.
* - c_none => nothing to do (let's optimize it)
* - other => apply cast and prepare to fail
*/
if (!sample_casts[p->data.type][conv_expr->conv->in_type])
return 0;
if (sample_casts[p->data.type][conv_expr->conv->in_type] != c_none &&
!sample_casts[p->data.type][conv_expr->conv->in_type](p))
return 0;
/* OK cast succeeded */
if (!conv_expr->conv->process(conv_expr->arg_p, p, conv_expr->conv->private))
return 0;
}
return 1;
}
/*
* Process a fetch + format conversion of defined by the sample expression <expr>
* on request or response considering the <opt> parameter.
@ -1313,8 +1346,6 @@ struct sample *sample_process(struct proxy *px, struct session *sess,
struct stream *strm, unsigned int opt,
struct sample_expr *expr, struct sample *p)
{
struct sample_conv_expr *conv_expr;
if (p == NULL) {
p = &temp_smp;
memset(p, 0, sizeof(*p));
@ -1324,25 +1355,8 @@ struct sample *sample_process(struct proxy *px, struct session *sess,
if (!expr->fetch->process(expr->arg_p, p, expr->fetch->kw, expr->fetch->private))
return NULL;
list_for_each_entry(conv_expr, &expr->conv_exprs, list) {
/* we want to ensure that p->type can be casted into
* conv_expr->conv->in_type. We have 3 possibilities :
* - NULL => not castable.
* - c_none => nothing to do (let's optimize it)
* - other => apply cast and prepare to fail
*/
if (!sample_casts[p->data.type][conv_expr->conv->in_type])
return NULL;
if (sample_casts[p->data.type][conv_expr->conv->in_type] != c_none &&
!sample_casts[p->data.type][conv_expr->conv->in_type](p))
return NULL;
/* OK cast succeeded */
if (!conv_expr->conv->process(conv_expr->arg_p, p, conv_expr->conv->private))
return NULL;
}
if (!sample_process_cnv(expr, p))
return NULL;
return p;
}