I#27 - [IMAPx] Ignore DavMail's CR/LF in BODYSTRUCTURE response
[evolution-data-server.git] / src / libedataserver / e-source-extension.c
blob3545e6fe8eeb25f353e30e6a312d51bface93601
1 /*
2 * e-source-extension.c
4 * This library is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11 * for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library. If not, see <http://www.gnu.org/licenses/>.
18 /**
19 * SECTION: e-source-extension
20 * @include: libedataserver/libedataserver.h
21 * @short_description: Base class for #ESource extensions
23 * #ESourceExtension is an abstract base class for #ESource extension
24 * objects. An #ESourceExtension object basically just maps the keys in
25 * a key file group to a set of #GObject properties. The name of the key
26 * file group doubles as the name of the #ESourceExtension object.
28 * #ESourceExtension objects are accessed through e_source_get_extension().
29 **/
31 #include "e-source-extension.h"
33 #define E_SOURCE_EXTENSION_GET_PRIVATE(obj) \
34 (G_TYPE_INSTANCE_GET_PRIVATE \
35 ((obj), E_TYPE_SOURCE_EXTENSION, ESourceExtensionPrivate))
37 struct _ESourceExtensionPrivate {
38 GWeakRef source;
39 GRecMutex property_lock;
42 enum {
43 PROP_0,
44 PROP_SOURCE
47 G_DEFINE_ABSTRACT_TYPE (
48 ESourceExtension,
49 e_source_extension,
50 G_TYPE_OBJECT)
52 static void
53 source_extension_set_source (ESourceExtension *extension,
54 ESource *source)
56 g_return_if_fail (E_IS_SOURCE (source));
58 g_weak_ref_set (&extension->priv->source, source);
61 static void
62 source_extension_set_property (GObject *object,
63 guint property_id,
64 const GValue *value,
65 GParamSpec *pspec)
67 switch (property_id) {
68 case PROP_SOURCE:
69 source_extension_set_source (
70 E_SOURCE_EXTENSION (object),
71 g_value_get_object (value));
72 return;
75 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
78 static void
79 source_extension_get_property (GObject *object,
80 guint property_id,
81 GValue *value,
82 GParamSpec *pspec)
84 switch (property_id) {
85 case PROP_SOURCE:
86 g_value_take_object (
87 value, e_source_extension_ref_source (
88 E_SOURCE_EXTENSION (object)));
89 return;
92 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
95 static void
96 source_extension_dispose (GObject *object)
98 ESourceExtensionPrivate *priv;
100 priv = E_SOURCE_EXTENSION_GET_PRIVATE (object);
102 g_weak_ref_set (&priv->source, NULL);
104 /* Chain up to parent's dispose() method. */
105 G_OBJECT_CLASS (e_source_extension_parent_class)->dispose (object);
108 static void
109 source_extension_finalize (GObject *object)
111 ESourceExtensionPrivate *priv;
113 priv = E_SOURCE_EXTENSION_GET_PRIVATE (object);
115 g_weak_ref_clear (&priv->source);
116 g_rec_mutex_clear (&priv->property_lock);
118 /* Chain up to parent's finalize() method. */
119 G_OBJECT_CLASS (e_source_extension_parent_class)->finalize (object);
122 static void
123 source_extension_notify (GObject *object,
124 GParamSpec *pspec)
126 ESource *source;
127 ESourceExtension *extension;
129 extension = E_SOURCE_EXTENSION (object);
130 source = e_source_extension_ref_source (extension);
131 g_return_if_fail (source != NULL);
133 if ((pspec->flags & E_SOURCE_PARAM_SETTING) != 0)
134 e_source_changed (source);
136 g_object_unref (source);
139 static void
140 e_source_extension_class_init (ESourceExtensionClass *class)
142 GObjectClass *object_class;
144 g_type_class_add_private (class, sizeof (ESourceExtensionPrivate));
146 object_class = G_OBJECT_CLASS (class);
147 object_class->set_property = source_extension_set_property;
148 object_class->get_property = source_extension_get_property;
149 object_class->dispose = source_extension_dispose;
150 object_class->finalize = source_extension_finalize;
151 object_class->notify = source_extension_notify;
153 g_object_class_install_property (
154 object_class,
155 PROP_SOURCE,
156 g_param_spec_object (
157 "source",
158 "Source",
159 "The ESource being extended",
160 E_TYPE_SOURCE,
161 G_PARAM_READWRITE |
162 G_PARAM_CONSTRUCT_ONLY |
163 G_PARAM_STATIC_STRINGS));
166 static void
167 e_source_extension_init (ESourceExtension *extension)
169 extension->priv = E_SOURCE_EXTENSION_GET_PRIVATE (extension);
170 g_weak_ref_init (&extension->priv->source, NULL);
171 g_rec_mutex_init (&extension->priv->property_lock);
175 * e_source_extension_ref_source:
176 * @extension: an #ESourceExtension
178 * Returns the #ESource instance to which the @extension belongs.
180 * The returned #ESource is referenced for thread-safety. Unreference
181 * the #ESource with g_object_unref() when finished with it.
183 * Returns: (transfer full): the #ESource instance
185 * Since: 3.8
187 ESource *
188 e_source_extension_ref_source (ESourceExtension *extension)
190 g_return_val_if_fail (E_IS_SOURCE_EXTENSION (extension), NULL);
192 return g_weak_ref_get (&extension->priv->source);
196 * e_source_extension_get_source:
197 * @extension: an #ESourceExtension
199 * Returns the #ESource instance to which @extension belongs.
201 * Note this function is not thread-safe. The returned #ESource could
202 * be finalized by another thread while the caller is still using it.
204 * Returns: (transfer none): the #ESource instance
206 * Since: 3.6
208 * Deprecated: 3.8: Use e_source_extension_ref_source() instead.
210 ESource *
211 e_source_extension_get_source (ESourceExtension *extension)
213 ESource *source;
215 g_return_val_if_fail (E_IS_SOURCE_EXTENSION (extension), NULL);
217 source = e_source_extension_ref_source (extension);
219 /* XXX Drop the ESource reference for backward-compatibility.
220 * This is risky. Without a reference, the ESource could
221 * be finalized while the caller is still using it. */
222 if (source != NULL)
223 g_object_unref (source);
225 return source;
229 * e_source_extension_property_lock:
230 * @extension: an #ESourceExtension
232 * Acquires a property lock, thus no other thread can change properties
233 * of the @extension until the lock is released.
235 * Since: 3.18
237 void
238 e_source_extension_property_lock (ESourceExtension *extension)
240 g_return_if_fail (E_IS_SOURCE_EXTENSION (extension));
242 g_rec_mutex_lock (&extension->priv->property_lock);
246 * e_source_extension_property_unlock:
247 * @extension: an #ESourceExtension
249 * Releases a property lock, previously acquired with e_source_extension_property_lock(),
250 * thus other threads can change properties of the @extension.
252 * Since: 3.18
254 void
255 e_source_extension_property_unlock (ESourceExtension *extension)
257 g_return_if_fail (E_IS_SOURCE_EXTENSION (extension));
259 g_rec_mutex_unlock (&extension->priv->property_lock);