renamed .h and libs clicon->clixon

This commit is contained in:
Olof Hagsand 2016-02-28 15:27:36 +01:00
parent baa5611616
commit 79b77943f9
132 changed files with 1240 additions and 1268 deletions

343
lib/src/clixon_hash.c Normal file
View 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);
}