Index: ChangeLog
===================================================================
--- ChangeLog	(revision 5423)
+++ ChangeLog	(revision 5443)
@@ -1,4 +1,5 @@
 v. 1.0beta1 - ?
 	* Added support to load plugins from search path
+	* Added key based store (Closes: #199)
 
 v. 1.0beta0 - Fri Mar 16 2012 19:39 CET
Index: include/libroar/kstore.h
===================================================================
--- include/libroar/kstore.h	(revision 5443)
+++ include/libroar/kstore.h	(revision 5443)
@@ -0,0 +1,61 @@
+//kstore.h:
+
+/*
+ *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012
+ *
+ *  This file is part of libroar a part of RoarAudio,
+ *  a cross-platform sound system for both, home and professional use.
+ *  See README for details.
+ *
+ *  This file is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3
+ *  as published by the Free Software Foundation.
+ *
+ *  libroar 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 software; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ *  NOTE for everyone want's to change something and send patches:
+ *  read README and HACKING! There a addition information on
+ *  the license of this document you need to read before you send
+ *  any patches.
+ *
+ *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
+ *  or libpulse*:
+ *  The libs libroaresd, libroararts and libroarpulse link this lib
+ *  and are therefore GPL. Because of this it may be illigal to use
+ *  them with any software that uses libesd, libartsc or libpulse*.
+ */
+
+#ifndef _LIBROARKSTORE_H_
+#define _LIBROARKSTORE_H_
+
+#include "libroar.h"
+
+struct roar_kstore;
+
+struct roar_kstore * roar_kstore_new(ssize_t len,
+                                     int (*ref)(void *), int (*unref)(void *),
+                                     const char * (*get_key)(void *));
+int                  roar_kstore_ref(struct roar_kstore * store);
+int                  roar_kstore_unref(struct roar_kstore * store);
+
+int                  roar_kstore_add(struct roar_kstore * store, void * obj, const char * key);
+void *               roar_kstore_get(struct roar_kstore * store, const char * key);
+int                  roar_kstore_delete(struct roar_kstore * store, const char * key);
+
+// aliases:
+#define roar_kstore_new_connection(len) roar_kstore_new((len),                \
+                                        (int (*)(void*))roar_connectionref,   \
+                                        (int (*)(void*))roar_connectionunref, \
+                                        (const char * (*)(void*))roar_get_connection_server)
+
+#endif
+
+//ll
Index: include/libroar/libroar.h
===================================================================
--- include/libroar/libroar.h	(revision 5381)
+++ include/libroar/libroar.h	(revision 5443)
@@ -186,4 +186,5 @@
 #include "notify_proxy.h"
 #include "asyncctl.h"
+#include "kstore.h"
 
 // some basic macros:
Index: libroar/Makefile
===================================================================
--- libroar/Makefile	(revision 5387)
+++ libroar/Makefile	(revision 5443)
@@ -11,5 +11,5 @@
 PASSWORD=passwordapi.o pinentry.o sshaskpass.o
 CRYPTO=crypto.o random.o $(HASHES) crc.o
-OBJS=libroar.o config.o debug.o error.o basic.o stream.o client.o simple.o auth.o socket.o ctl.o buffer.o meta.o file.o acl.o cdrom.o $(PASSWORD) $(VIO) stack.o slp.o nnode.o roardl.o plugincontainer.o roarx11.o beep.o proto.o env.o keyval.o vs.o ltm.o notify.o notify_proxy.o asyncctl.o enumdev.o serverinfo.o $(CRYPTO) authfile.o caps.o roarfloat.o base64.o trap.o memmgr.o time.o
+OBJS=libroar.o config.o debug.o error.o basic.o stream.o client.o simple.o auth.o socket.o ctl.o buffer.o meta.o file.o acl.o cdrom.o $(PASSWORD) $(VIO) stack.o slp.o nnode.o roardl.o plugincontainer.o roarx11.o beep.o proto.o env.o keyval.o vs.o ltm.o notify.o notify_proxy.o asyncctl.o enumdev.o serverinfo.o $(CRYPTO) authfile.o caps.o roarfloat.o base64.o trap.o memmgr.o time.o kstore.o
 
 #DEFINES        = -DDEBUG
Index: libroar/kstore.c
===================================================================
--- libroar/kstore.c	(revision 5443)
+++ libroar/kstore.c	(revision 5443)
@@ -0,0 +1,213 @@
+//kstore.c:
+
+/*
+ *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012
+ *
+ *  This file is part of libroar a part of RoarAudio,
+ *  a cross-platform sound system for both, home and professional use.
+ *  See README for details.
+ *
+ *  This file is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3
+ *  as published by the Free Software Foundation.
+ *
+ *  libroar 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 software; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ *  NOTE for everyone want's to change something and send patches:
+ *  read README and HACKING! There a addition information on
+ *  the license of this document you need to read before you send
+ *  any patches.
+ *
+ *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
+ *  or libpulse*:
+ *  The libs libroaresd, libroararts and libroarpulse link this lib
+ *  and are therefore GPL. Because of this it may be illigal to use
+ *  them with any software that uses libesd, libartsc or libpulse*.
+ */
+
+#include "libroar.h"
+
+#define _LEN_DEFAULT 16
+
+struct binkv {
+ const char * key;
+ void * value;
+};
+
+struct roar_kstore {
+ size_t refc;
+ int (*ref)(void *);
+ int (*unref)(void *);
+ const char * (*get_key)(void *);
+ size_t len;
+ struct binkv * kv;
+};
+
+struct roar_kstore * roar_kstore_new(ssize_t len,
+                                     int (*ref)(void *), int (*unref)(void *),
+                                     const char * (*get_key)(void *)) {
+ struct roar_kstore * ret = roar_mm_malloc(sizeof(struct roar_kstore));
+ int err;
+
+ if ( ret == NULL )
+  return NULL;
+
+ memset(ret, 0, sizeof(struct roar_kstore));
+
+ if ( len == -1 )
+  len = _LEN_DEFAULT;
+
+ ret->kv = roar_mm_malloc(len*sizeof(struct binkv));
+ if ( ret->kv == NULL ) {
+  err = roar_error;
+  roar_mm_free(ret);
+  roar_error = err;
+  return NULL;
+ }
+
+ memset(ret->kv, 0, len*sizeof(struct binkv));
+
+ ret->refc    = 1;
+ ret->ref     = ref;
+ ret->unref   = unref;
+ ret->get_key = get_key;
+ ret->len     = len;
+
+ return ret;
+}
+
+int                  roar_kstore_ref(struct roar_kstore * store) {
+ if ( store == NULL ) {
+  roar_err_set(ROAR_ERROR_FAULT);
+  return -1;
+ }
+
+ store->refc++;
+
+ return 0;
+}
+
+int                  roar_kstore_unref(struct roar_kstore * store) {
+ size_t i;
+
+ if ( store == NULL ) {
+  roar_err_set(ROAR_ERROR_FAULT);
+  return -1;
+ }
+
+ store->refc--;
+
+ if ( store->refc )
+  return 0;
+
+ if ( store->unref != NULL ) {
+  for (i = 0; i < store->len; i++) {
+   if ( store->kv[i].key == NULL )
+    continue;
+
+   if ( store->unref(store->kv[i].value) == -1 )
+    return -1;
+   store->kv[i].key = NULL;
+   store->kv[i].value = NULL;
+  }
+ }
+
+ roar_mm_free(store->kv);
+ roar_mm_free(store);
+
+ return 0;
+}
+
+int                  roar_kstore_add(struct roar_kstore * store, void * obj, const char * key) {
+ size_t i;
+
+ if ( store == NULL ) {
+  roar_err_set(ROAR_ERROR_FAULT);
+  return -1;
+ }
+
+ if ( key == NULL && store->get_key != NULL )
+  key = store->get_key(obj);
+
+ if ( key == NULL ) {
+  roar_err_set(ROAR_ERROR_INVAL);
+  return -1;
+ }
+
+ for (i = 0; i < store->len; i++) {
+  if ( store->kv[i].key == NULL )
+   continue;
+  if ( !strcmp(store->kv[i].key, key) ) {
+   roar_err_set(ROAR_ERROR_EXIST);
+   return -1;
+  }
+ }
+
+ for (i = 0; i < store->len; i++) {
+  if ( store->kv[i].key != NULL )
+   continue;
+  if ( store->ref != NULL )
+   if ( store->ref(obj) == -1 )
+    return -1;
+  store->kv[i].key = key;
+  store->kv[i].value = obj;
+  return 0;
+ }
+
+ roar_err_set(ROAR_ERROR_NOSPC);
+ return -1;
+}
+
+void *               roar_kstore_get(struct roar_kstore * store, const char * key) {
+ size_t i;
+
+ if ( store == NULL ) {
+  roar_err_set(ROAR_ERROR_FAULT);
+  return NULL;
+ }
+
+ for (i = 0; i < store->len; i++) {
+  if ( store->kv[i].key != NULL && !strcmp(store->kv[i].key, key) ) {
+   if ( store->ref != NULL )
+    if ( store->ref(store->kv[i].value) == -1 )
+     return NULL;
+   return store->kv[i].value;
+  }
+ }
+
+ roar_err_set(ROAR_ERROR_NOENT);
+ return NULL;
+}
+
+int                  roar_kstore_delete(struct roar_kstore * store, const char * key) {
+ size_t i;
+
+ if ( store == NULL ) {
+  roar_err_set(ROAR_ERROR_FAULT);
+  return -1;
+ }
+
+ for (i = 0; i < store->len; i++) {
+  if ( store->kv[i].key != NULL && !strcmp(store->kv[i].key, key) ) {
+   if ( store->unref != NULL )
+    if ( store->unref(store->kv[i].value) == -1 )
+     return -1;
+   store->kv[i].key = NULL;
+   store->kv[i].value = NULL;
+   return 0;
+  }
+ }
+
+ roar_err_set(ROAR_ERROR_NOENT);
+ return -1;
+}
+
+//ll
