renamed .h and libs clicon->clixon
This commit is contained in:
parent
baa5611616
commit
79b77943f9
132 changed files with 1240 additions and 1268 deletions
343
lib/src/clixon_hash.c
Normal file
343
lib/src/clixon_hash.c
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
/*
|
||||
*
|
||||
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
|
||||
|
||||
This file is part of CLIXON.
|
||||
|
||||
CLIXON 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CLIXON 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 CLIXON; see the file LICENSE. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* A simple implementation of a associative array style data store. Keys
|
||||
* are always strings while values can be some arbitrary data referenced
|
||||
* by void*.
|
||||
*
|
||||
* XXX: functions such as hash_keys(), hash_value() etc are currently returning
|
||||
* pointers to the actual data storage. Should probably make copies.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* int main()
|
||||
* {
|
||||
* char **s;
|
||||
* int n;
|
||||
* size_t slen;
|
||||
* clicon_hash_t *hash = hash_init();
|
||||
*
|
||||
* n = 234;
|
||||
* hash_add (hash, "APA", &n, sizeof(n));
|
||||
* hash_dump(hash, stdout);
|
||||
*
|
||||
* puts("----");
|
||||
*
|
||||
* hash_add (hash, "BEPA", "hoppla Polle!", strlen("hoppla Polle!")+1);
|
||||
* puts((char *)hash_value(hash, "BEPA", NULL));
|
||||
* hash_dump(hash, stdout);
|
||||
*
|
||||
* puts("----");
|
||||
*
|
||||
* n = 33;
|
||||
* hash_add (hash, "CEPA", &n, sizeof(n));
|
||||
* hash_dump(hash, stdout);
|
||||
*
|
||||
* puts("----");
|
||||
*
|
||||
* hash_del (hash, "APA");
|
||||
* hash_dump(hash, stdout);
|
||||
*
|
||||
* hash_free(hash);
|
||||
*
|
||||
* return 0;
|
||||
* }
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "clixon_config.h" /* generated by config & autoconf */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/* clicon */
|
||||
#include "clixon_queue.h"
|
||||
#include "clixon_err.h"
|
||||
#include "clixon_hash.h"
|
||||
|
||||
#define HASH_SIZE 1031 /* Number of hash buckets. Should be a prime */
|
||||
|
||||
/*
|
||||
* A very simplistic algorithm to calculate a hash bucket index
|
||||
*/
|
||||
static uint32_t
|
||||
hash_bucket(const char *str)
|
||||
{
|
||||
uint32_t n = 0;
|
||||
|
||||
while(*str)
|
||||
n += (uint32_t)*str++;
|
||||
|
||||
return n % HASH_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize hash table.
|
||||
*
|
||||
* Arguments: none
|
||||
*
|
||||
* Returns: new pointer to hash table.
|
||||
*/
|
||||
clicon_hash_t *
|
||||
hash_init (void)
|
||||
{
|
||||
clicon_hash_t *hash;
|
||||
|
||||
if ((hash = (clicon_hash_t *)malloc (sizeof (clicon_hash_t) * HASH_SIZE)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "malloc: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
memset (hash, 0, sizeof(clicon_hash_t)*HASH_SIZE);
|
||||
return hash;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free hash table.
|
||||
*
|
||||
* Arguments:
|
||||
* hash - Hash table
|
||||
*
|
||||
* Returns: void
|
||||
*/
|
||||
void
|
||||
hash_free (clicon_hash_t *hash)
|
||||
{
|
||||
int i;
|
||||
clicon_hash_t tmp;
|
||||
for (i = 0; i < HASH_SIZE; i++) {
|
||||
while (hash[i]) {
|
||||
tmp = hash[i];
|
||||
DELQ(tmp, hash[i], clicon_hash_t);
|
||||
free(tmp->h_key);
|
||||
free(tmp->h_val);
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
free(hash);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find keys.
|
||||
*
|
||||
* key - Variable name
|
||||
*
|
||||
* Returns: variable structure on success, NULL on failure
|
||||
*/
|
||||
clicon_hash_t
|
||||
hash_lookup (clicon_hash_t *hash, const char *key)
|
||||
{
|
||||
uint32_t bkt;
|
||||
clicon_hash_t h;
|
||||
|
||||
bkt = hash_bucket(key);
|
||||
h = hash[bkt];
|
||||
if (h) {
|
||||
do {
|
||||
if (!strcmp (h->h_key, key))
|
||||
return h;
|
||||
h = NEXTQ(clicon_hash_t, h);
|
||||
} while (h != hash[bkt]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get value of hash
|
||||
*/
|
||||
void *
|
||||
hash_value(clicon_hash_t *hash, const char *key, size_t *vlen)
|
||||
{
|
||||
clicon_hash_t h;
|
||||
|
||||
h = hash_lookup(hash, key);
|
||||
if (h == NULL)
|
||||
return NULL;
|
||||
|
||||
if (vlen)
|
||||
*vlen = h->h_vlen;
|
||||
return h->h_val;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copy value and add hash entry.
|
||||
*
|
||||
* Arguments:
|
||||
* hash - Hash structure
|
||||
* key - New variable name
|
||||
* val - New variable value
|
||||
*
|
||||
* Returns: new variable on success, NULL on failure
|
||||
*/
|
||||
clicon_hash_t
|
||||
hash_add (clicon_hash_t *hash, const char *key, void *val, size_t vlen)
|
||||
{
|
||||
void *newval;
|
||||
clicon_hash_t h, new = NULL;
|
||||
|
||||
/* If variable exist, don't allocate a new. just replace value */
|
||||
h = hash_lookup (hash, key);
|
||||
if (h == NULL) {
|
||||
if ((new = (clicon_hash_t)malloc (sizeof (*new))) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "malloc: %s", strerror(errno));
|
||||
goto catch;
|
||||
}
|
||||
memset (new, 0, sizeof (*new));
|
||||
|
||||
new->h_key = strdup (key);
|
||||
if (new->h_key == NULL){
|
||||
clicon_err(OE_UNIX, errno, "strdup: %s", strerror(errno));
|
||||
goto catch;
|
||||
}
|
||||
|
||||
h = new;
|
||||
}
|
||||
|
||||
/* Make copy of lvalue */
|
||||
newval = malloc (vlen+3); /* XXX: qdbm needs aligned mallocs? */
|
||||
if (newval == NULL){
|
||||
clicon_err(OE_UNIX, errno, "malloc: %s", strerror(errno));
|
||||
goto catch;
|
||||
}
|
||||
memcpy (newval, val, vlen);
|
||||
|
||||
/* Free old value if existing variable */
|
||||
if (h->h_val)
|
||||
free (h->h_val);
|
||||
h->h_val = newval;
|
||||
h->h_vlen = vlen;
|
||||
|
||||
/* Add to list only if new variable */
|
||||
if (new)
|
||||
INSQ(h, hash[hash_bucket(key)]);
|
||||
|
||||
return h;
|
||||
|
||||
catch:
|
||||
if (new) {
|
||||
if (new->h_key)
|
||||
free (new->h_key);
|
||||
free (new);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete entry.
|
||||
*
|
||||
* Arguments:
|
||||
* hash - Hash structure
|
||||
* key - Variable name
|
||||
*
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int
|
||||
hash_del (clicon_hash_t *hash, const char *key)
|
||||
{
|
||||
clicon_hash_t h;
|
||||
|
||||
h = hash_lookup (hash, key);
|
||||
if (h == NULL)
|
||||
return -1;
|
||||
|
||||
DELQ(h, hash[hash_bucket(key)], clicon_hash_t);
|
||||
|
||||
free (h->h_key);
|
||||
free (h->h_val);
|
||||
free (h);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char **
|
||||
hash_keys(clicon_hash_t *hash, size_t *nkeys)
|
||||
{
|
||||
int bkt;
|
||||
clicon_hash_t h;
|
||||
char **tmp;
|
||||
char **keys = NULL;
|
||||
|
||||
*nkeys = 0;
|
||||
for (bkt = 0; bkt < HASH_SIZE; bkt++) {
|
||||
h = hash[bkt];
|
||||
do {
|
||||
if (h == NULL)
|
||||
break;
|
||||
tmp = realloc(keys, ((*nkeys)+1) * sizeof(char *));
|
||||
if (tmp == NULL){
|
||||
clicon_err(OE_UNIX, errno, "realloc: %s", strerror(errno));
|
||||
goto catch;
|
||||
}
|
||||
keys = tmp;
|
||||
keys[*nkeys] = h->h_key;
|
||||
(*nkeys)++;
|
||||
h = NEXTQ(clicon_hash_t, h);
|
||||
} while (h != hash[bkt]);
|
||||
}
|
||||
|
||||
return keys;
|
||||
|
||||
catch:
|
||||
if (keys)
|
||||
free(keys);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump contents of hash to FILE pointer.
|
||||
*
|
||||
* Arguments:
|
||||
* f - FILE pointer for print output
|
||||
* hash - Hash structure
|
||||
*
|
||||
* Returns: void
|
||||
*/
|
||||
void
|
||||
hash_dump(clicon_hash_t *hash, FILE *f)
|
||||
{
|
||||
int i;
|
||||
char **keys;
|
||||
void *val;
|
||||
size_t klen;
|
||||
size_t vlen;
|
||||
|
||||
if (hash == NULL)
|
||||
return;
|
||||
keys = hash_keys(hash, &klen);
|
||||
if (keys == NULL)
|
||||
return;
|
||||
|
||||
for(i = 0; i < klen; i++) {
|
||||
val = hash_value(hash, keys[i], &vlen);
|
||||
printf("%s =\t 0x%p , length %zu\n", keys[i], val, vlen);
|
||||
}
|
||||
free(keys);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue