/* %Z%%M% %I% %E% */

/*
 * Copyright (c) 1990, 1991, 1995 by Wayne C. Gramlich.
 * All rights reserved.
 *
 * Permission to use, copy, modify, distribute, and sell this software
 * for any purpose is hereby granted without fee provided that the above
 * copyright notice and this permission are retained.  The author makes
 * no representations about the suitability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 */

/*
 * This file implements a trivial attribute-value list package.
 *
 * Linear searches are used, so long lists are inappropriate for this
 * implementation.
 */

#ifndef AVLIST_EXPORTS_H
#include "avlist_exports.h"
#endif

#ifndef HEAP_EXPORTS_H
#include "heap_exports.h"
#endif

#ifndef VECTOR_EXPORTS_H
#include "vector_exports.h"
#endif

struct Avlist_struct {
	Vec(Pointer)	attributes;	/* Attribute list */
	Heap		heap;		/* Heap allocated from */
	Vec(Pointer)	values;		/* Value list */
};

/* LINTLIBRARY */

/*
 * avlist_create(heap)
 *	This routine will return a new attribute-value list object allocated
 *	from "heap".
 */
Avlist
avlist_create(
	Heap		heap)
{
	Avlist		avlist;

	avlist = heap_allocate(heap, Avlist);
	avlist->attributes = vec_create(Pointer, heap);
	avlist->heap = heap;
	avlist->values = vec_create(Pointer, heap);
	return avlist;
}

/*
 * avlist_lookup(avlist, attribute)
 *	This routine will return the value assocated with "attribute" in
 *	"avlist".  If there is no such value, (Pointer)0 is returned.
 */
Pointer
avlist_lookup(
	Avlist		avlist,
	Pointer		attribute)
{
	Vec(Pointer)	attributes;
	int		index;
	int		size;

	attributes = avlist->attributes;
	size = vec_size(Pointer, attributes);
	for (index = 0; index < size; index++) {
		if (attribute == vec_fetch(Pointer, attributes, index)) {
			return vec_fetch(Pointer, avlist->values, index);
		}
	}
	return (Pointer)0;
}

/*
 * avlist_insert(avlist, attribute, value)
 *	This routine will insert "attribute" and "value" into "avlist".  If
 *	"attribute" is already in "avlist", the previous value is replaced.
 */
void
avlist_insert(
	Avlist		avlist,
	Pointer		attribute,
	Pointer		value)
{
	Vec(Pointer)	attributes;
	int		index;
	int		size;

	attributes = avlist->attributes;
	size = vec_size(Pointer, attributes);
	for (index = 0; index < size; index++) {
		if (attribute == vec_fetch(Pointer, attributes, index)) {
			vec_store(Pointer, avlist->values, index, value);
			return;
		}
}
	vec_append(Pointer, attributes, attribute);
	vec_append(Pointer, avlist->values, value);
}
