view src/ploki/variable.c @ 10131:bbbdb09e6365

<boily> le/rn mate//Mat\xc3\xa9 is a southern hemisphere shamanist beverage that opens your inner self to the Sacred World. Its enlightened users become friendly, wishing \xe2\x80\x9cG\'day, mat\xc3\xa9!\xe2\x80\x9d to one another.
author HackBot
date Sat, 14 Jan 2017 14:02:22 +0000
parents ac0403686959
children
line wrap: on
line source

#include "config.h"
#include "Str.h"
#include "strhash.h"
#include "variable.h"
#include "xmalloc.h"

#include <assert.h>

enum {MAGIC = 23};

static void delcookie(void *c) {
	xfree(c);
}

t_vr_container *vr_new(void (*del)(void *)) {
	t_vr_container *v = xmalloc(1, sizeof *v);
	v->data = xmalloc(v->size = MAGIC, sizeof *v->data);
	v->length = 0;
	v->del = del;
	v->hash = sh_new(delcookie);
	return v;
}

void vr_delete(t_vr_container *v) {
	assert(v != NULL);
	if (v->hash) {
		vr_freeze(v);
	}
	while (v->length) {
		--v->length;
		if (v->del) {
			v->del(v->data[v->length]);
		}
	}
	xfree(v->data);
	xfree(v);
}

t_vr_cookie vr_exists(const t_vr_container *v, const char *key, size_t len) {
	t_vr_cookie *c;
	assert(v->hash != NULL);
	return (c = sh_get(v->hash, key, len)) ? *c : VR_NO_COOKIE;
}

t_vr_cookie vr_register(t_vr_container *v, const char *key, size_t len, void *val) {
	t_vr_cookie *cookie;

	assert(v->hash != NULL);
	assert(sh_get(v->hash, key, len) == NULL);

	if (v->length >= v->size) {
		v->data = xrealloc(v->data, v->size *= 2);
	}

	cookie = xmalloc(1, sizeof *cookie);
	v->data[*cookie = v->length++] = val;
	sh_put(v->hash, key, len, cookie);

	return *cookie;
}

void vr_freeze(t_vr_container *v) {
	assert(v->hash != NULL);
	sh_delete(v->hash);
	v->hash = NULL;
}

void *(vr_data)(const t_vr_container *v, t_vr_cookie c) {
	assert(v->hash == NULL);
	assert(c < v->length);
	return v->data[c];
}