package CGI::QueryString;
# $Id: QueryString.pm,v 1.26 2000/12/08 02:02:26 tom Exp $
################################################################

=head1 NAME

CGI::QueryString - CGIクエリーの処理

=cut
    
################################################################

use strict;

use Exporter;
use vars qw(@ISA @EXPORT);

use JConv;
use CGI::Tools;

@ISA = qw(Exporter);
@EXPORT = qw(query_string param);

my $InternalJcode = qq(euc);
my $QueryString;
my %Parameter;
my $Parsed = 0;

################################################################

=head1 STATIC FUNCTIONS

=head2 ParseQuery($query)

再度 $QUERY_STRING から値を取り出し、セットする。
$query を与えれば、それを $QUERY_STRING と見做す

=cut
    
sub ParseQuery(;$)
{
#    PrintHTTPHeader();
#    print "parse query:", times(), "<br>";
#    print "RELODED, ";
    my $query = shift;
    my $method = $ENV{'REQUEST_METHOD'} || "";

    
#    print "content-type: text/html\n\nRELOADED, ";

    # クエリが指定されているか、初めてのリクエストだったら解析
    return unless $query || !$Parsed; # IsNewRequest();
    $Parsed = 1;
    if (&CGI::Tools::IsModPerl()){
	Apache->request->register_cleanup(\&GlobalInitializer::CleanupGlobals);
    }

    if ($query){        # 引数があればそれをセット
	$QueryString = $query;
    } else {            # なければ取得
	if ($method =~ /^(GET|HEAD)$/o){
	    $QueryString = $ENV{'QUERY_STRING'};
	} elsif ($method eq 'POST'){
	    read(STDIN, $QueryString, $ENV{'CONTENT_LENGTH'});
#	    print "content-type: text/html\n\n";
#	    print "POST read<br>";
	} else {                # command line
	    $QueryString = join('&', @ARGV);
	}
    }
    # パラメータに分解
    *conv = mkjconv('auto', $InternalJcode);
    for (split("&", $QueryString)){
	my ($key, $value) = split("=");
	if (defined $value){
	    $value =~ tr/+/ /;       # pluses become spaces
	    $value =~ s/%([0-9a-fA-F]{2})/pack("c",hex($1))/ge;
	    conv(\$value);
	    $Parameter{$key} = $value;
#	    die "$key: $value";
#	    print "$key, $value : $Parameter{$key} ";
	} else {
	    $Parameter{keywords} = $key;
	}
    }
#    print "parse done.:", times(), "<br>";
}
################################################################

sub query_string(;$)
{
    my $query = shift;
    if ($query){
	ParseQuery($query);
	return $query;
    } else {
	ParseQuery();
	return $QueryString;
    }
}

=head2 param($key, $value)

$key の値を取り出す。
２つ引数が与えられた時はセット

=cut

sub param(;$$)
{
    my ($key, $value) = @_;
#    print "param($key):\n";
    ParseQuery();

    unless ($key){
	return keys %Parameter;
    }
    unless ($value){
	$value = $Parameter{$key};
    } else {
	$Parameter{$key} = $value;
    }
#    print "value: $value\n";

    return $value || "";
}

sub SetInternalJcode($)
{
    my $code = shift;

    $InternalJcode = $code;
}
		      
1;
