/*
 * YASM associated data storage (libyasm internal use)
 *
 *  Copyright (C) 2003  Peter Johnson
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#define YASM_LIB_INTERNAL
#include "util.h"
/*@unused@*/ RCSID("$Id$");

#include "coretype.h"
#include "assocdat.h"


typedef struct assoc_data_item {
    const yasm_assoc_data_callback *callback;
    void *data;
} assoc_data_item;

struct yasm__assoc_data {
    assoc_data_item *vector;
    size_t size;
    size_t alloc;
};


yasm__assoc_data *
yasm__assoc_data_create(void)
{
    yasm__assoc_data *assoc_data = yasm_xmalloc(sizeof(yasm__assoc_data));

    assoc_data->size = 0;
    assoc_data->alloc = 2;
    assoc_data->vector = yasm_xmalloc(assoc_data->alloc *
				      sizeof(assoc_data_item));

    return assoc_data;
}

void *
yasm__assoc_data_get(yasm__assoc_data *assoc_data,
		     const yasm_assoc_data_callback *callback)
{
    size_t i;

    if (!assoc_data)
	return NULL;

    for (i=0; i<assoc_data->size; i++) {
	if (assoc_data->vector[i].callback == callback)
	    return assoc_data->vector[i].data;
    }
    return NULL;
}

yasm__assoc_data *
yasm__assoc_data_add(yasm__assoc_data *assoc_data_arg,
		     const yasm_assoc_data_callback *callback, void *data)
{
    yasm__assoc_data *assoc_data;
    assoc_data_item *item = NULL;
    size_t i;

    /* Create a new assoc_data if necessary */
    if (assoc_data_arg)
	assoc_data = assoc_data_arg;
    else
	assoc_data = yasm__assoc_data_create();

    /* See if there's already assocated data for this callback */
    for (i=0; i<assoc_data->size; i++) {
	if (assoc_data->vector[i].callback == callback)
	    item = &assoc_data->vector[i];
    }

    /* No?  Then append a new one */
    if (!item) {
	assoc_data->size++;
	if (assoc_data->size > assoc_data->alloc) {
	    assoc_data->alloc *= 2;
	    assoc_data->vector =
		yasm_xrealloc(assoc_data->vector,
			      assoc_data->alloc * sizeof(assoc_data_item));
	}
	item = &assoc_data->vector[assoc_data->size-1];
	item->callback = callback;
	item->data = NULL;
    }

    /* Delete existing data (if any) */
    if (item->data)
	item->callback->destroy(item->data);

    item->data = data;

    return assoc_data;
}

void
yasm__assoc_data_destroy(yasm__assoc_data *assoc_data)
{
    size_t i;

    if (!assoc_data)
	return;

    for (i=0; i<assoc_data->size; i++)
	assoc_data->vector[i].callback->destroy(assoc_data->vector[i].data);
    yasm_xfree(assoc_data->vector);
    yasm_xfree(assoc_data);
}

void
yasm__assoc_data_print(const yasm__assoc_data *assoc_data, FILE *f,
		       int indent_level)
{
    /*TODO*/
}
