/* $Id$ * $URL$ * * hashes (associative arrays) * * Copyright (C) 2003 Michael Reinelt * Copyright (C) 2004 The LCD4Linux Team * * This file is part of LCD4Linux. * * LCD4Linux is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * LCD4Linux is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* * exported functions: * * void hash_create (HASH *Hash); * initializes hash * * int hash_age (HASH *Hash, char *key, char **value); * return time of last hash_put * * void hash_put (HASH *Hash, char *key, char *val); * set an entry in the hash * * void hash_put_delta (HASH *Hash, char *key, char *val); * set a delta entry in the hash * * char *hash_get (HASH *Hash, char *key); * fetch an entry from the hash * * double hash_get_delta (HASH *Hash, char *key, int delay); * fetch a delta antry from the hash * * double hash_get_regex (HASH *Hash, char *key, int delay); * fetch one or more entries from the hash * * void hash_destroy (HASH *Hash); * releases hash * */ #include "config.h" #include #include #include #include #include "debug.h" #include "hash.h" #ifdef WITH_DMALLOC #include #endif /* number of slots for delta processing */ #define DELTA_SLOTS 64 /* string buffer chunk size */ #define CHUNK_SIZE 16 /* initialize a new hash table */ void hash_create(HASH * Hash) { Hash->sorted = 0; Hash->timestamp.tv_sec = 0; Hash->timestamp.tv_usec = 0; Hash->nItems = 0; Hash->Items = NULL; Hash->nColumns = 0; Hash->Columns = NULL; Hash->delimiter = strdup(" \t\n"); } /* bsearch compare function for hash items */ static int hash_lookup_item(const void *a, const void *b) { char *key = (char *) a; HASH_ITEM *item = (HASH_ITEM *) b; return strcasecmp(key, item->key); } /* qsort compare function for hash items */ static int hash_sort_item(const void *a, const void *b) { HASH_ITEM *ha = (HASH_ITEM *) a; HASH_ITEM *hb = (HASH_ITEM *) b; return strcasecmp(ha->key, hb->key); } /* bsearch compare function for hash headers */ static int hash_lookup_column(const void *a, const void *b) { char *key = (char *) a; HASH_COLUMN *column = (HASH_COLUMN *) b; return strcasecmp(key, column->key); } /* qsort compare function for hash headers */ static int hash_sort_column(const void *a, const void *b) { HASH_COLUMN *ha = (HASH_COLUMN *) a; HASH_COLUMN *hb = (HASH_COLUMN *) b; return strcasecmp(ha->key, hb->key); } /* split a value into columns and */ /* return the nth column in a string */ /* WARNING: does return a pointer to a static string!! */ static char *split(const char *val, const int column, const char *delimiter) { static char buffer[256]; int num; size_t len; const char *beg, *end; if (column < 0) return (char *) val; if (val == NULL) return NULL; num = 0; len = 0; beg = val; end = beg; while (beg && *beg) { while (s
c8:198500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:82
c22:482000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:82
c34:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:82
c54:738000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:82
c57:762000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:82
c64:818000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:161:82
m = &(Hash->Items[Hash->nItems - 1]); Item->key = strdup(key); Item->index = 0; Item->nSlot = delta; Item->Slot = malloc(Item->nSlot * sizeof(HASH_SLOT)); memset(Item->Slot, 0, Item->nSlot * sizeof(HASH_SLOT)); } else { /* maybe enlarge delta table */ if (Item->nSlot < delta) { Item->nSlot = delta; Item->Slot = realloc(Item->Slot, Item->nSlot * sizeof(HASH_SLOT)); } } if (Item->nSlot > 1) { /* move the pointer to the next free slot, wrap around if necessary */ if (--Item->index < 0) Item->index = Item->nSlot - 1; } /* create entry */ Slot = &(Item->Slot[Item->index]); size = strlen(value) + 1; /* maybe enlarge value buffer */ if (size > Slot->size) { /* buffer is either empty or too small */ /* allocate memory in multiples of CHUNK_SIZE */ Slot->size = CHUNK_SIZE * (size / CHUNK_SIZE + 1); Slot->value = realloc(Slot->value, Slot->size); } /* set value */ strcpy(Slot->value, value); /* set timestamps */ gettimeofday(&(Hash->timestamp), NULL); Slot->timestamp = Hash->timestamp; return Item; } /* insert a string into the hash table */ /* without delta processing */ void hash_put(HASH * Hash, const char *key, const char *value) { hash_set(Hash, key, value, 1); } /* insert a string into the hash table */ /* with delta processing */ void hash_put_delta(HASH * Hash, const char *key, const char *value) { hash_set(Hash, key, value, DELTA_SLOTS); } void hash_destroy(HASH * Hash) { int i; if (Hash->Items) { /* free all headers */ for (i = 0; i < Hash->nColumns; i++) { if (Hash->Columns[i].key) free(Hash->Columns[i].key); } /* free header table */ free(Hash->Columns); /* free all items */ for (i = 0; i < Hash->nItems; i++) { if (Hash->Items[i].key) free(Hash->Items[i].key); if (Hash->Items[i].Slot) free(Hash->Items[i].Slot); } /* free items table */ free(Hash->Items); } Hash->sorted = 0; Hash->nItems = 0; Hash->Items = NULL; }