Add optimized indexing capabilities for phone number values.
[platform/upstream/evolution-data-server.git] / camel / camel-local-settings.c
1 /*
2  * camel-local-settings.c
3  *
4  * This program 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 of the License, or (at your option) version 3.
8  *
9  * This program 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 the program; if not, see <http://www.gnu.org/licenses/>
16  *
17  */
18
19 #include "camel-local-settings.h"
20
21 #include <string.h>
22
23 #define CAMEL_LOCAL_SETTINGS_GET_PRIVATE(obj) \
24         (G_TYPE_INSTANCE_GET_PRIVATE \
25         ((obj), CAMEL_TYPE_LOCAL_SETTINGS, CamelLocalSettingsPrivate))
26
27 struct _CamelLocalSettingsPrivate {
28         GMutex property_lock;
29         gchar *path;
30 };
31
32 enum {
33         PROP_0,
34         PROP_PATH
35 };
36
37 G_DEFINE_TYPE (
38         CamelLocalSettings,
39         camel_local_settings,
40         CAMEL_TYPE_STORE_SETTINGS)
41
42 static void
43 local_settings_set_property (GObject *object,
44                              guint property_id,
45                              const GValue *value,
46                              GParamSpec *pspec)
47 {
48         switch (property_id) {
49                 case PROP_PATH:
50                         camel_local_settings_set_path (
51                                 CAMEL_LOCAL_SETTINGS (object),
52                                 g_value_get_string (value));
53                         return;
54         }
55
56         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
57 }
58
59 static void
60 local_settings_get_property (GObject *object,
61                              guint property_id,
62                              GValue *value,
63                              GParamSpec *pspec)
64 {
65         switch (property_id) {
66                 case PROP_PATH:
67                         g_value_take_string (
68                                 value,
69                                 camel_local_settings_dup_path (
70                                 CAMEL_LOCAL_SETTINGS (object)));
71                         return;
72         }
73
74         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
75 }
76
77 static void
78 local_settings_finalize (GObject *object)
79 {
80         CamelLocalSettingsPrivate *priv;
81
82         priv = CAMEL_LOCAL_SETTINGS_GET_PRIVATE (object);
83
84         g_mutex_clear (&priv->property_lock);
85
86         g_free (priv->path);
87
88         /* Chain up to parent's finalize() method. */
89         G_OBJECT_CLASS (camel_local_settings_parent_class)->finalize (object);
90 }
91
92 static void
93 camel_local_settings_class_init (CamelLocalSettingsClass *class)
94 {
95         GObjectClass *object_class;
96
97         g_type_class_add_private (class, sizeof (CamelLocalSettingsPrivate));
98
99         object_class = G_OBJECT_CLASS (class);
100         object_class->set_property = local_settings_set_property;
101         object_class->get_property = local_settings_get_property;
102         object_class->finalize = local_settings_finalize;
103
104         g_object_class_install_property (
105                 object_class,
106                 PROP_PATH,
107                 g_param_spec_string (
108                         "path",
109                         "Path",
110                         "File path to the local store",
111                         NULL,
112                         G_PARAM_READWRITE |
113                         G_PARAM_CONSTRUCT |
114                         G_PARAM_STATIC_STRINGS));
115 }
116
117 static void
118 camel_local_settings_init (CamelLocalSettings *settings)
119 {
120         settings->priv = CAMEL_LOCAL_SETTINGS_GET_PRIVATE (settings);
121         g_mutex_init (&settings->priv->property_lock);
122 }
123
124 /**
125  * camel_local_settings_get_path:
126  * @settings: a #CamelLocalSettings
127  *
128  * Returns the file path to the root of the local mail store.
129  *
130  * Returns: the file path to the local store
131  *
132  * Since: 3.4
133  **/
134 const gchar *
135 camel_local_settings_get_path (CamelLocalSettings *settings)
136 {
137         g_return_val_if_fail (CAMEL_IS_LOCAL_SETTINGS (settings), NULL);
138
139         return settings->priv->path;
140 }
141
142 /**
143  * camel_local_settings_dup_path:
144  * @settings: a #CamelLocalSettings
145  *
146  * Thread-safe variation of camel_local_settings_get_path().
147  * Use this function when accessing @settings from multiple threads.
148  *
149  * The returned string should be freed with g_free() when no longer needed.
150  *
151  * Returns: a newly-allocated copy of #CamelLocalSettings:path
152  *
153  * Since: 3.4
154  **/
155 gchar *
156 camel_local_settings_dup_path (CamelLocalSettings *settings)
157 {
158         const gchar *protected;
159         gchar *duplicate;
160
161         g_return_val_if_fail (CAMEL_IS_LOCAL_SETTINGS (settings), NULL);
162
163         g_mutex_lock (&settings->priv->property_lock);
164
165         protected = camel_local_settings_get_path (settings);
166         duplicate = g_strdup (protected);
167
168         g_mutex_unlock (&settings->priv->property_lock);
169
170         return duplicate;
171 }
172
173 /**
174  * camel_local_settings_set_path:
175  * @settings: a #CamelLocalSettings
176  * @path: the file path to the local store
177  *
178  * Sets the file path to the root of the local mail store.  Any
179  * trailing directory separator characters will be stripped off
180  * of the #CamelLocalSettings:path property.
181  *
182  * Since: 3.4
183  **/
184 void
185 camel_local_settings_set_path (CamelLocalSettings *settings,
186                                const gchar *path)
187 {
188         gsize length = 0;
189         gchar *new_path;
190
191         g_return_if_fail (CAMEL_IS_LOCAL_SETTINGS (settings));
192
193         /* Exclude trailing directory separators. */
194         if (path != NULL) {
195                 length = strlen (path);
196                 while (length > 0) {
197                         if (G_IS_DIR_SEPARATOR (path[length - 1]))
198                                 length--;
199                         else
200                                 break;
201                 }
202         }
203
204         g_mutex_lock (&settings->priv->property_lock);
205
206         new_path = g_strndup (path, length);
207
208         if (g_strcmp0 (settings->priv->path, new_path) == 0) {
209                 g_mutex_unlock (&settings->priv->property_lock);
210                 g_free (new_path);
211                 return;
212         }
213
214         g_free (settings->priv->path);
215         settings->priv->path = new_path;
216
217         g_mutex_unlock (&settings->priv->property_lock);
218
219         g_object_notify (G_OBJECT (settings), "path");
220 }
221