You are viewing a plain text version of this content. The canonical link for it is here.
Posted to rivet-dev@tcl.apache.org by David Brancato <Da...@Brancato.com> on 2002/12/11 07:20:07 UTC

Re: specifying source - 3 table method

----- Original Message -----
From: David N. Welton <da...@dedasys.com>
> "David Brancato" <Da...@Brancato.com> writes:
>
> > Yes! The separate command approach makes the most obvious sense. And
> > by using objv[0] as you mentioned, it makes it a cinch to implement
> > and maintain.
>
> I will be gone for the next few days - are you interested in having a
> go at implementing this into a nice, easily digestable patch?  Bonus
> points for pushing the necessary changes to the apreq-dev list:-)
>

Well, I came up with an alternative to the three table method that Joe
Shaefer preferred . Here's how I described it on the apreq-dev list:

"Another way to afford differentiation is to store the number of query
string elements added to the parms table in something like
ApacheRequest->nargs. Since the lead elements in the parms table are from
the query string, nargs could then be used in for loops as either an offset
(for traversing only the post parameters), an ending point (for traversing
only the query string parameters) or not at all (for traversing the entire
table)."

Joe coded this approach into apache_request.c, .h. He hasn't released
anything yet but he sent the diffs, so I inserted the changes myself and it
works well. Here's the basic jist of using ApacheRequest->nargs with the var
commands:

--- TclWebapache.c
***************
--- 134,158 ----

int TclWeb_GetVar(Tcl_Obj *result, char *varname, int source, TclWebRequest
*req)
{
    int i, j;
    array_header *parmsarray = ap_table_elts(req->apachereq->parms);
    table_entry *parms = (table_entry *)parmsarray->elts;

/* determine which part of table to traverse */
if (source == VAR_SRC_QUERYSTRING) {
    i = 0; j = req->apachereq->nargs;
} else if (source == VAR_SRC_POST) {
    i = req->apachereq->nargs; j = parmsarray->nelts;
} else {
    i = 0; j = parmsarray->nelts;
}

for (; i < j; ++i)
{
    char *parmkey = TclWeb_StringToUtf(parms[i].key, req);
    if (!strncmp(varname, parmkey,
***************

It works like this for all the var options, except for [var number] which
doesn't need to traverse the table. For that, we do:

if (source == VAR_SRC_QUERYSTRING) {
    Tcl_SetIntObj(result, req->apachereq->nargs);
} else if (source == VAR_SRC_POST) {
    Tcl_SetIntObj(result, parmsarray->nelts - req->apachereq->nargs);
} else {
    Tcl_SetIntObj(result, parmsarray->nelts);
}

Anyone see any problems with this "nargs" approach? David W, I'll send you
the sources shortly. Also, what should the new commands be named? Maybe
var_qs, var_post?

-- David Brancato




---------------------------------------------------------------------
To unsubscribe, e-mail: rivet-dev-unsubscribe@tcl.apache.org
For additional commands, e-mail: rivet-dev-help@tcl.apache.org


Re: specifying source - 3 table method

Posted by David Brancato <Da...@Brancato.com>.
----- Original Message -----
From: David N. Welton <da...@dedasys.com>
> "David Brancato" <Da...@Brancato.com> writes:
>
> > Well, I came up with an alternative to the three table method that
> > Joe Shaefer preferred . Here's how I described it on the apreq-dev
> > list:
>
> Yeah - I saw that - good work!

Thanks :)

>
> > "Another way to afford differentiation is to store the number of
> > query string elements added to the parms table in something like
> > ApacheRequest->nargs. Since the lead elements in the parms table are
> > from the query string, nargs could then be used in for loops as
> > either an offset (for traversing only the post parameters), an
> > ending point (for traversing only the query string parameters) or
> > not at all (for traversing the entire table)."
>
> > Joe coded this approach into apache_request.c, .h. He hasn't
> > released anything yet but he sent the diffs, so I inserted the
> > changes myself and it works well. Here's the basic jist of using
> > ApacheRequest->nargs with the var commands:
>
> It hasn't been committed yet, but I'm fine with patching the files we
> have in the Rivet directory.  Actually - if he doesn't commit it, I
> will post something saying that I will if no one objects.

Cool.

<snip>

> > Anyone see any problems with this "nargs" approach?
>
> Looks good to me.  Aesthetically, it's not quite as nice as the 3
> tables, approach, but it's a better solution because it uses less
> resources.  I wonder if there should be some accessors in apreq to
> automate what you're doing above?  Basically, a way to make the above
> just a little bit cleaner/less dependant on the low level details as
> an API.

Actually, there are. ApacheRequest_query_params and
ApacheRequest_post_params return tables, but I didn't use them because the
functions allocate a table each time they're called.

table *ApacheRequest_query_params(ApacheRequest *req, ap_pool *p)
{
    array_header *a = ap_palloc(p, sizeof *a);
    array_header *b = (array_header *)req->parms;

    a->elts     = b->elts;
    a->nelts    = req->nargs;

    a->nalloc   = a->nelts; /* COW hack: array push will induce copying */
    a->elt_size = sizeof(table_entry);
    return (table *)a;
}

I wasn't sure if the new table was filled using string duplication (not
familiar with this COW hack) but "array push will induce copying" makes me
believe so, so I went low. Maybe we could convince Joe Shaefer to create
forms of the functions that don't duplicate the strings.


> Oh well, we have our solution, so anything more is icing on
> the cake.
>
> > David W, I'll send you the sources shortly. Also, what should the
> > new commands be named? Maybe var_qs, var_post?
>
> var_qs isn't that immediate, but var_get certainly isn't what we want
> either.  var_querystring ?  That's wordy.  Depends on whether people
> use this stuff a lot...
>

Yeah, I'm not sure what to call it. Maybe var_qstring as a compromise?
That's the best that I can come up with. Hopefully others will chime in with
better ideas, otherwise my vote would go to var_qstring.

-- David Brancato



---------------------------------------------------------------------
To unsubscribe, e-mail: rivet-dev-unsubscribe@tcl.apache.org
For additional commands, e-mail: rivet-dev-help@tcl.apache.org


Re: specifying source - 3 table method

Posted by "David N. Welton" <da...@dedasys.com>.
"David Brancato" <Da...@Brancato.com> writes:

> Well, I came up with an alternative to the three table method that
> Joe Shaefer preferred . Here's how I described it on the apreq-dev
> list:

Yeah - I saw that - good work!
 
> "Another way to afford differentiation is to store the number of
> query string elements added to the parms table in something like
> ApacheRequest->nargs. Since the lead elements in the parms table are
> from the query string, nargs could then be used in for loops as
> either an offset (for traversing only the post parameters), an
> ending point (for traversing only the query string parameters) or
> not at all (for traversing the entire table)."

> Joe coded this approach into apache_request.c, .h. He hasn't
> released anything yet but he sent the diffs, so I inserted the
> changes myself and it works well. Here's the basic jist of using
> ApacheRequest->nargs with the var commands:

It hasn't been committed yet, but I'm fine with patching the files we
have in the Rivet directory.  Actually - if he doesn't commit it, I
will post something saying that I will if no one objects.
 
> --- TclWebapache.c
> ***************
> --- 134,158 ----
> 
> int TclWeb_GetVar(Tcl_Obj *result, char *varname, int source, TclWebRequest
> *req)
> {
>     int i, j;
>     array_header *parmsarray = ap_table_elts(req->apachereq->parms);
>     table_entry *parms = (table_entry *)parmsarray->elts;
> 
> /* determine which part of table to traverse */
> if (source == VAR_SRC_QUERYSTRING) {
>     i = 0; j = req->apachereq->nargs;
> } else if (source == VAR_SRC_POST) {
>     i = req->apachereq->nargs; j = parmsarray->nelts;
> } else {
>     i = 0; j = parmsarray->nelts;
> }
> 
> for (; i < j; ++i)
> {
>     char *parmkey = TclWeb_StringToUtf(parms[i].key, req);
>     if (!strncmp(varname, parmkey,
> ***************
> 
> It works like this for all the var options, except for [var number] which
> doesn't need to traverse the table. For that, we do:
> 
> if (source == VAR_SRC_QUERYSTRING) {
>     Tcl_SetIntObj(result, req->apachereq->nargs);
> } else if (source == VAR_SRC_POST) {
>     Tcl_SetIntObj(result, parmsarray->nelts - req->apachereq->nargs);
> } else {
>     Tcl_SetIntObj(result, parmsarray->nelts);
> }
 
> Anyone see any problems with this "nargs" approach? 

Looks good to me.  Aesthetically, it's not quite as nice as the 3
tables, approach, but it's a better solution because it uses less
resources.  I wonder if there should be some accessors in apreq to
automate what you're doing above?  Basically, a way to make the above
just a little bit cleaner/less dependant on the low level details as
an API.  Oh well, we have our solution, so anything more is icing on
the cake.

> David W, I'll send you the sources shortly. Also, what should the
> new commands be named? Maybe var_qs, var_post?

var_qs isn't that immediate, but var_get certainly isn't what we want
either.  var_querystring ?  That's wordy.  Depends on whether people
use this stuff a lot...

-- 
David N. Welton
   Consulting: http://www.dedasys.com/
     Personal: http://www.dedasys.com/davidw/
Free Software: http://www.dedasys.com/freesoftware/
   Apache Tcl: http://tcl.apache.org/

---------------------------------------------------------------------
To unsubscribe, e-mail: rivet-dev-unsubscribe@tcl.apache.org
For additional commands, e-mail: rivet-dev-help@tcl.apache.org