//-----------------------------------------------------------------------------
// Copyright © 2003 - Philip Howard - All rights reserved
//
// This program 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
//-----------------------------------------------------------------------------
// package	libh/cgi
// homepage	http://libh.slashusr.org/
//-----------------------------------------------------------------------------
// author	Philip Howard
// email	libh at ipal dot org
// homepage	http://phil.ipal.org/
//-----------------------------------------------------------------------------
// This file is best viewed using a fixed spaced font such as Courier
// and in a display at least 120 columns wide.
//-----------------------------------------------------------------------------
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "cgi_lib.h"


__PROTO_BEGIN__
//-----------------------------------------------------------------------------
// function	cgi_form_map
//
// purpose	Fill mappings from web page form variables from either query
//		string or post request method or both, in a CGI conforming web
//		server environment (such as Apache).
//
// usage	Call cgi_form_map() to fill one or two mappings from web form
//		variables, then use the map_str_*() functions to access those
//		variables including multiple instances of the same variable
//		name.  When the mapping is no longer needed, its memory can
//		be recovered by calling map_destroy() for each map.
//
// arguments	1 (MAP) mapping to fill in with variables from query string
//		2 (MAP) mapping to fill in with variables from post content
//
// returns	(int) >=  0 : count of total variables from both sources
//		(int)  < -1 : error
//
// note		If cgi_form_map is used, do not use cgi_form_parse or any of
//		the cgi_form_fetch functions.
//
// note		If the browser passes the same variable name multiple times,
//		only one of the values will be returned.  Usually it will be
//		the first one, but not always.  For access to multiple
//		variable instances, do not use cgi_form_fetch(), but instead
//		use either cgi_form_map() in conjunction with the map library
//		functions, or use cgi_form_parse() in a loop to pick up all
//		the variables in sequence.
//
// note		No information is available to identify whether the variable
//		came from the query string or the post content.  If that
//		information is needed, use cgi_form_parse() directly instead.
//-----------------------------------------------------------------------------
int
cgi_form_map (
    MAP			arg_query_string_map
    ,
    MAP			arg_post_content_map
    )
    __PROTO_END__
{
    static int		state		= 0;
    int			count		;


    //---------------------------------------------------------
    // If this is not the first time, reloading cannot be done.
    //---------------------------------------------------------
    if ( state != 0 ) return -1;
    count = 0;

    //---------------------
    // Fill in the mapping.
    //---------------------
    for (;;) {
	MAP		this_map	;
	char *		name_ptr	;
	size_t		name_len	;
	char *		value_ptr	;
	size_t		value_len	;
	int		var_src		;

	var_src = cgi_form_parse( & name_ptr, & name_len, & value_ptr, & value_len );
	if ( var_src == CGI_FORM_SRC_QUERY_STRING ) {
	    this_map = arg_query_string_map;
	}
	else if ( var_src == CGI_FORM_SRC_POST_CONTENT ) {
	    this_map = arg_post_content_map;
	}
	else {
	    break;
	}
	if ( this_map ) {
	    if ( map_ca_insert_dup( this_map, name_ptr, name_len ) > 0 ) {
		map_ca_store( this_map, value_ptr, value_len );
	    }
	}
	++ count;
    }

    //-----------
    // Finish up.
    //-----------
    cgi_form_parse_finish();
    state = 1;

    //--------------
    // Return count.
    //--------------
    return count;
}

