Replace functions which called once with their bodies
[pidgin-git.git] / libpurple / protocols / jabber / jingle / content.c
bloba641328ac50345381c60443d2bda1dcc1202442a
1 /**
2 * @file content.c
4 * purple
6 * Purple is the legal property of its developers, whose names are too numerous
7 * to list here. Please refer to the COPYRIGHT file distributed with this
8 * source distribution.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
25 #include "internal.h"
26 #include "glibcompat.h"
28 #include "debug.h"
29 #include "content.h"
30 #include "jingle.h"
32 #include <string.h>
34 typedef struct
36 JingleSession *session;
37 gchar *description_type;
38 gchar *creator;
39 gchar *disposition;
40 gchar *name;
41 gchar *senders;
42 JingleTransport *transport;
43 JingleTransport *pending_transport;
44 } JingleContentPrivate;
46 enum {
47 PROP_0,
48 PROP_SESSION,
49 PROP_CREATOR,
50 PROP_DISPOSITION,
51 PROP_NAME,
52 PROP_SENDERS,
53 PROP_TRANSPORT,
54 PROP_PENDING_TRANSPORT,
55 PROP_LAST
58 static GParamSpec *properties[PROP_LAST];
60 G_DEFINE_DYNAMIC_TYPE_EXTENDED(
61 JingleContent,
62 jingle_content,
63 G_TYPE_OBJECT,
65 G_ADD_PRIVATE_DYNAMIC(JingleContent)
68 /******************************************************************************
69 * JingleContent Implementation
70 *****************************************************************************/
71 static JingleContent *
72 jingle_content_parse_internal(PurpleXmlNode *content)
74 PurpleXmlNode *description = purple_xmlnode_get_child(content, "description");
75 const gchar *type = purple_xmlnode_get_namespace(description);
76 const gchar *creator = purple_xmlnode_get_attrib(content, "creator");
77 const gchar *disposition = purple_xmlnode_get_attrib(content, "disposition");
78 const gchar *senders = purple_xmlnode_get_attrib(content, "senders");
79 const gchar *name = purple_xmlnode_get_attrib(content, "name");
80 JingleTransport *transport =
81 jingle_transport_parse(purple_xmlnode_get_child(content, "transport"));
82 if (transport == NULL)
83 return NULL;
85 if (senders == NULL)
86 senders = "both";
88 return jingle_content_create(type, creator, disposition, name, senders, transport);
91 static PurpleXmlNode *
92 jingle_content_to_xml_internal(JingleContent *content, PurpleXmlNode *jingle, JingleActionType action)
94 PurpleXmlNode *node = purple_xmlnode_new_child(jingle, "content");
95 gchar *creator = jingle_content_get_creator(content);
96 gchar *name = jingle_content_get_name(content);
97 gchar *senders = jingle_content_get_senders(content);
98 gchar *disposition = jingle_content_get_disposition(content);
100 purple_xmlnode_set_attrib(node, "creator", creator);
101 purple_xmlnode_set_attrib(node, "name", name);
102 purple_xmlnode_set_attrib(node, "senders", senders);
103 if (!purple_strequal("session", disposition))
104 purple_xmlnode_set_attrib(node, "disposition", disposition);
106 g_free(disposition);
107 g_free(senders);
108 g_free(name);
109 g_free(creator);
111 if (action != JINGLE_CONTENT_REMOVE) {
112 JingleTransport *transport;
114 if (action != JINGLE_TRANSPORT_ACCEPT &&
115 action != JINGLE_TRANSPORT_INFO &&
116 action != JINGLE_TRANSPORT_REJECT &&
117 action != JINGLE_TRANSPORT_REPLACE) {
118 PurpleXmlNode *description = purple_xmlnode_new_child(node, "description");
120 purple_xmlnode_set_namespace(description,
121 jingle_content_get_description_type(content));
124 if (action != JINGLE_TRANSPORT_REJECT && action == JINGLE_TRANSPORT_REPLACE)
125 transport = jingle_content_get_pending_transport(content);
126 else
127 transport = jingle_content_get_transport(content);
129 jingle_transport_to_xml(transport, node, action);
130 g_object_unref(transport);
133 return node;
136 /******************************************************************************
137 * GObject Stuff
138 *****************************************************************************/
139 static void
140 jingle_content_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
142 JingleContent *content = JINGLE_CONTENT(object);
143 JingleContentPrivate *priv = jingle_content_get_instance_private(content);
145 switch (prop_id) {
146 case PROP_SESSION:
147 priv->session = g_value_get_object(value);
148 break;
149 case PROP_CREATOR:
150 g_free(priv->creator);
151 priv->creator = g_value_dup_string(value);
152 break;
153 case PROP_DISPOSITION:
154 g_free(priv->disposition);
155 priv->disposition = g_value_dup_string(value);
156 break;
157 case PROP_NAME:
158 g_free(priv->name);
159 priv->name = g_value_dup_string(value);
160 break;
161 case PROP_SENDERS:
162 g_free(priv->senders);
163 priv->senders = g_value_dup_string(value);
164 break;
165 case PROP_TRANSPORT:
166 if (priv->transport)
167 g_object_unref(priv->transport);
168 priv->transport = g_value_get_object(value);
169 break;
170 case PROP_PENDING_TRANSPORT:
171 if (priv->pending_transport)
172 g_object_unref(priv->pending_transport);
173 priv->pending_transport = g_value_get_object(value);
174 break;
175 default:
176 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
177 break;
181 static void
182 jingle_content_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
184 JingleContent *content = JINGLE_CONTENT(object);
185 JingleContentPrivate *priv = jingle_content_get_instance_private(content);
187 switch (prop_id) {
188 case PROP_SESSION:
189 g_value_set_object(value, priv->session);
190 break;
191 case PROP_CREATOR:
192 g_value_set_string(value, priv->creator);
193 break;
194 case PROP_DISPOSITION:
195 g_value_set_string(value, priv->disposition);
196 break;
197 case PROP_NAME:
198 g_value_set_string(value, priv->name);
199 break;
200 case PROP_SENDERS:
201 g_value_set_string(value, priv->senders);
202 break;
203 case PROP_TRANSPORT:
204 g_value_set_object(value, priv->transport);
205 break;
206 case PROP_PENDING_TRANSPORT:
207 g_value_set_object(value, priv->pending_transport);
208 break;
209 default:
210 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
211 break;
215 static void
216 jingle_content_init (JingleContent *content)
220 static void
221 jingle_content_finalize (GObject *content)
223 JingleContentPrivate *priv = jingle_content_get_instance_private(JINGLE_CONTENT(content));
225 purple_debug_info("jingle","jingle_content_finalize\n");
227 g_free(priv->description_type);
228 g_free(priv->creator);
229 g_free(priv->disposition);
230 g_free(priv->name);
231 g_free(priv->senders);
232 g_object_unref(priv->transport);
233 if (priv->pending_transport)
234 g_object_unref(priv->pending_transport);
236 G_OBJECT_CLASS(jingle_content_parent_class)->finalize(content);
240 static void
241 jingle_content_class_finalize (JingleContentClass *klass)
245 static void
246 jingle_content_class_init (JingleContentClass *klass)
248 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
250 obj_class->finalize = jingle_content_finalize;
251 obj_class->set_property = jingle_content_set_property;
252 obj_class->get_property = jingle_content_get_property;
254 klass->to_xml = jingle_content_to_xml_internal;
255 klass->parse = jingle_content_parse_internal;
257 properties[PROP_SESSION] = g_param_spec_object("session",
258 "Jingle Session",
259 "The jingle session parent of this content.",
260 JINGLE_TYPE_SESSION,
261 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
263 properties[PROP_CREATOR] = g_param_spec_string("creator",
264 "Creator",
265 "The participant that created this content.",
266 NULL,
267 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
269 properties[PROP_DISPOSITION] = g_param_spec_string("disposition",
270 "Disposition",
271 "The disposition of the content.",
272 NULL,
273 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
275 properties[PROP_NAME] = g_param_spec_string("name",
276 "Name",
277 "The name of this content.",
278 NULL,
279 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
281 properties[PROP_SENDERS] = g_param_spec_string("senders",
282 "Senders",
283 "The sender of this content.",
284 NULL,
285 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
287 properties[PROP_TRANSPORT] = g_param_spec_object("transport",
288 "transport",
289 "The transport of this content.",
290 JINGLE_TYPE_TRANSPORT,
291 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
293 properties[PROP_PENDING_TRANSPORT] = g_param_spec_object("pending-transport",
294 "Pending transport",
295 "The pending transport contained within this content",
296 JINGLE_TYPE_TRANSPORT,
297 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
299 g_object_class_install_properties(obj_class, PROP_LAST, properties);
302 /******************************************************************************
303 * Public API
304 *****************************************************************************/
305 void
306 jingle_content_register(PurplePlugin *plugin)
308 jingle_content_register_type(G_TYPE_MODULE(plugin));
311 JingleContent *
312 jingle_content_create(const gchar *type, const gchar *creator,
313 const gchar *disposition, const gchar *name,
314 const gchar *senders, JingleTransport *transport)
318 JingleContent *content = g_object_new(jingle_get_type(type),
319 "creator", creator,
320 "disposition", disposition != NULL ? disposition : "session",
321 "name", name,
322 "senders", senders != NULL ? senders : "both",
323 "transport", transport,
324 NULL);
325 return content;
328 JingleSession *jingle_content_get_session(JingleContent *content)
330 JingleSession *session;
331 g_object_get(content, "session", &session, NULL);
332 return session;
335 const gchar *
336 jingle_content_get_description_type(JingleContent *content)
338 return JINGLE_CONTENT_GET_CLASS(content)->description_type;
341 gchar *
342 jingle_content_get_creator(JingleContent *content)
344 gchar *creator;
345 g_object_get(content, "creator", &creator, NULL);
346 return creator;
349 gchar *
350 jingle_content_get_disposition(JingleContent *content)
352 gchar *disposition;
353 g_object_get(content, "disposition", &disposition, NULL);
354 return disposition;
357 gchar *
358 jingle_content_get_name(JingleContent *content)
360 gchar *name;
361 g_object_get(content, "name", &name, NULL);
362 return name;
365 gchar *
366 jingle_content_get_senders(JingleContent *content)
368 gchar *senders;
369 g_object_get(content, "senders", &senders, NULL);
370 return senders;
373 JingleTransport *
374 jingle_content_get_transport(JingleContent *content)
376 JingleTransport *transport;
377 g_object_get(content, "transport", &transport, NULL);
378 return transport;
381 JingleTransport *
382 jingle_content_get_pending_transport(JingleContent *content)
384 JingleTransport *pending_transport;
385 g_object_get(content, "pending-transport", &pending_transport, NULL);
386 return pending_transport;
389 void
390 jingle_content_set_session(JingleContent *content, JingleSession *session)
392 g_return_if_fail(JINGLE_IS_CONTENT(content));
393 g_return_if_fail(JINGLE_IS_SESSION(session));
394 g_object_set(content, "session", session, NULL);
397 void
398 jingle_content_set_pending_transport(JingleContent *content, JingleTransport *transport)
400 g_object_set(content, "pending-transport", transport, NULL);
403 void
404 jingle_content_accept_transport(JingleContent *content)
406 JingleContentPrivate *priv = NULL;
407 GObject *obj;
409 g_return_if_fail(JINGLE_IS_CONTENT(content));
411 priv = jingle_content_get_instance_private(content);
413 if (priv->transport)
414 g_object_unref(priv->transport);
416 priv->transport = priv->pending_transport;
417 priv->pending_transport = NULL;
419 obj = G_OBJECT(content);
420 g_object_freeze_notify(obj);
421 g_object_notify_by_pspec(obj, properties[PROP_TRANSPORT]);
422 g_object_notify_by_pspec(obj, properties[PROP_PENDING_TRANSPORT]);
423 g_object_thaw_notify(obj);
426 void
427 jingle_content_remove_pending_transport(JingleContent *content)
429 JingleContentPrivate *priv = NULL;
431 g_return_if_fail(JINGLE_IS_CONTENT(content));
433 priv = jingle_content_get_instance_private(content);
435 if (priv->pending_transport) {
436 g_object_unref(priv->pending_transport);
437 priv->pending_transport = NULL;
440 g_object_notify_by_pspec(G_OBJECT(content), properties[PROP_PENDING_TRANSPORT]);
443 void
444 jingle_content_modify(JingleContent *content, const gchar *senders)
446 g_object_set(content, "senders", senders, NULL);
449 JingleContent *
450 jingle_content_parse(PurpleXmlNode *content)
452 const gchar *type = purple_xmlnode_get_namespace(purple_xmlnode_get_child(content, "description"));
453 GType jingle_type = jingle_get_type(type);
455 if (jingle_type != G_TYPE_NONE) {
456 return JINGLE_CONTENT_CLASS(g_type_class_ref(jingle_type))->parse(content);
457 } else {
458 return NULL;
462 PurpleXmlNode *
463 jingle_content_to_xml(JingleContent *content, PurpleXmlNode *jingle, JingleActionType action)
465 g_return_val_if_fail(content != NULL, NULL);
466 g_return_val_if_fail(JINGLE_IS_CONTENT(content), NULL);
467 return JINGLE_CONTENT_GET_CLASS(content)->to_xml(content, jingle, action);
470 void
471 jingle_content_handle_action(JingleContent *content, PurpleXmlNode *xmlcontent, JingleActionType action)
473 g_return_if_fail(content != NULL);
474 g_return_if_fail(JINGLE_IS_CONTENT(content));
475 JINGLE_CONTENT_GET_CLASS(content)->handle_action(content, xmlcontent, action);