blob: 835d2fc4092770f3f5f8ed18388591af5e07456a [file] [log] [blame]
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include "symtab.h"
#define DEFAULT_TABLE_SIZE 16
typedef struct {
char *symbol;
const void *cookie;
unsigned int flags;
} SymbolTableEntry;
struct SymbolTable {
SymbolTableEntry *table;
int numEntries;
int maxSize;
};
SymbolTable *
createSymbolTable()
{
SymbolTable *tab;
tab = (SymbolTable *)malloc(sizeof(SymbolTable));
if (tab != NULL) {
tab->numEntries = 0;
tab->maxSize = DEFAULT_TABLE_SIZE;
tab->table = (SymbolTableEntry *)malloc(
tab->maxSize * sizeof(SymbolTableEntry));
if (tab->table == NULL) {
free(tab);
tab = NULL;
}
}
return tab;
}
void
deleteSymbolTable(SymbolTable *tab)
{
if (tab != NULL) {
while (tab->numEntries > 0) {
free(tab->table[--tab->numEntries].symbol);
}
free(tab->table);
}
}
void *
findInSymbolTable(SymbolTable *tab, const char *symbol, unsigned int flags)
{
int i;
if (tab == NULL || symbol == NULL) {
return NULL;
}
// TODO: Sort the table and binary search
for (i = 0; i < tab->numEntries; i++) {
if (strcmp(tab->table[i].symbol, symbol) == 0 &&
tab->table[i].flags == flags)
{
return (void *)tab->table[i].cookie;
}
}
return NULL;
}
int
addToSymbolTable(SymbolTable *tab, const char *symbol, unsigned int flags,
const void *cookie)
{
if (tab == NULL || symbol == NULL || cookie == NULL) {
return -1;
}
/* Make sure that this symbol isn't already in the table.
*/
if (findInSymbolTable(tab, symbol, flags) != NULL) {
return -2;
}
/* Make sure there's enough space for the new entry.
*/
if (tab->numEntries == tab->maxSize) {
SymbolTableEntry *newTable;
int newSize;
newSize = tab->numEntries * 2;
if (newSize < DEFAULT_TABLE_SIZE) {
newSize = DEFAULT_TABLE_SIZE;
}
newTable = (SymbolTableEntry *)realloc(tab->table,
newSize * sizeof(SymbolTableEntry));
if (newTable == NULL) {
return -1;
}
tab->maxSize = newSize;
tab->table = newTable;
}
/* Insert the new entry.
*/
symbol = strdup(symbol);
if (symbol == NULL) {
return -1;
}
// TODO: Sort the table
tab->table[tab->numEntries].symbol = (char *)symbol;
tab->table[tab->numEntries].cookie = cookie;
tab->table[tab->numEntries].flags = flags;
tab->numEntries++;
return 0;
}