/*
 *
 *
 *    cgi.cc
 *
 *    C++ source code for class X, Y and Z member functions and/or static
 *    member data.
 *
 *    =========================================================================
 *
 *    Copyright (C) 1999-2003 by Matt Roberts, KK5JY.
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation; either
 *    version 2.1 of the License, or (at your option) any later version.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *    =========================================================================
 *
 *
 */


#include <my++/cgi.h>

using namespace std;


/*
 *
 *   The ~CGI destructor simply 'delete's all of the CGI_Field's that were
 *   allocated in the constructor
 *
 */

my::cgi::~cgi (void) {
	list_type::iterator vi;
	field *fp = *vi;

	for (vi = cf_vec.begin(); vi != cf_vec.end(); vi++) {
		fp = *vi;
		delete fp;
	}
}


/*
 *
 *   The 'getValue' function searches the posted data for a variable with
 *   name 'name' and returns its value as a 'std::string'
 *
 */

std::string my::cgi::getValue (const std::string &name) {
	static std::string empty ("");
	for (size_t i = 0; i < cf_vec.size(); ++i)
		if (cf_vec[i]->name() == name)
			return cf_vec[i]->value();
	return empty;
}

std::string my::cgi::getValue (const char *name) {
	static std::string empty ("");
	for (size_t i = 0; i < cf_vec.size(); i++)
		if (cf_vec[i]->name() == name)
			return cf_vec[i]->value();
	return empty;
}


/*
 *
 *    The 'CGI' constructor is responsible for querying the environment,
 *    drawing the data from the input stream, parsing that data, and making
 *    it ready for retrieval by the user program.
 *
 */

my::cgi::cgi (istream &in) {
	field *cf = 0;
	unsigned len = 0;
	char *c_buf = 0;
	std::string c_field;
	std::string content;

	valid = false;

	/* grab the CONTENT_LENGTH environment variable */
	c_buf = getenv ("CONTENT_LENGTH");
	if (!c_buf) {
		/* error condition */
		return;
	}

	/* read the content length into 'len' */
	istringstream env_var (c_buf);
	env_var >> len;

	/* allocate enough char[] space to hold the content */
	if (len == 0)
		return;

	/* get the content */
	getline (in, content);
	istringstream input (content.c_str());

	/* break the content by variable, and make new fields to hold them */
	while (input) {
		c_field.erase();
		getline (input, c_field, '&');
		if (c_field.length () <= 2)
			continue;
		cf = new field (c_field);
		cf_vec.push_back (cf);
	}

	valid = true;
}
