Boost logo

Boost :

From: Phil Endecott (spam_from_boost_dev_at_[hidden])
Date: 2007-08-25 09:02:05


Hi Darren,

Darren Garvey wrote:
> On 20/08/07, Phil Endecott <spam_from_boost_dev_at_[hidden]> wrote:
>>
>> <!-- snip -->
>> > cgi::request req;
>> > cgi::map& form_map = req.meta_form();
>>
>> Good. If I were you, I would advertise this as the primary way to
>> access the data, i.e.
>>
>> string frob = req.form ["frob"];
>>
>> <!-- snip -->
>>
>> ...we all know how to do this with a std::map:
>>
>> cgi::map::const_iterator i = req.form.find("frob");
>> if (i==req.form.end()) {
>> ....not set....
>> } else {
>> string frob = i->second;
>> .......
>> }
>>
>> (OK, you might think that's ugly too, but it's "standard ugly". The
>> main point is that a user already knows how to do this, and doesn't
>> need to refer to your docs to discover your is_unset() function or
>> whatever.)
>
>
> I agree that the 'standard' way should be encouraged more. At the same time,
> the member function version has the advantage that there is no requirement
> to parse all of the variables unless it's needed, which is a bonus in the
> cast of POST data.

I think you could implement a map-like interface that parses the input
lazily. Presumably you have a parser for each form-data format that
provides some sort of iterator-adapter, which takes a forward iterator
over the character data and returns an iterator over name-value string
pairs. I think I've already suggested that these parsers should be
accessible independent of the rest of the library.

> Plus, I'm not too keen on allowing direct access to the variables.

Why?

> What I
> put in for now seems (to me) like a reasonable compromise:
>
> request req;
> cgi::map& form_map = req.form_(); // returns the map of the form variables
> std::string name = req.form_()["name"]; // direct access like this
> name = req.form_()["name"]->first; // or even like this!
> BOOST_ASSERT( name == req.form_("name")); // shortcut to the above
> (obviously)
>
> The reasoning behind the trailing underscore, is to avoid req.get() and
> req.post(), which I think are misleading (as is req.get_var()). This is
> about the fifth iteration for these functions' names, but I quite like this
> one. Any better suggestions?

req.form_data

>> Note that [the data map] can't currently be used for environment
>> variables: this will
>> > probably change, but with the warning that it's going to be much slower
>> for standard CGI.
>>
>> Why? I don't think getenv is particularly slow.
>> Actually a small library that implements a std::map-like interface to
>> the environment variables would be useful in itself. I encourage you
>> to take every opportunity to make components that can be used
>> independently, as this could.
>
>
> I finally discovered `extern char ** environ;`. Exactly what's needed; I've
> added this so now access is uniform across variable types. :) (if you're
> interested: *http://tinyurl.com/2delnd* - it's not a 'map-like interface'
> though, it just copies the environment data into a map<string,string>. It
> probably needs profiling and tweaking too).

Well a const map<string,const char*> would probably be about as good as
you can get, i.e. don't copy the values of the environment variables.

Regards,

Phil.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk