source: roaraudio/libroar/keyval.c @ 5661:efd1ca5963ee

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

Improved kv API: added roar_keyval_copy()

File size: 5.2 KB
Line 
1//keyval.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-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
38struct roar_keyval * roar_keyval_lookup (struct roar_keyval *  kv, const char * key, ssize_t len, int casesens) {
39 int (*sc)(const char *s1, const char *s2) = strcasecmp;
40 ssize_t i;
41
42 ROAR_DBG("roar_keyval_lookup(kv=%p, key=%p'%s', len=%li, casesens=%i) = ?", kv, key, key, (long int)len, casesens);
43
44 if ( kv == NULL || key == NULL ) {
45  ROAR_DBG("roar_keyval_lookup(kv=%p, key=%p'%s', len=%li, casesens=%i) = NULL //error=FAULT", kv, key, key, (long int)len, casesens);
46  roar_err_set(ROAR_ERROR_FAULT);
47  return NULL;
48 }
49
50 if ( casesens )
51  sc = strcmp;
52
53 for (i = 0; len != -1 ? (i < len) : kv[i].key != NULL; i++) {
54  if ( kv[i].key != NULL && !sc(key, kv[i].key) )
55   return &(kv[i]);
56 }
57
58 ROAR_DBG("roar_keyval_lookup(kv=%p, key=%p'%s', len=%li, casesens=%i) = NULL //error=NOENT", kv, key, key, (long int)len, casesens);
59 roar_err_set(ROAR_ERROR_NOENT);
60 return NULL;
61}
62
63static inline int is_in (const char c, const char * delm) {
64 for (; *delm != 0; delm++)
65  if ( *delm == c )
66   return 1;
67
68 return 0;
69}
70
71static inline void skip_char(char * str) {
72 memmove(str, str+1, roar_mm_strlen(str));
73}
74
75ssize_t              roar_keyval_split  (struct roar_keyval ** kv, char * str, const char * fdel, const char * kdel, int quotes) {
76 struct roar_keyval * kvs;
77 int    pos = -1;
78 size_t len =  0;
79 char * sp;
80 char quote =  0;
81 int last_was_seg = 0;
82
83 if ( kv == NULL || str == NULL ) {
84  roar_err_set(ROAR_ERROR_FAULT);
85  return -1;
86 }
87
88 if ( fdel == NULL )
89  fdel = " \t,";
90
91 if ( kdel == NULL )
92  kdel = "=:";
93
94 // count num of segements:
95 for (sp = str; *sp != 0; sp++) {
96  if ( quote ) {
97   if ( *sp == quote )
98    quote = 0;
99  } else if ( quotes && (*sp == '\'' || *sp == '\"') ) {
100   quote = *sp;
101  } else {
102   if ( last_was_seg ) {
103    last_was_seg = !is_in(*sp, fdel);
104   } else {
105    if ( !is_in(*sp, fdel) ) {
106     last_was_seg = 1;
107     len++;
108    }
109   }
110  }
111 }
112
113 kvs = roar_mm_malloc(sizeof(struct roar_keyval)*(len+1));
114
115 if ( kvs == NULL )
116  return -1;
117
118 *kv = kvs;
119
120 // End of Array Mark:
121 kvs[len].key   = NULL;
122 kvs[len].value = NULL;
123
124 // do the acctual filling:
125 last_was_seg = 0;
126
127 for (sp = str; *sp != 0; sp++) {
128  if ( quote ) {
129   if ( *sp == quote ) {
130    skip_char(sp);
131    quote = 0;
132   } else {
133    continue;
134   }
135  } else if ( quotes && (*sp == '\'' || *sp == '\"') ) {
136   quote = *sp;
137   skip_char(sp);
138   continue;
139  }
140
141  if ( last_was_seg ) {
142   if ( is_in(*sp, fdel) ) {
143    last_was_seg = 0;
144    *sp = 0;
145   } else {
146    last_was_seg = 1;
147    if ( kvs[pos].value == NULL && is_in(*sp, kdel) ) {
148     *sp = 0;
149     kvs[pos].value = sp+1;
150    }
151   }
152  } else {
153   if ( !is_in(*sp, fdel) ) {
154    last_was_seg = 1;
155    pos++;
156    kvs[pos].key   = sp;
157    kvs[pos].value = NULL;
158   }
159  }
160 }
161
162 return len;
163}
164
165static inline void _copy_str(char ** dst, const char * src) {
166 for (; *src; src++, (*dst)++) **dst = *src;
167 *((*dst)++) = 0;
168}
169
170void * roar_keyval_copy(struct roar_keyval ** copy, const struct roar_keyval * src, ssize_t len) {
171 size_t buflen = 0;
172 ssize_t i;
173 void * ret;
174 char * p;
175 struct roar_keyval * c;
176
177 // TODO: optimize this.
178 if ( len == -1 ) {
179  len = 0;
180  for (i = 0; src[i].key != NULL || src[i].value != NULL; i++)
181   len++;
182 }
183
184 for (i = 0; i < len; i++) {
185  if ( src[i].key != NULL )
186   buflen += roar_mm_strlen(src[i].key) + 1;
187  if ( src[i].value != NULL )
188   buflen += roar_mm_strlen(src[i].value) + 1;
189 }
190
191 c   = roar_mm_malloc(len * sizeof(struct roar_keyval));
192 if ( c == NULL )
193  return NULL;
194
195 memset(c, 0, len * sizeof(struct roar_keyval));
196
197 ret = roar_mm_malloc(buflen);
198 if ( ret == NULL )
199  return NULL;
200
201 memset(ret, 0, buflen);
202
203 p = ret;
204
205 for (i = 0; i < len; i++) {
206  if ( src[i].key == NULL ) {
207   c[i].key = NULL;
208  } else {
209   c[i].key = p;
210   _copy_str(&p, src[i].key);
211  }
212
213  if ( src[i].value == NULL ) {
214   c[i].value = NULL;
215  } else {
216   c[i].value = p;
217   _copy_str(&p, src[i].value);
218  }
219 }
220
221 *copy = c;
222 return ret;
223}
224
225//ll
Note: See TracBrowser for help on using the repository browser.