133 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * 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;
 | |
| }
 |