1 /* OGMRip - A library for DVD ripping and encoding
2 * Copyright (C) 2004-2012 Olivier Rolland <billl@users.sourceforge.net>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 /**
20 * SECTION:ogmrip-keyfile-settings
21 * @title: KeyFile Settings
22 * @short_description: Settings manager using key files
23 * @include: ogmrip-keyfile-settings.h
24 */
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "ogmrip-keyfile-settings.h"
31
32 #include <string.h>
33
34 #define OGMRIP_KEYFILE_SETTINGS_GET_PRIVATE(o) \
35 (G_TYPE_INSTANCE_GET_PRIVATE ((o), OGMRIP_TYPE_KEYFILE_SETTINGS, OGMRipKeyFileSettingsPriv))
36
37 struct _OGMRipKeyFileSettingsPriv
38 {
39 GKeyFile *keyfile;
40 gchar *filename;
41 };
42
43 static void ogmrip_settings_finalize (GObject *gobject);
44 static void ogmrip_settings_init (OGMRipSettingsIface *iface);
45
G_DEFINE_TYPE_WITH_CODE(OGMRipKeyFileSettings,ogmrip_keyfile_settings,G_TYPE_OBJECT,G_IMPLEMENT_INTERFACE (OGMRIP_TYPE_SETTINGS,ogmrip_settings_init))46 G_DEFINE_TYPE_WITH_CODE (OGMRipKeyFileSettings, ogmrip_keyfile_settings, G_TYPE_OBJECT,
47 G_IMPLEMENT_INTERFACE (OGMRIP_TYPE_SETTINGS, ogmrip_settings_init))
48
49 static void
50 ogmrip_keyfile_settings_class_init (OGMRipKeyFileSettingsClass *klass)
51 {
52 GObjectClass *gobject_class;
53
54 gobject_class = G_OBJECT_CLASS (klass);
55 gobject_class->finalize = ogmrip_settings_finalize;
56
57 g_type_class_add_private (klass, sizeof (OGMRipKeyFileSettingsPriv));
58 }
59
60 static void
ogmrip_settings_finalize(GObject * gobject)61 ogmrip_settings_finalize (GObject *gobject)
62 {
63 OGMRipKeyFileSettings *keyfile;
64
65 keyfile = OGMRIP_KEYFILE_SETTINGS (gobject);
66
67 if (keyfile->priv->keyfile)
68 {
69 g_key_file_free (keyfile->priv->keyfile);
70 keyfile->priv->keyfile = NULL;
71 }
72
73 if (keyfile->priv->filename)
74 {
75 g_free (keyfile->priv->filename);
76 keyfile->priv->filename = NULL;
77 }
78
79 (*G_OBJECT_CLASS (ogmrip_keyfile_settings_parent_class)->finalize) (gobject);
80 }
81
82 static void
ogmrip_keyfile_settings_set_value(OGMRipSettings * settings,const gchar * section,const gchar * key,const GValue * value)83 ogmrip_keyfile_settings_set_value (OGMRipSettings *settings, const gchar *section, const gchar *key, const GValue *value)
84 {
85 OGMRipKeyFileSettings *keyfile;
86
87 keyfile = OGMRIP_KEYFILE_SETTINGS (settings);
88
89 switch (G_VALUE_TYPE (value))
90 {
91 case G_TYPE_INT:
92 g_key_file_set_integer (keyfile->priv->keyfile, section, key, g_value_get_int (value));
93 break;
94 case G_TYPE_BOOLEAN:
95 g_key_file_set_boolean (keyfile->priv->keyfile, section, key, g_value_get_boolean (value));
96 break;
97 case G_TYPE_DOUBLE:
98 g_key_file_set_double (keyfile->priv->keyfile, section, key, g_value_get_double (value));
99 break;
100 case G_TYPE_STRING:
101 g_key_file_set_string (keyfile->priv->keyfile, section, key, g_value_get_string (value));
102 break;
103 default:
104 break;
105 }
106 }
107
108 static void
ogmrip_keyfile_settings_get_value(OGMRipSettings * settings,const gchar * section,const gchar * key,GValue * value)109 ogmrip_keyfile_settings_get_value (OGMRipSettings *settings, const gchar *section, const gchar *key, GValue *value)
110 {
111 GType type;
112
113 type = ogmrip_settings_get_key_type (settings, section, key);
114 if (type != G_TYPE_NONE)
115 {
116 OGMRipKeyFileSettings *keyfile;
117
118 keyfile = OGMRIP_KEYFILE_SETTINGS (settings);
119
120 g_value_init (value, type);
121
122 switch (type)
123 {
124 case G_TYPE_INT:
125 g_value_set_int (value, g_key_file_get_integer (keyfile->priv->keyfile, section, key, NULL));
126 break;
127 case G_TYPE_BOOLEAN:
128 g_value_set_boolean (value, g_key_file_get_boolean (keyfile->priv->keyfile, section, key, NULL));
129 break;
130 case G_TYPE_DOUBLE:
131 g_value_set_double (value, g_key_file_get_double (keyfile->priv->keyfile, section, key, NULL));
132 break;
133 case G_TYPE_STRING:
134 {
135 gchar *str;
136
137 str = g_key_file_get_string (keyfile->priv->keyfile, section, key, NULL);
138 g_value_take_string (value, str);
139 }
140 break;
141 default:
142 break;
143 }
144 }
145 }
146
147 static GSList *
ogmrip_keyfile_settings_get_subsections(OGMRipSettings * settings,const gchar * section)148 ogmrip_keyfile_settings_get_subsections (OGMRipSettings *settings, const gchar *section)
149 {
150 OGMRipKeyFileSettings *keyfile;
151 GSList *list = NULL;
152
153 gchar **groups;
154 gint i;
155
156 keyfile = OGMRIP_KEYFILE_SETTINGS (settings);
157
158 groups = g_key_file_get_groups (keyfile->priv->keyfile, NULL);
159 for (i = 0; groups[i]; i ++)
160 if (g_str_has_prefix (groups[i], section))
161 list = g_slist_append (list, groups[i]);
162
163 return list;
164 }
165
166 static GSList *
ogmrip_keyfile_settings_get_keys(OGMRipSettings * settings,const gchar * section,gboolean recursive)167 ogmrip_keyfile_settings_get_keys (OGMRipSettings *settings, const gchar *section, gboolean recursive)
168 {
169 GSList *list = NULL;
170
171 OGMRipKeyFileSettings *keyfile;
172 gchar **keys;
173 guint i;
174
175 keyfile = OGMRIP_KEYFILE_SETTINGS (settings);
176
177 keys = g_key_file_get_keys (keyfile->priv->keyfile, section, NULL, NULL);
178 for (i = 0; keys[i]; i ++)
179 list = g_slist_append (list, keys[i]);
180 g_free (keys);
181
182 return list;
183 }
184
185 static void
ogmrip_keyfile_settings_remove_key(OGMRipSettings * settings,const gchar * section,const gchar * key)186 ogmrip_keyfile_settings_remove_key (OGMRipSettings *settings, const gchar *section, const gchar *key)
187 {
188 OGMRipKeyFileSettings *keyfile;
189
190 keyfile = OGMRIP_KEYFILE_SETTINGS (settings);
191
192 g_key_file_remove_key (keyfile->priv->keyfile, section, key, NULL);
193 }
194
195 static void
ogmrip_keyfile_settings_remove_section(OGMRipSettings * settings,const gchar * section)196 ogmrip_keyfile_settings_remove_section (OGMRipSettings *settings, const gchar *section)
197 {
198 OGMRipKeyFileSettings *keyfile;
199
200 keyfile = OGMRIP_KEYFILE_SETTINGS (settings);
201
202 g_key_file_remove_group (keyfile->priv->keyfile, section, NULL);
203 }
204
205 static gboolean
ogmrip_keyfile_settings_has_key(OGMRipSettings * settings,const gchar * section,const gchar * key)206 ogmrip_keyfile_settings_has_key (OGMRipSettings *settings, const gchar *section, const gchar *key)
207 {
208 OGMRipKeyFileSettings *keyfile;
209
210 keyfile = OGMRIP_KEYFILE_SETTINGS (settings);
211
212 return g_key_file_has_key (keyfile->priv->keyfile, section, key, NULL);
213 }
214
215 static gboolean
ogmrip_keyfile_settings_has_section(OGMRipSettings * settings,const gchar * section)216 ogmrip_keyfile_settings_has_section (OGMRipSettings *settings, const gchar *section)
217 {
218 OGMRipKeyFileSettings *keyfile;
219
220 keyfile = OGMRIP_KEYFILE_SETTINGS (settings);
221
222 return g_key_file_has_group (keyfile->priv->keyfile, section);
223 }
224
225 static gchar *
ogmrip_keyfile_settings_build_section(OGMRipSettings * settings,const gchar * element,va_list var_args)226 ogmrip_keyfile_settings_build_section (OGMRipSettings *settings, const gchar *element, va_list var_args)
227 {
228 gchar *str, *section = NULL;
229
230 while (element)
231 {
232 if (section)
233 str = g_strconcat (section, "-", element, NULL);
234 else
235 str = g_strdup (element);
236
237 g_free (section);
238 section = str;
239
240 element = va_arg (var_args, gchar *);
241 }
242
243 return section;
244 }
245
246 static const gchar *
ogmrip_keyfile_settings_get_section_name(OGMRipSettings * settings,const gchar * section)247 ogmrip_keyfile_settings_get_section_name (OGMRipSettings *settings, const gchar *section)
248 {
249 gchar *name;
250
251 name = strrchr (section, '-');
252 if (!name)
253 return section;
254
255 return name + 1;
256 }
257
258 static void
ogmrip_settings_init(OGMRipSettingsIface * iface)259 ogmrip_settings_init (OGMRipSettingsIface *iface)
260 {
261 iface->set_value = ogmrip_keyfile_settings_set_value;
262 iface->get_value = ogmrip_keyfile_settings_get_value;
263
264 iface->get_subsections = ogmrip_keyfile_settings_get_subsections;
265 iface->get_keys = ogmrip_keyfile_settings_get_keys;
266
267 iface->has_key = ogmrip_keyfile_settings_has_key;
268 iface->has_section = ogmrip_keyfile_settings_has_section;
269 iface->remove_key = ogmrip_keyfile_settings_remove_key;
270 iface->remove_section = ogmrip_keyfile_settings_remove_section;
271
272 iface->build_section = ogmrip_keyfile_settings_build_section;
273 iface->get_section_name = ogmrip_keyfile_settings_get_section_name;
274 }
275
276 static void
ogmrip_keyfile_settings_init(OGMRipKeyFileSettings * settings)277 ogmrip_keyfile_settings_init (OGMRipKeyFileSettings *settings)
278 {
279 settings->priv = OGMRIP_KEYFILE_SETTINGS_GET_PRIVATE (settings);
280 }
281
282 /**
283 * ogmrip_keyfile_settings_new:
284 *
285 * Creates a new #OGMRipSettings
286 *
287 * Returns: the new #OGMRipSettings
288 */
289 OGMRipSettings *
ogmrip_keyfile_settings_new(void)290 ogmrip_keyfile_settings_new (void)
291 {
292 OGMRipKeyFileSettings *settings;
293
294 settings = g_object_new (OGMRIP_TYPE_KEYFILE_SETTINGS, NULL);
295
296 settings->priv->keyfile = g_key_file_new ();
297
298 return OGMRIP_SETTINGS (settings);
299 }
300
301 /**
302 * ogmrip_keyfile_settings_load:
303 * @settings: an #OGMRipKeyFileSettings
304 * @filename: the filename to load
305 * @error: return location for error
306 *
307 * Loads a key file.
308 *
309 * Returns: %TRUE on success, %FALSE if an error was set
310 */
311 gboolean
ogmrip_keyfile_settings_load(OGMRipKeyFileSettings * settings,const gchar * filename,GError ** error)312 ogmrip_keyfile_settings_load (OGMRipKeyFileSettings *settings, const gchar *filename, GError **error)
313 {
314 GError *tmp_error = NULL;
315
316 g_return_val_if_fail (OGMRIP_IS_KEYFILE_SETTINGS (settings), FALSE);
317 g_return_val_if_fail (filename != NULL, FALSE);
318 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
319
320 if (!g_key_file_load_from_file (settings->priv->keyfile, filename, G_KEY_FILE_NONE, &tmp_error))
321 {
322 g_propagate_error (error, tmp_error);
323 return FALSE;
324 }
325
326 return TRUE;
327 }
328
329 /**
330 * ogmrip_keyfile_settings_save:
331 * @settings: an #OGMRipKeyFileSettings
332 * @filename: the filename where to save the keys and values
333 * @error: return location for error
334 *
335 * Saves a key file.
336 *
337 * Returns: %TRUE on success, %FALSE if an error was set
338 */
339 gboolean
ogmrip_keyfile_settings_save(OGMRipKeyFileSettings * settings,const gchar * filename,GError ** error)340 ogmrip_keyfile_settings_save (OGMRipKeyFileSettings *settings, const gchar *filename, GError **error)
341 {
342 return FALSE;
343 }
344
345