b3964f29e37a53a3e315c2bb84f518dfe6b09486
[platform/upstream/evolution-data-server.git] / camel / camel-medium.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /* camelMedium.c : Abstract class for a medium
4  *
5  * Authors: Bertrand Guiheneuf <bertrand@helixcode.com>
6  *          Michael Zucchi <notzed@ximian.com>
7  *
8  * Copyright 1999, 2000 Ximian, Inc. (www.ximian.com)
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of version 2 of the GNU General Public
12  * License as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22  * USA
23  */
24
25
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29
30 #include <stdio.h>
31 #include <ctype.h>
32
33 #include "camel-medium.h"
34
35 #define d(x)
36
37 static CamelDataWrapperClass *parent_class = NULL;
38
39 /* Returns the class for a CamelMedium */
40 #define CM_CLASS(so) CAMEL_MEDIUM_CLASS (CAMEL_OBJECT_GET_CLASS(so))
41
42 static gboolean is_offline (CamelDataWrapper *data_wrapper);
43 static void add_header (CamelMedium *medium, const char *name,
44                         const void *value);
45 static void set_header (CamelMedium *medium, const char *name, const void *value);
46 static void remove_header (CamelMedium *medium, const char *name);
47 static const void *get_header (CamelMedium *medium, const char *name);
48
49 static GArray *get_headers (CamelMedium *medium);
50 static void free_headers (CamelMedium *medium, GArray *headers);
51
52 static CamelDataWrapper *get_content_object (CamelMedium *medium);
53 static void set_content_object (CamelMedium *medium,
54                                 CamelDataWrapper *content);
55
56 static void
57 camel_medium_class_init (CamelMediumClass *camel_medium_class)
58 {
59         CamelDataWrapperClass *camel_data_wrapper_class =
60                 CAMEL_DATA_WRAPPER_CLASS (camel_medium_class);
61
62         parent_class = CAMEL_DATA_WRAPPER_CLASS (camel_type_get_global_classfuncs (camel_data_wrapper_get_type ()));
63
64         /* virtual method overload */
65         camel_data_wrapper_class->is_offline = is_offline;
66
67         /* virtual method definition */
68         camel_medium_class->add_header = add_header;
69         camel_medium_class->set_header = set_header;
70         camel_medium_class->remove_header = remove_header;
71         camel_medium_class->get_header = get_header;
72
73         camel_medium_class->get_headers = get_headers;
74         camel_medium_class->free_headers = free_headers;
75
76         camel_medium_class->set_content_object = set_content_object;
77         camel_medium_class->get_content_object = get_content_object;
78 }
79
80 static void
81 camel_medium_init (gpointer object, gpointer klass)
82 {
83         CamelMedium *camel_medium = CAMEL_MEDIUM (object);
84
85         camel_medium->content = NULL;
86 }
87
88 static void
89 camel_medium_finalize (CamelObject *object)
90 {
91         CamelMedium *medium = CAMEL_MEDIUM (object);
92
93         if (medium->content)
94                 camel_object_unref (CAMEL_OBJECT (medium->content));
95 }
96
97
98 CamelType
99 camel_medium_get_type (void)
100 {
101         static CamelType camel_medium_type = CAMEL_INVALID_TYPE;
102
103         if (camel_medium_type == CAMEL_INVALID_TYPE) {
104                 camel_medium_type = camel_type_register (CAMEL_DATA_WRAPPER_TYPE, "medium",
105                                                          sizeof (CamelMedium),
106                                                          sizeof (CamelMediumClass),
107                                                          (CamelObjectClassInitFunc) camel_medium_class_init,
108                                                          NULL,
109                                                          (CamelObjectInitFunc) camel_medium_init,
110                                                          (CamelObjectFinalizeFunc) camel_medium_finalize);
111         }
112
113         return camel_medium_type;
114 }
115
116 static gboolean
117 is_offline (CamelDataWrapper *data_wrapper)
118 {
119         return parent_class->is_offline (data_wrapper) ||
120                 camel_data_wrapper_is_offline (CAMEL_MEDIUM (data_wrapper)->content);
121 }
122
123 static void
124 add_header (CamelMedium *medium, const char *name, const void *value)
125 {
126         g_warning("No %s::add_header implemented, adding %s", camel_type_to_name(CAMEL_OBJECT_GET_TYPE(medium)), name);
127 }
128
129 /**
130  * camel_medium_add_header:
131  * @medium: a CamelMedium
132  * @name: name of the header
133  * @value: value of the header
134  *
135  * Adds a header to a medium.
136  *
137  * FIXME: Where does it add it? We need to be able to prepend and
138  * append headers, and also be able to insert them relative to other
139  * headers.   No we dont, order isn't important! Z
140  **/
141 void
142 camel_medium_add_header (CamelMedium *medium, const char *name, const void *value)
143 {
144         g_return_if_fail (CAMEL_IS_MEDIUM (medium));
145         g_return_if_fail (name != NULL);
146         g_return_if_fail (value != NULL);
147
148         CM_CLASS (medium)->add_header(medium, name, value);
149 }
150
151 static void
152 set_header (CamelMedium *medium, const char *name, const void *value)
153 {
154         g_warning("No %s::set_header implemented, setting %s", camel_type_to_name(CAMEL_OBJECT_GET_TYPE(medium)), name);
155 }
156
157 /**
158  * camel_medium_set_header:
159  * @medium: a CamelMedium
160  * @name: name of the header
161  * @value: value of the header
162  *
163  * Sets the value of a header.  Any other occurances of the header
164  * will be removed.  Setting a %NULL header can be used to remove
165  * the header also.
166  **/
167 void
168 camel_medium_set_header (CamelMedium *medium, const char *name, const void *value)
169 {
170         g_return_if_fail (CAMEL_IS_MEDIUM (medium));
171         g_return_if_fail (name != NULL);
172
173         if (value == NULL)
174                 CM_CLASS(medium)->remove_header(medium, name);
175         else
176                 CM_CLASS(medium)->set_header(medium, name, value);
177 }
178
179 static void
180 remove_header(CamelMedium *medium, const char *name)
181 {
182         g_warning("No %s::remove_header implemented, removing %s", camel_type_to_name(CAMEL_OBJECT_GET_TYPE(medium)), name);
183 }
184
185 /**
186  * camel_medium_remove_header:
187  * @medium: a medium
188  * @name: the name of the header
189  *
190  * Removes the named header from the medium.  All occurances of the
191  * header are removed.
192  **/
193 void
194 camel_medium_remove_header(CamelMedium *medium, const char *name)
195 {
196         g_return_if_fail (CAMEL_IS_MEDIUM (medium));
197         g_return_if_fail (name != NULL);
198
199         CM_CLASS(medium)->remove_header(medium, name);
200 }
201
202
203 static const void *
204 get_header(CamelMedium *medium, const char *name)
205 {
206         g_warning("No %s::get_header implemented, getting %s", camel_type_to_name(CAMEL_OBJECT_GET_TYPE(medium)), name);
207         return NULL;
208 }
209
210 /**
211  * camel_medium_get_header:
212  * @medium: a medium
213  * @name: the name of the header
214  *
215  * Returns the value of the named header in the medium, or %NULL if
216  * it is unset. The caller should not modify or free the data.
217  *
218  * If the header occurs more than once, only retrieve the first
219  * instance of the header.  For multi-occuring headers, use
220  * :get_headers().
221  *
222  * Return value: the value of the named header, or %NULL
223  **/
224 const void *
225 camel_medium_get_header(CamelMedium *medium, const char *name)
226 {
227         g_return_val_if_fail (CAMEL_IS_MEDIUM (medium), NULL);
228         g_return_val_if_fail (name != NULL, NULL);
229
230         return CM_CLASS (medium)->get_header (medium, name);
231 }
232
233
234 static GArray *
235 get_headers(CamelMedium *medium)
236 {
237         g_warning("No %s::get_headers implemented", camel_type_to_name(CAMEL_OBJECT_GET_TYPE(medium)));
238         return NULL;
239 }
240
241 /**
242  * camel_medium_get_headers:
243  * @medium: a medium
244  *
245  * Returns an array of all header name/value pairs (as
246  * CamelMediumHeader structures). The values will be decoded
247  * to UTF-8 for any headers that are recognized by Camel. The
248  * caller should not modify the returned data.
249  *
250  * Return value: the array of headers, which must be freed with
251  * camel_medium_free_headers().
252  **/
253 GArray *
254 camel_medium_get_headers(CamelMedium *medium)
255 {
256         g_return_val_if_fail (CAMEL_IS_MEDIUM (medium), NULL);
257
258         return CM_CLASS (medium)->get_headers (medium);
259 }
260
261 static void
262 free_headers (CamelMedium *medium, GArray *headers)
263 {
264         g_warning("No %s::free_headers implemented", camel_type_to_name(CAMEL_OBJECT_GET_TYPE(medium)));
265 }
266
267 /**
268  * camel_medium_free_headers:
269  * @medium: a medium
270  * @headers: an array of headers returned from camel_medium_get_headers()
271  *
272  * Frees @headers
273  **/
274 void
275 camel_medium_free_headers (CamelMedium *medium, GArray *headers)
276 {
277         g_return_if_fail (CAMEL_IS_MEDIUM (medium));
278         g_return_if_fail (headers != NULL);
279
280         CM_CLASS (medium)->free_headers (medium, headers);
281 }
282
283
284 static CamelDataWrapper *
285 get_content_object(CamelMedium *medium)
286 {
287         return medium->content;
288 }
289
290 /**
291  * camel_medium_get_content_object:
292  * @medium: a medium
293  *
294  * Returns a data wrapper that represents the content of the medium,
295  * without its headers.
296  *
297  * Return value: the medium's content object.
298  **/
299 CamelDataWrapper *
300 camel_medium_get_content_object (CamelMedium *medium)
301 {
302         g_return_val_if_fail (CAMEL_IS_MEDIUM (medium), NULL);
303
304         return CM_CLASS (medium)->get_content_object (medium);
305 }
306
307
308 static void
309 set_content_object (CamelMedium *medium, CamelDataWrapper *content)
310 {
311         if (medium->content)
312                 camel_object_unref (CAMEL_OBJECT (medium->content));
313         camel_object_ref (CAMEL_OBJECT (content));
314         medium->content = content;
315 }
316
317 /**
318  * camel_medium_set_content_object:
319  * @medium: a medium
320  * @content: a data wrapper representing the medium's content
321  *
322  * Sets the content of @medium to be @content.
323  **/
324 void
325 camel_medium_set_content_object (CamelMedium *medium,
326                                  CamelDataWrapper *content)
327 {
328         g_return_if_fail (CAMEL_IS_MEDIUM (medium));
329         g_return_if_fail (CAMEL_IS_DATA_WRAPPER (content));
330
331         CM_CLASS (medium)->set_content_object (medium, content);
332 }