/* item.c
   routines to manage the data fields for gopher items */

     /*---------------------------------------------------------------*/
     /* Xgopher        version 1.2     20 November 1991               */
     /*                version 1.1     20 April 1991                  */
     /*                version 1.0     04 March 1991                  */
     /* X window system client for the University of Minnesota        */
     /*                                Internet Gopher System.        */
     /* Allan Tuchman, University of Illinois at Urbana-Champaign     */
     /*                Computing and Communications Services Office   */
     /* Copyright 1992 by                                             */
     /*           the Board of Trustees of the University of Illinois */
     /* Permission is granted to freely copy and redistribute this    */
     /* software with the copyright notice intact.                    */
     /*---------------------------------------------------------------*/


#include <stdio.h>

#include "gopher.h"
#include "item.h"
#include "itemList.h"

#include <string.h>
#if defined(sun) || defined(sgi)
#include <strings.h>
#endif


/* Item data management routines:
	newItem()			return ptr to a gopherItem structure
	copyItem(gopherItemP)		return pointer to a copy of an item
	freeItem(gopherItemP)		free the contents of item and release
	compareItem(gopherItemP, gopherItemP) T/F; item contents are equal
	initItemFields(gopherItemP)	init fields of freshly allocated items

	getItemIndex(gopherItemP)	return an item's index search string

   debugging routines:
	printItem			print contents of an item
*/


/* newItem 
	Return a fresh empty gopher item */

gopherItemP
newItem()
{
	gopherItemP	gi;

	gi = acquireItem();

	gi->type = '\0';
	gi->plus = FALSE;

	return gi;
}


/* copyItem 
	return a copy of a gopher item */

gopherItemP
copyItem(old_gi)
gopherItemP	old_gi;
{
	gopherItemP	gi;

	if (old_gi == NULL) return NULL;

	gi = acquireItem();
	gi->type = old_gi->type;
	strncpy(USER_STRING_PREFIX(gi), USER_STRING_PREFIX(old_gi), PREFIX_LEN);
	strncpy(USER_STRING(gi), USER_STRING(old_gi), USER_STRING_LEN);
	vStringSet(&(gi->selector), vStringValue(&(old_gi->selector)));
	strncpy(gi->host, old_gi->host, HOST_STRING_LEN);
	gi->port = old_gi->port;
	gi->plus = old_gi->plus;

	return gi;
}


/* freeItem 
	Free the contents of a gopher item */

void
freeItem(gi)
gopherItemP	gi;
{
	if (gi != NULL) {

		/* most of the gopher item is static, so there is no
		   point to freeing anything.  Except the selector string.
		   For now, it is sufficient to NOT free the selector
		   however, since it will be re-used in place if possible
		   when the item is reused. */

		releaseItem(gi);
	}

	return;
}


/* compareItem 
	return boolean for two gopher items having equal content */

BOOLEAN
compareItem(g1, g2)
gopherItemP	g1, g2;
{
	if ( g1->type != g2->type )				return FALSE;
	if ( strcmp(USER_STRING(g1), USER_STRING(g2)) != 0 ) 	return FALSE;
	if ( strcmp(vStringValue(&(g1->selector)),
		    vStringValue(&(g2->selector))) != 0 ) 	return FALSE;
	if ( strcmp(g1->host, g2->host) != 0 ) 			return FALSE;
	if ( g1->port != g2->port )	 			return FALSE;

#ifdef NOTYET
	if ( g1->plus != g2->plus )	 			return FALSE;
#endif /* NOTYET */

	return TRUE;
}


/* initItemFields
	Initialize fields for newly allocated gopher items. 
	This is not used for clearing previously used items,
	otherwise it will leak dynamically allocated memory. */

void
initItemFields(gi)
gopherItemP	gi;
{
	gi->selector.len = 0;
	gi->selector.data = NULL;

	return;
}


/* getItemIndex
	return an item's index search string */
char	*
getItemIndex(gi)
gopherItemP	gi;
{
	char    *ind;
	char    *string;

	if (gi == NULL) return NULL;

	string = vStringValue(&(gi->selector));
	ind = index(string, '\t');

	if (ind != NULL) ind++;

	return ind;

}


#ifdef DEBUG_LIST


/* printItem
   Print the contents of a gopher item */

void
printItem(gi, label)
gopherItemP	 gi;
char            *label;
{
	int		i;

        if (gi == NULL) fprintf(stdout, "NULL item %s\n", label);
        else {
                fprintf (stdout, "item %s:\n", label);
		fprintf (stdout, "\t{ type:\t%c\n", gi->type);
		fprintf (stdout, "\t  prefix:\t%*s\n", PREFIX_LEN,
						       USER_STRING_PREFIX(gi));
		fprintf (stdout, "\t  user:\t%s\n", USER_STRING(gi));
		fprintf (stdout, "\t  path:\t(%d chars):%s\n",
					gi->selector.len, gi->selector.data);
		fprintf (stdout, "\t  host:\t%s\n", gi->host);
		fprintf (stdout, "\t  port:\t%d\n", gi->port);
		fprintf (stdout, "\t  plus:\t%s\n", gi->plus?"True":"False");
		fprintf (stdout, "\t}\n");
        }
}
#endif /* DEBUG_LIST */
