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