source: roaraudio/libroar/kstore.c @ 5443:b57e144b3ddf

Last change on this file since 5443:b57e144b3ddf was 5443:b57e144b3ddf, checked in by phi, 12 years ago

Added key based store (Closes: #199)

File size: 4.8 KB
Line 
1//kstore.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#include "libroar.h"
37
38#define _LEN_DEFAULT 16
39
40struct binkv {
41 const char * key;
42 void * value;
43};
44
45struct roar_kstore {
46 size_t refc;
47 int (*ref)(void *);
48 int (*unref)(void *);
49 const char * (*get_key)(void *);
50 size_t len;
51 struct binkv * kv;
52};
53
54struct roar_kstore * roar_kstore_new(ssize_t len,
55                                     int (*ref)(void *), int (*unref)(void *),
56                                     const char * (*get_key)(void *)) {
57 struct roar_kstore * ret = roar_mm_malloc(sizeof(struct roar_kstore));
58 int err;
59
60 if ( ret == NULL )
61  return NULL;
62
63 memset(ret, 0, sizeof(struct roar_kstore));
64
65 if ( len == -1 )
66  len = _LEN_DEFAULT;
67
68 ret->kv = roar_mm_malloc(len*sizeof(struct binkv));
69 if ( ret->kv == NULL ) {
70  err = roar_error;
71  roar_mm_free(ret);
72  roar_error = err;
73  return NULL;
74 }
75
76 memset(ret->kv, 0, len*sizeof(struct binkv));
77
78 ret->refc    = 1;
79 ret->ref     = ref;
80 ret->unref   = unref;
81 ret->get_key = get_key;
82 ret->len     = len;
83
84 return ret;
85}
86
87int                  roar_kstore_ref(struct roar_kstore * store) {
88 if ( store == NULL ) {
89  roar_err_set(ROAR_ERROR_FAULT);
90  return -1;
91 }
92
93 store->refc++;
94
95 return 0;
96}
97
98int                  roar_kstore_unref(struct roar_kstore * store) {
99 size_t i;
100
101 if ( store == NULL ) {
102  roar_err_set(ROAR_ERROR_FAULT);
103  return -1;
104 }
105
106 store->refc--;
107
108 if ( store->refc )
109  return 0;
110
111 if ( store->unref != NULL ) {
112  for (i = 0; i < store->len; i++) {
113   if ( store->kv[i].key == NULL )
114    continue;
115
116   if ( store->unref(store->kv[i].value) == -1 )
117    return -1;
118   store->kv[i].key = NULL;
119   store->kv[i].value = NULL;
120  }
121 }
122
123 roar_mm_free(store->kv);
124 roar_mm_free(store);
125
126 return 0;
127}
128
129int                  roar_kstore_add(struct roar_kstore * store, void * obj, const char * key) {
130 size_t i;
131
132 if ( store == NULL ) {
133  roar_err_set(ROAR_ERROR_FAULT);
134  return -1;
135 }
136
137 if ( key == NULL && store->get_key != NULL )
138  key = store->get_key(obj);
139
140 if ( key == NULL ) {
141  roar_err_set(ROAR_ERROR_INVAL);
142  return -1;
143 }
144
145 for (i = 0; i < store->len; i++) {
146  if ( store->kv[i].key == NULL )
147   continue;
148  if ( !strcmp(store->kv[i].key, key) ) {
149   roar_err_set(ROAR_ERROR_EXIST);
150   return -1;
151  }
152 }
153
154 for (i = 0; i < store->len; i++) {
155  if ( store->kv[i].key != NULL )
156   continue;
157  if ( store->ref != NULL )
158   if ( store->ref(obj) == -1 )
159    return -1;
160  store->kv[i].key = key;
161  store->kv[i].value = obj;
162  return 0;
163 }
164
165 roar_err_set(ROAR_ERROR_NOSPC);
166 return -1;
167}
168
169void *               roar_kstore_get(struct roar_kstore * store, const char * key) {
170 size_t i;
171
172 if ( store == NULL ) {
173  roar_err_set(ROAR_ERROR_FAULT);
174  return NULL;
175 }
176
177 for (i = 0; i < store->len; i++) {
178  if ( store->kv[i].key != NULL && !strcmp(store->kv[i].key, key) ) {
179   if ( store->ref != NULL )
180    if ( store->ref(store->kv[i].value) == -1 )
181     return NULL;
182   return store->kv[i].value;
183  }
184 }
185
186 roar_err_set(ROAR_ERROR_NOENT);
187 return NULL;
188}
189
190int                  roar_kstore_delete(struct roar_kstore * store, const char * key) {
191 size_t i;
192
193 if ( store == NULL ) {
194  roar_err_set(ROAR_ERROR_FAULT);
195  return -1;
196 }
197
198 for (i = 0; i < store->len; i++) {
199  if ( store->kv[i].key != NULL && !strcmp(store->kv[i].key, key) ) {
200   if ( store->unref != NULL )
201    if ( store->unref(store->kv[i].value) == -1 )
202     return -1;
203   store->kv[i].key = NULL;
204   store->kv[i].value = NULL;
205   return 0;
206  }
207 }
208
209 roar_err_set(ROAR_ERROR_NOENT);
210 return -1;
211}
212
213//ll
Note: See TracBrowser for help on using the repository browser.