|
Packit |
a38265 |
/*
|
|
Packit |
a38265 |
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
|
Packit |
a38265 |
Organisation (CSIRO) Australia
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
Redistribution and use in source and binary forms, with or without
|
|
Packit |
a38265 |
modification, are permitted provided that the following conditions
|
|
Packit |
a38265 |
are met:
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
- Redistributions of source code must retain the above copyright
|
|
Packit |
a38265 |
notice, this list of conditions and the following disclaimer.
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
- Redistributions in binary form must reproduce the above copyright
|
|
Packit |
a38265 |
notice, this list of conditions and the following disclaimer in the
|
|
Packit |
a38265 |
documentation and/or other materials provided with the distribution.
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
- Neither the name of CSIRO Australia nor the names of its
|
|
Packit |
a38265 |
contributors may be used to endorse or promote products derived from
|
|
Packit |
a38265 |
this software without specific prior written permission.
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
a38265 |
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
a38265 |
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
Packit |
a38265 |
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
|
Packit |
a38265 |
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
Packit |
a38265 |
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
Packit |
a38265 |
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
Packit |
a38265 |
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
Packit |
a38265 |
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
Packit |
a38265 |
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
Packit |
a38265 |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
a38265 |
*/
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#include "config.h"
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#include <stdlib.h>
|
|
Packit |
a38265 |
#include "oggz_macros.h"
|
|
Packit |
a38265 |
#include "oggz_vector.h"
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
typedef struct _OggzTable OggzTable;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
struct _OggzTable {
|
|
Packit |
a38265 |
OggzVector * keys;
|
|
Packit |
a38265 |
OggzVector * data;
|
|
Packit |
a38265 |
};
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
OggzTable *
|
|
Packit |
a38265 |
oggz_table_new (void)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
OggzTable * table;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
table = oggz_malloc (sizeof (OggzTable));
|
|
Packit |
a38265 |
if (table == NULL) return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
table->keys = oggz_vector_new ();
|
|
Packit |
a38265 |
table->data = oggz_vector_new ();
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return table;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
void
|
|
Packit |
a38265 |
oggz_table_delete (OggzTable * table)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
if (table == NULL) return;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
oggz_vector_delete (table->keys);
|
|
Packit |
a38265 |
oggz_vector_delete (table->data);
|
|
Packit |
a38265 |
oggz_free (table);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
void *
|
|
Packit |
a38265 |
oggz_table_lookup (OggzTable * table, long key)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
int i, size;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (table == NULL) return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
size = oggz_vector_size (table->keys);
|
|
Packit |
a38265 |
for (i = 0; i < size; i++) {
|
|
Packit |
a38265 |
if (oggz_vector_nth_l (table->keys, i) == key) {
|
|
Packit |
a38265 |
return oggz_vector_nth_p (table->data, i);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return NULL;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
void *
|
|
Packit |
a38265 |
oggz_table_insert (OggzTable * table, long key, void * data)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
void * old_data;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if ((old_data = oggz_table_lookup (table, key)) != NULL) {
|
|
Packit |
a38265 |
if (oggz_vector_remove_l (table->keys, key) == NULL)
|
|
Packit |
a38265 |
return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz_vector_remove_p (table->data, old_data) == NULL) {
|
|
Packit |
a38265 |
/* XXX: This error condition can only happen if the previous
|
|
Packit |
a38265 |
* removal succeeded, and this removal failed, ie. there was
|
|
Packit |
a38265 |
* an error reallocing table->data->data downwards. */
|
|
Packit |
a38265 |
return NULL;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz_vector_insert_l (table->keys, key) == -1)
|
|
Packit |
a38265 |
return NULL;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz_vector_insert_p (table->data, data) == NULL) {
|
|
Packit |
a38265 |
oggz_vector_remove_l (table->keys, key);
|
|
Packit |
a38265 |
return NULL;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return data;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
oggz_table_remove (OggzTable * table, long key)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
void * old_data;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if ((old_data = oggz_table_lookup (table, key)) != NULL) {
|
|
Packit |
a38265 |
if (oggz_vector_remove_l (table->keys, key) == NULL)
|
|
Packit |
a38265 |
return -1;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz_vector_remove_p (table->data, old_data) == NULL) {
|
|
Packit |
a38265 |
/* XXX: This error condition can only happen if the previous
|
|
Packit |
a38265 |
* removal succeeded, and this removal failed, ie. there was
|
|
Packit |
a38265 |
* an error reallocing table->data->data downwards. */
|
|
Packit |
a38265 |
return -1;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
oggz_table_size (OggzTable * table)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
if (table == NULL) return 0;
|
|
Packit |
a38265 |
return oggz_vector_size (table->data);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
void *
|
|
Packit |
a38265 |
oggz_table_nth (OggzTable * table, int n, long * key)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
if (table == NULL) return NULL;
|
|
Packit |
a38265 |
if (key) *key = oggz_vector_nth_l (table->keys, n);
|
|
Packit |
a38265 |
return oggz_vector_nth_p (table->data, n);
|
|
Packit |
a38265 |
}
|