#-*-perl-*-
#
#  soif.pl - Processing for the SOIF format.
#
#  Darren Hardy, hardy@cs.colorado.edu, January 1995
#
#  $Id: soif.pl,v 1.12 1995/09/05 20:18:16 hardy Exp $
#
#######################################################################
#  Usage:
#
#    require 'soif.pl';
#    
#    $soif'input = 'WHATEVER'; 	# defaults to STDIN
#    ($ttype, $url, %SOIF) = &soif'parse();
#    foreach $k (sort keys %SOIF) {
#        print "KEY: $k\n";
#        print "DATA: $SOIF{$k}\n";
#    }
#    exit(0);
#    
#######################################################################
#  Copyright (c) 1994, 1995.  All rights reserved.
#  
#    The Harvest software was developed by the Internet Research Task
#    Force Research Group on Resource Discovery (IRTF-RD):
#  
#          Mic Bowman of Transarc Corporation.
#          Peter Danzig of the University of Southern California.
#          Darren R. Hardy of the University of Colorado at Boulder.
#          Udi Manber of the University of Arizona.
#          Michael F. Schwartz of the University of Colorado at Boulder.
#          Duane Wessels of the University of Colorado at Boulder.
#  
#    This copyright notice applies to software in the Harvest
#    ``src/'' directory only.  Users should consult the individual
#    copyright notices in the ``components/'' subdirectories for
#    copyright information about other software bundled with the
#    Harvest source code distribution.
#  
#  TERMS OF USE
#    
#    The Harvest software may be used and re-distributed without
#    charge, provided that the software origin and research team are
#    cited in any use of the system.  Most commonly this is
#    accomplished by including a link to the Harvest Home Page
#    (http://harvest.cs.colorado.edu/) from the query page of any
#    Broker you deploy, as well as in the query result pages.  These
#    links are generated automatically by the standard Broker
#    software distribution.
#    
#    The Harvest software is provided ``as is'', without express or
#    implied warranty, and with no support nor obligation to assist
#    in its use, correction, modification or enhancement.  We assume
#    no liability with respect to the infringement of copyrights,
#    trade secrets, or any patents, and are not responsible for
#    consequential damages.  Proper use of the Harvest software is
#    entirely the responsibility of the user.
#  
#  DERIVATIVE WORKS
#  
#    Users may make derivative works from the Harvest software, subject 
#    to the following constraints:
#  
#      - You must include the above copyright notice and these 
#        accompanying paragraphs in all forms of derivative works, 
#        and any documentation and other materials related to such 
#        distribution and use acknowledge that the software was 
#        developed at the above institutions.
#  
#      - You must notify IRTF-RD regarding your distribution of 
#        the derivative work.
#  
#      - You must clearly notify users that your are distributing 
#        a modified version and not the original Harvest software.
#  
#      - Any derivative product is also subject to these copyright 
#        and use restrictions.
#  
#    Note that the Harvest software is NOT in the public domain.  We
#    retain copyright, as specified above.
#  
#  HISTORY OF FREE SOFTWARE STATUS
#  
#    Originally we required sites to license the software in cases
#    where they were going to build commercial products/services
#    around Harvest.  In June 1995 we changed this policy.  We now
#    allow people to use the core Harvest software (the code found in
#    the Harvest ``src/'' directory) for free.  We made this change
#    in the interest of encouraging the widest possible deployment of
#    the technology.  The Harvest software is really a reference
#    implementation of a set of protocols and formats, some of which
#    we intend to standardize.  We encourage commercial
#    re-implementations of code complying to this set of standards.  
#  
#  
#  
package soif;

$soif'debug = 0;
$soif'input = 'STDIN';
$soif'output = 'STDOUT';
$soif'sort_on_output = 0;

#
#  soif'parse - $soif'input is the file descriptor from which to read SOIF.
#  	        Returns an associative array containing the SOIF,
#		the template type, and the URL.
#
sub soif'parse {
	print "Inside soif'parse.\n" if ($soif'debug);

        return () if (eof($soif'input));       # DW
	local($template_type) = "UNKNOWN";
	local($url) = "UNKNOWN";
	local(%SOIF);
	undef %SOIF;
	local ($attr, $vsize, $value, $end_value);

	while (<$soif'input>) {
		print "READING input line: $_\n" if ($soif'debug);
		last if (/^\@\S+\s*{\s*\S+\s*$/o);
	}
	if (/^\@(\S+)\s*{\s*(\S+)\s*$/o) {
		$template_type = $1, $url = $2;
	} else {
		return ($template_type, $url, %SOIF);	# done
	}

	while (<$soif'input>) {
                if (/^\s*([^{]+){(\d+)}:\t(.*\n)/o) {
			$attr = $1;
			$vsize = $2;
			$value = $3;
			if (length($value) < $vsize) {
				$nleft = $vsize - length($value);
				$end_value = "";
				$x = read($soif'input, $end_value, $nleft);
				die "Cannot read $nleft bytes: $!" 
					if ($x != $nleft);
				$value .= $end_value;
				undef $end_value;
			}
                        chop ($value) if ($value =~ /\n$/);
                        $SOIF{$attr} = $value;
			undef $value;
			undef $end_value;
			next;
		} 
		last if (/^}/o);
	}

	return ($template_type, $url, %SOIF);
}

#
#  soif'print - $soif'output is the file descriptor to write SOIF.
#
sub soif'print {
	print "Inside soif'print.\n" if ($soif'debug);
	local($template_type, $url, %SOIF) = @_;

	# Write SOIF header, body, and trailer
	print $soif'output "\@$template_type { $url\n";
	if ($soif'sort_on_output) {
		foreach $k (sort keys %SOIF) {
			&soif'print_av($k, $SOIF{$k});
		}
	} else {
		while (($k, $v) = each %SOIF) {
			&soif'print_av($k, $v);
		}
	}
	print $soif'output "}\n";
}


sub soif'print_av {
	local($k, $v) = @_;
	return if (length($v) < 1);
	print $soif'output $k;
	print $soif'output "{", length($v), "}:\t";
	print $soif'output $v;
	print $soif'output "\n";
}

# for backwards compatiablity
sub soif'print_item { 
	local($k, $v) = @_;
	&soif'print_av($k, $v);
}
1;
