1/*
2 * YASM associated data storage (libyasm internal use)
3 *
4 *  Copyright (C) 2003-2007  Peter Johnson
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27#include "util.h"
28
29#include "coretype.h"
30#include "assocdat.h"
31
32
33typedef struct assoc_data_item {
34    const yasm_assoc_data_callback *callback;
35    void *data;
36} assoc_data_item;
37
38struct yasm__assoc_data {
39    assoc_data_item *vector;
40    size_t size;
41    size_t alloc;
42};
43
44
45yasm__assoc_data *
46yasm__assoc_data_create(void)
47{
48    yasm__assoc_data *assoc_data = yasm_xmalloc(sizeof(yasm__assoc_data));
49
50    assoc_data->size = 0;
51    assoc_data->alloc = 2;
52    assoc_data->vector = yasm_xmalloc(assoc_data->alloc *
53                                      sizeof(assoc_data_item));
54
55    return assoc_data;
56}
57
58void *
59yasm__assoc_data_get(yasm__assoc_data *assoc_data,
60                     const yasm_assoc_data_callback *callback)
61{
62    size_t i;
63
64    if (!assoc_data)
65        return NULL;
66
67    for (i=0; i<assoc_data->size; i++) {
68        if (assoc_data->vector[i].callback == callback)
69            return assoc_data->vector[i].data;
70    }
71    return NULL;
72}
73
74yasm__assoc_data *
75yasm__assoc_data_add(yasm__assoc_data *assoc_data_arg,
76                     const yasm_assoc_data_callback *callback, void *data)
77{
78    yasm__assoc_data *assoc_data;
79    assoc_data_item *item = NULL;
80    size_t i;
81
82    /* Create a new assoc_data if necessary */
83    if (assoc_data_arg)
84        assoc_data = assoc_data_arg;
85    else
86        assoc_data = yasm__assoc_data_create();
87
88    /* See if there's already assocated data for this callback */
89    for (i=0; i<assoc_data->size; i++) {
90        if (assoc_data->vector[i].callback == callback)
91            item = &assoc_data->vector[i];
92    }
93
94    /* No?  Then append a new one */
95    if (!item) {
96        assoc_data->size++;
97        if (assoc_data->size > assoc_data->alloc) {
98            assoc_data->alloc *= 2;
99            assoc_data->vector =
100                yasm_xrealloc(assoc_data->vector,
101                              assoc_data->alloc * sizeof(assoc_data_item));
102        }
103        item = &assoc_data->vector[assoc_data->size-1];
104        item->callback = callback;
105        item->data = NULL;
106    }
107
108    /* Delete existing data (if any) */
109    if (item->data && item->data != data)
110        item->callback->destroy(item->data);
111
112    item->data = data;
113
114    return assoc_data;
115}
116
117void
118yasm__assoc_data_destroy(yasm__assoc_data *assoc_data)
119{
120    size_t i;
121
122    if (!assoc_data)
123        return;
124
125    for (i=0; i<assoc_data->size; i++)
126        assoc_data->vector[i].callback->destroy(assoc_data->vector[i].data);
127    yasm_xfree(assoc_data->vector);
128    yasm_xfree(assoc_data);
129}
130
131void
132yasm__assoc_data_print(const yasm__assoc_data *assoc_data, FILE *f,
133                       int indent_level)
134{
135    /*TODO*/
136}
137