2
* GConf BerkeleyDB back-end
4
* Copyright (C) 2000 Sun Microsystems Inc Contributed to the GConf project.
6
* This library is free software; you can redistribute it and/or modify it under
7
* the terms of the GNU Library General Public License as published by the
8
* Free Software Foundation; either version 2 of the License, or (at your
9
* option) any later version.
11
* This library is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14
* License for more details.
16
* You should have received a copy of the GNU Library General Public License
17
* along with this library; if not, write to the Free Software Foundation,
18
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
#include <gconf/gconf.h>
27
/* required for gconf_value_new_from_string() */
28
#include <gconf/gconf-internals.h>
30
/* required for _gconf_slist_free_all */
31
#include "dir-utils.h"
33
/* GConf Value type character identifiers */
34
static const char bdb_string = 's';
35
static const char bdb_int = 'i';
36
static const char bdb_float = 'f';
37
static const char bdb_bool = 'b';
38
static const char bdb_schema = 'x';
39
static const char bdb_list = 'l';
40
static const char bdb_pair = 'p';
42
/* Map each character value type id to the corresponding GConfValueType
44
static struct s_TypeMap
47
GConfValueType valuetype;
52
's', GCONF_VALUE_STRING}
58
'f', GCONF_VALUE_FLOAT}
61
'b', GCONF_VALUE_BOOL}
64
'x', GCONF_VALUE_SCHEMA}
67
'l', GCONF_VALUE_LIST}
70
'p', GCONF_VALUE_PAIR}
73
'\0', GCONF_VALUE_INVALID}
76
/* { Conversion functions using bdb_value_types to map between GConfValueType
77
* and the corresponding character-based value type identifiers
80
get_value_type (char type)
84
while (bdb_value_types[i].type && (bdb_value_types[i].type != type))
86
return bdb_value_types[i].valuetype;
90
get_type_for_value_type (GConfValueType valuetype)
94
while (bdb_value_types[i].type
95
&& (bdb_value_types[i].valuetype != valuetype))
97
return bdb_value_types[i].type;
103
append_string (char *buf, const char *string)
107
strcpy (buf, string);
108
return buf + strlen (string) + 1;
114
static char tbuf[259]; /* 256 + 3 bytes for "<type>:" and end zero byte */
117
_gconf_check_free (char *buf)
119
if (buf && buf != tbuf)
123
/* { Functions to size, serialize and de-serialize a GConfValue, which
124
* is stored in the database as an encoded string.
127
/* bdb_size_value returns the encoded size of a value, which is 2 bytes
128
* for leading type info, plus enough room for the value as a string
129
* (excluding terminal NULL byte)
132
bdb_size_value (const GConfValue * val)
137
return 3; /* empty values are encoded as a type and a
141
case GCONF_VALUE_STRING:
143
char *t = gconf_value_get_string (val) == 0 ? "" : val->d.string_data;
144
len = strlen (t) + 2;
147
case GCONF_VALUE_INT:
148
sprintf (buf, "%d", val->d.int_data);
149
len = strlen (buf) + 2;
151
case GCONF_VALUE_FLOAT:
152
sprintf (buf, "%f", (double) gconf_value_get_float (val));
153
len = strlen (buf) + 2;
155
case GCONF_VALUE_BOOL:
158
case GCONF_VALUE_SCHEMA:
160
GConfSchema *schema = gconf_value_get_schema (val);
167
len += strlen (schema->locale); /* Schema locale */
170
len += strlen (schema->owner); /* Name of creating application */
172
if (schema->short_desc)
173
len += strlen (schema->short_desc); /* 40 char or less
174
* description, no newlines */
176
if (schema->long_desc)
177
len += strlen (schema->long_desc); /* could be a paragraph or so */
179
len += bdb_size_value (schema->default_value); /* includes type
181
if (!schema->default_value)
183
if (schema->type == GCONF_VALUE_LIST)
184
len++; /* even an empty list will include the type
189
case GCONF_VALUE_LIST:
193
list = gconf_value_get_list (val);
196
len += bdb_size_value ((GConfValue *) list->data) + 1;
197
list = g_slist_next (list);
201
case GCONF_VALUE_PAIR:
202
len = 2 + bdb_size_value (gconf_value_get_car (val)) +
203
bdb_size_value (gconf_value_get_cdr (val));
204
case GCONF_VALUE_INVALID:
212
/* All values are stored in the database as strings; bdb_serialize_value()
213
* encodes a GConfValue as a string, bdb_restore_value() decodes a
214
* serialized string back to a value
217
bdb_serialize_value (GConfValue * val, size_t * lenp)
225
case GCONF_VALUE_STRING:
226
t = gconf_value_get_string (val) == 0 ? "" : val->d.string_data;
227
len = strlen (t) + 3;
230
buf = (char *) malloc (len);
236
case GCONF_VALUE_INT:
237
sprintf (buf, "%c:%d", bdb_int, gconf_value_get_int (val));
238
len = strlen (buf) + 1;
240
case GCONF_VALUE_FLOAT:
241
sprintf (buf, "%c:%f", bdb_float, (double) gconf_value_get_float (val));
242
len = strlen (buf) + 1;
244
case GCONF_VALUE_BOOL:
245
sprintf (buf, "%c:%d", bdb_bool, gconf_value_get_bool (val) ? 1 : 0);
246
len = strlen (buf) + 1;
248
case GCONF_VALUE_SCHEMA:
250
GConfSchema *schema = gconf_value_get_schema (val);
253
len = bdb_size_value (val);
254
buf = (char *) malloc (len);
263
end = append_string (end, schema->locale);
264
end = append_string (end, schema->owner);
265
end = append_string (end, schema->short_desc);
266
end = append_string (end, schema->long_desc);
267
if (!schema->default_value)
269
*end++ = get_type_for_value_type (schema->type);
275
t = bdb_serialize_value (schema->default_value, &sublen);
276
memcpy (end, t, sublen);
281
case GCONF_VALUE_LIST:
286
len = bdb_size_value (val);
287
buf = (char *) malloc (len);
288
list = val->d.list_data.list;
291
buf[2] = get_type_for_value_type (gconf_value_get_list_type (val));
295
t = bdb_serialize_value ((GConfValue *) list->data, &sublen);
296
memcpy (end, t, sublen);
298
_gconf_check_free (t);
299
list = g_slist_next (list);
304
case GCONF_VALUE_PAIR:
307
len = bdb_size_value (val);
308
buf = (char *) malloc (len);
312
t = bdb_serialize_value (gconf_value_get_car (val), &sublen);
315
memcpy (buf + len, t, sublen);
317
_gconf_check_free (t);
323
t = bdb_serialize_value (gconf_value_get_cdr (val), &sublen);
326
memcpy (buf + len, t, sublen);
328
_gconf_check_free (t);
336
case GCONF_VALUE_INVALID:
347
bdb_restore_value (const char *srz)
353
if ((strlen (srz) < 2) || (srz[1] != ':'))
362
return gconf_value_new_from_string (GCONF_VALUE_STRING, srz, &err);
365
return gconf_value_new_from_string (GCONF_VALUE_INT, srz, &err);
368
return gconf_value_new_from_string (GCONF_VALUE_FLOAT, srz, &err);
371
return gconf_value_new_from_string (GCONF_VALUE_BOOL, srz, &err);
375
GConfValue *schema_val = gconf_value_new (GCONF_VALUE_SCHEMA);
377
GConfSchema *schema = gconf_schema_new ();
378
len = 4; /* "x:" + (char)type + '\0' */
380
gconf_schema_set_locale (schema, srz);
381
srz += strlen (srz) + 1;
383
gconf_schema_set_owner (schema, srz);
384
srz += strlen (srz) + 1;
386
gconf_schema_set_short_desc (schema, srz);
387
srz += strlen (srz) + 1;
389
gconf_schema_set_long_desc (schema, srz);
390
srz += strlen (srz) + 1;
391
val = bdb_restore_value (srz);
392
gconf_schema_set_type (schema, get_value_type (*srz));
393
gconf_schema_set_default_value_nocopy (schema, val);
394
gconf_value_set_schema (schema_val, schema);
402
valuep = gconf_value_new (GCONF_VALUE_LIST);
403
gconf_value_set_list_type (valuep, get_value_type (*srz++));
406
list = g_slist_append (list, bdb_restore_value (srz));
411
gconf_value_set_list (valuep, list);
412
_gconf_slist_free_all (list);
418
GConfValue *valuep = NULL;
421
valuep = gconf_value_new (GCONF_VALUE_PAIR);
422
gconf_value_set_car (valuep, bdb_restore_value (srz));
428
gconf_value_set_cdr (valuep, bdb_restore_value (srz));
432
gconf_value_free (valuep);