1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /* camelMedium.c : Abstract class for a medium
3 *
4 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
5 *
6 * This library is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation.
9 *
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Bertrand Guiheneuf <bertrand@helixcode.com>
19 * Michael Zucchi <notzed@ximian.com>
20 */
21
22 #include "evolution-data-server-config.h"
23
24 #include <ctype.h>
25 #include <stdio.h>
26
27 #include "camel-medium.h"
28
29 #define d(x)
30
31 struct _CamelMediumPrivate {
32 /* The content of the medium, as opposed to our parent
33 * CamelDataWrapper, which wraps both the headers and
34 * the content. */
35 CamelDataWrapper *content;
36 };
37
38 enum {
39 PROP_0,
40 PROP_CONTENT
41 };
42
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(CamelMedium,camel_medium,CAMEL_TYPE_DATA_WRAPPER)43 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (CamelMedium, camel_medium, CAMEL_TYPE_DATA_WRAPPER)
44
45 static void
46 medium_set_property (GObject *object,
47 guint property_id,
48 const GValue *value,
49 GParamSpec *pspec)
50 {
51 switch (property_id) {
52 case PROP_CONTENT:
53 camel_medium_set_content (
54 CAMEL_MEDIUM (object),
55 g_value_get_object (value));
56 return;
57 }
58
59 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
60 }
61
62 static void
medium_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)63 medium_get_property (GObject *object,
64 guint property_id,
65 GValue *value,
66 GParamSpec *pspec)
67 {
68 switch (property_id) {
69 case PROP_CONTENT:
70 g_value_set_object (
71 value, camel_medium_get_content (
72 CAMEL_MEDIUM (object)));
73 return;
74 }
75
76 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
77 }
78
79 static void
medium_dispose(GObject * object)80 medium_dispose (GObject *object)
81 {
82 CamelMediumPrivate *priv;
83
84 priv = CAMEL_MEDIUM (object)->priv;
85 g_clear_object (&priv->content);
86
87 /* Chain up to parent's dispose() method. */
88 G_OBJECT_CLASS (camel_medium_parent_class)->dispose (object);
89 }
90
91 static gboolean
medium_is_offline(CamelDataWrapper * data_wrapper)92 medium_is_offline (CamelDataWrapper *data_wrapper)
93 {
94 CamelDataWrapper *content;
95
96 content = camel_medium_get_content (CAMEL_MEDIUM (data_wrapper));
97
98 return CAMEL_DATA_WRAPPER_CLASS (camel_medium_parent_class)->is_offline (data_wrapper) ||
99 camel_data_wrapper_is_offline (content);
100 }
101
102 static void
medium_set_content(CamelMedium * medium,CamelDataWrapper * content)103 medium_set_content (CamelMedium *medium,
104 CamelDataWrapper *content)
105 {
106 if (medium->priv->content == content)
107 return;
108
109 if (content != NULL)
110 g_object_ref (content);
111
112 if (medium->priv->content != NULL)
113 g_object_unref (medium->priv->content);
114
115 medium->priv->content = content;
116
117 g_object_notify (G_OBJECT (medium), "content");
118 }
119
120 static CamelDataWrapper *
medium_get_content(CamelMedium * medium)121 medium_get_content (CamelMedium *medium)
122 {
123 return medium->priv->content;
124 }
125
126 static void
camel_medium_class_init(CamelMediumClass * class)127 camel_medium_class_init (CamelMediumClass *class)
128 {
129 GObjectClass *object_class;
130 CamelDataWrapperClass *data_wrapper_class;
131
132 object_class = G_OBJECT_CLASS (class);
133 object_class->set_property = medium_set_property;
134 object_class->get_property = medium_get_property;
135 object_class->dispose = medium_dispose;
136
137 data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (class);
138 data_wrapper_class->is_offline = medium_is_offline;
139
140 class->set_content = medium_set_content;
141 class->get_content = medium_get_content;
142
143 g_object_class_install_property (
144 object_class,
145 PROP_CONTENT,
146 g_param_spec_object (
147 "content",
148 "Content",
149 NULL,
150 CAMEL_TYPE_DATA_WRAPPER,
151 G_PARAM_READWRITE |
152 G_PARAM_EXPLICIT_NOTIFY));
153 }
154
155 static void
camel_medium_init(CamelMedium * medium)156 camel_medium_init (CamelMedium *medium)
157 {
158 medium->priv = camel_medium_get_instance_private (medium);
159 }
160
161 /**
162 * camel_medium_add_header:
163 * @medium: a #CamelMedium object
164 * @name: name of the header
165 * @value: value of the header
166 *
167 * Adds a header to a #CamelMedium.
168 **/
169 void
camel_medium_add_header(CamelMedium * medium,const gchar * name,const gchar * value)170 camel_medium_add_header (CamelMedium *medium,
171 const gchar *name,
172 const gchar *value)
173 {
174 CamelMediumClass *class;
175
176 g_return_if_fail (CAMEL_IS_MEDIUM (medium));
177 g_return_if_fail (name != NULL);
178 g_return_if_fail (value != NULL);
179
180 class = CAMEL_MEDIUM_GET_CLASS (medium);
181 g_return_if_fail (class != NULL);
182 g_return_if_fail (class->add_header != NULL);
183
184 class->add_header (medium, name, value);
185 }
186
187 /**
188 * camel_medium_set_header:
189 * @medium: a #CamelMedium object
190 * @name: name of the header
191 * @value: value of the header
192 *
193 * Sets the value of a header. Any other occurances of the header
194 * will be removed. Setting a %NULL header can be used to remove
195 * the header also.
196 **/
197 void
camel_medium_set_header(CamelMedium * medium,const gchar * name,const gchar * value)198 camel_medium_set_header (CamelMedium *medium,
199 const gchar *name,
200 const gchar *value)
201 {
202 CamelMediumClass *class;
203
204 g_return_if_fail (CAMEL_IS_MEDIUM (medium));
205 g_return_if_fail (name != NULL);
206
207 if (value == NULL) {
208 camel_medium_remove_header (medium, name);
209 return;
210 }
211
212 class = CAMEL_MEDIUM_GET_CLASS (medium);
213 g_return_if_fail (class != NULL);
214 g_return_if_fail (class->set_header != NULL);
215
216 class->set_header (medium, name, value);
217 }
218
219 /**
220 * camel_medium_remove_header:
221 * @medium: a #CamelMedium
222 * @name: the name of the header
223 *
224 * Removes the named header from the medium. All occurances of the
225 * header are removed.
226 **/
227 void
camel_medium_remove_header(CamelMedium * medium,const gchar * name)228 camel_medium_remove_header (CamelMedium *medium,
229 const gchar *name)
230 {
231 CamelMediumClass *class;
232
233 g_return_if_fail (CAMEL_IS_MEDIUM (medium));
234 g_return_if_fail (name != NULL);
235
236 class = CAMEL_MEDIUM_GET_CLASS (medium);
237 g_return_if_fail (class != NULL);
238 g_return_if_fail (class->remove_header != NULL);
239
240 class->remove_header (medium, name);
241 }
242
243 /**
244 * camel_medium_get_header:
245 * @medium: a #CamelMedium
246 * @name: the name of the header
247 *
248 * Gets the value of the named header in the medium, or %NULL if
249 * it is unset. The caller should not modify or free the data.
250 *
251 * If the header occurs more than once, only retrieve the first
252 * instance of the header. For multi-occuring headers, use
253 * camel_medium_dup_headers() or camel_medium_get_headers().
254 *
255 * Returns: (nullable): the value of the named header, or %NULL
256 **/
257 const gchar *
camel_medium_get_header(CamelMedium * medium,const gchar * name)258 camel_medium_get_header (CamelMedium *medium,
259 const gchar *name)
260 {
261 CamelMediumClass *class;
262
263 g_return_val_if_fail (CAMEL_IS_MEDIUM (medium), NULL);
264 g_return_val_if_fail (name != NULL, NULL);
265
266 class = CAMEL_MEDIUM_GET_CLASS (medium);
267 g_return_val_if_fail (class != NULL, NULL);
268 g_return_val_if_fail (class->get_header != NULL, NULL);
269
270 return class->get_header (medium, name);
271 }
272
273 /**
274 * camel_medium_dup_headers:
275 * @medium: a #CamelMedium object
276 *
277 * Gets an array of all header name/value pairs. The values will be
278 * decoded to UTF-8 for any headers that are recognized by Camel.
279 * See also camel_medium_get_headers().
280 *
281 * Returns: (transfer full): the array of headers, which must be freed with camel_name_value_array_free().
282 *
283 * Since: 3.24
284 **/
285 CamelNameValueArray *
camel_medium_dup_headers(CamelMedium * medium)286 camel_medium_dup_headers (CamelMedium *medium)
287 {
288 CamelMediumClass *class;
289
290 g_return_val_if_fail (CAMEL_IS_MEDIUM (medium), NULL);
291
292 class = CAMEL_MEDIUM_GET_CLASS (medium);
293 g_return_val_if_fail (class != NULL, NULL);
294 g_return_val_if_fail (class->dup_headers != NULL, NULL);
295
296 return class->dup_headers (medium);
297 }
298
299 /**
300 * camel_medium_get_headers:
301 * @medium: a #CamelMedium object
302 *
303 * Gets an array of all header name/value pairs. The values will be
304 * decoded to UTF-8 for any headers that are recognized by Camel.
305 * See also camel_medium_dup_headers().
306 *
307 * Returns: (transfer none): the array of headers, owned by @medium.
308 *
309 * Since: 3.24
310 **/
311 const CamelNameValueArray *
camel_medium_get_headers(CamelMedium * medium)312 camel_medium_get_headers (CamelMedium *medium)
313 {
314 CamelMediumClass *class;
315
316 g_return_val_if_fail (CAMEL_IS_MEDIUM (medium), NULL);
317
318 class = CAMEL_MEDIUM_GET_CLASS (medium);
319 g_return_val_if_fail (class != NULL, NULL);
320 g_return_val_if_fail (class->get_headers != NULL, NULL);
321
322 return class->get_headers (medium);
323 }
324
325 /**
326 * camel_medium_get_content:
327 * @medium: a #CamelMedium object
328 *
329 * Gets a data wrapper that represents the content of the medium,
330 * without its headers.
331 *
332 * Returns: (transfer none) (nullable): a #CamelDataWrapper containing
333 * @medium's content. Can return NULL.
334 **/
335 CamelDataWrapper *
camel_medium_get_content(CamelMedium * medium)336 camel_medium_get_content (CamelMedium *medium)
337 {
338 CamelMediumClass *class;
339
340 g_return_val_if_fail (CAMEL_IS_MEDIUM (medium), NULL);
341
342 class = CAMEL_MEDIUM_GET_CLASS (medium);
343 g_return_val_if_fail (class != NULL, NULL);
344 g_return_val_if_fail (class->get_content != NULL, NULL);
345
346 return class->get_content (medium);
347 }
348
349 /**
350 * camel_medium_set_content:
351 * @medium: a #CamelMedium object
352 * @content: a #CamelDataWrapper object
353 *
354 * Sets the content of @medium to be @content.
355 **/
356 void
camel_medium_set_content(CamelMedium * medium,CamelDataWrapper * content)357 camel_medium_set_content (CamelMedium *medium,
358 CamelDataWrapper *content)
359 {
360 CamelMediumClass *class;
361
362 g_return_if_fail (CAMEL_IS_MEDIUM (medium));
363
364 if (content != NULL)
365 g_return_if_fail (CAMEL_IS_DATA_WRAPPER (content));
366
367 class = CAMEL_MEDIUM_GET_CLASS (medium);
368 g_return_if_fail (class != NULL);
369 g_return_if_fail (class->set_content != NULL);
370
371 class->set_content (medium, content);
372 }
373