Reapplying patch to disable attempts to use gtk-doc
[profile/ivi/libsoup2.4.git] / libsoup / soup-session-feature.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * soup-session-feature.c: Miscellaneous session feature-provider interface
4  *
5  * Copyright (C) 2008 Red Hat, Inc.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include "soup-session-feature.h"
13 #include "soup-message-private.h"
14
15 /**
16  * SECTION:soup-session-feature
17  * @short_description: Interface for miscellaneous session features
18  *
19  * #SoupSessionFeature is the interface used by classes that extend
20  * the functionality of a #SoupSession. Some features like HTTP
21  * authentication handling are implemented internally via
22  * #SoupSessionFeature<!-- -->s. Other features can be added to the session
23  * by the application. (Eg, #SoupLogger, #SoupCookieJar.)
24  *
25  * See soup_session_add_feature(), etc, to add a feature to a session.
26  **/
27
28 /**
29  * SoupSessionFeature:
30  *
31  * An object that implement some sort of optional feature for
32  * #SoupSession.
33  *
34  * Since: 2.24
35  **/
36
37 /**
38  * SoupSessionFeatureInterface:
39  * @parent: The parent interface.
40  * @attach: Perform setup when a feature is added to a session
41  * @detach: Perform cleanup when a feature is removed from a session
42  * @request_queued: Proxies the session's #SoupSession::request_queued signal
43  * @request_started: Proxies the session's #SoupSession::request_started signal
44  * @request_unqueued: Proxies the session's #SoupSession::request_unqueued signal
45  * @add_feature: adds a sub-feature to the main feature
46  * @remove_feature: removes a sub-feature from the main feature
47  * @has_feature: tests if the feature includes a sub-feature
48  *
49  * The interface implemented by #SoupSessionFeature<!-- -->s.
50  *
51  * Since: 2.24
52  **/
53
54 static void soup_session_feature_interface_init (SoupSessionFeatureInterface *interface);
55
56 static void attach (SoupSessionFeature *feature, SoupSession *session);
57 static void detach (SoupSessionFeature *feature, SoupSession *session);
58
59 GType
60 soup_session_feature_get_type (void)
61 {
62   static volatile gsize g_define_type_id__volatile = 0;
63   if (g_once_init_enter (&g_define_type_id__volatile))
64     {
65       GType g_define_type_id =
66         g_type_register_static_simple (G_TYPE_INTERFACE,
67                                        g_intern_static_string ("SoupSessionFeature"),
68                                        sizeof (SoupSessionFeatureInterface),
69                                        (GClassInitFunc)soup_session_feature_interface_init,
70                                        0,
71                                        (GInstanceInitFunc)NULL,
72                                        (GTypeFlags) 0);
73       g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_OBJECT);
74       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
75     }
76   return g_define_type_id__volatile;
77 }
78
79 static void
80 soup_session_feature_interface_init (SoupSessionFeatureInterface *interface)
81 {
82         interface->attach = attach;
83         interface->detach = detach;
84 }
85
86 static void
87 weak_notify_unref (gpointer feature, GObject *ex_object)
88 {
89         g_object_unref (feature);
90 }
91
92 static void
93 request_queued (SoupSession *session, SoupMessage *msg, gpointer feature)
94 {
95         if (soup_message_disables_feature (msg, feature))
96                 return;
97
98         SOUP_SESSION_FEATURE_GET_CLASS (feature)->
99                 request_queued (feature, session, msg);
100 }
101
102 static void
103 request_started (SoupSession *session, SoupMessage *msg,
104                  SoupSocket *socket, gpointer feature)
105 {
106         if (soup_message_disables_feature (msg, feature))
107                 return;
108
109         SOUP_SESSION_FEATURE_GET_CLASS (feature)->
110                 request_started (feature, session, msg, socket);
111 }
112
113 static void
114 request_unqueued (SoupSession *session, SoupMessage *msg, gpointer feature)
115 {
116         if (soup_message_disables_feature (msg, feature))
117                 return;
118
119         SOUP_SESSION_FEATURE_GET_CLASS (feature)->
120                 request_unqueued (feature, session, msg);
121 }
122
123 static void
124 attach (SoupSessionFeature *feature, SoupSession *session)
125 {
126         g_object_weak_ref (G_OBJECT (session),
127                            weak_notify_unref, g_object_ref (feature));
128
129         if (SOUP_SESSION_FEATURE_GET_CLASS (feature)->request_queued) {
130                 g_signal_connect (session, "request_queued",
131                                   G_CALLBACK (request_queued), feature);
132         }
133
134         if (SOUP_SESSION_FEATURE_GET_CLASS (feature)->request_started) {
135                 g_signal_connect (session, "request_started",
136                                   G_CALLBACK (request_started), feature);
137         }
138
139         if (SOUP_SESSION_FEATURE_GET_CLASS (feature)->request_unqueued) {
140                 g_signal_connect (session, "request_unqueued",
141                                   G_CALLBACK (request_unqueued), feature);
142         }
143 }
144
145 void
146 soup_session_feature_attach (SoupSessionFeature *feature,
147                              SoupSession        *session)
148 {
149         SOUP_SESSION_FEATURE_GET_CLASS (feature)->attach (feature, session);
150 }
151
152 static void
153 detach (SoupSessionFeature *feature, SoupSession *session)
154 {
155         g_object_weak_unref (G_OBJECT (session), weak_notify_unref, feature);
156
157         g_signal_handlers_disconnect_by_func (session, request_queued, feature);
158         g_signal_handlers_disconnect_by_func (session, request_started, feature);
159         g_signal_handlers_disconnect_by_func (session, request_unqueued, feature);
160
161         g_object_unref (feature);
162 }
163
164 void
165 soup_session_feature_detach (SoupSessionFeature *feature,
166                              SoupSession        *session)
167 {
168         SOUP_SESSION_FEATURE_GET_CLASS (feature)->detach (feature, session);
169 }
170
171 /**
172  * soup_session_feature_add_feature:
173  * @feature: the "base" feature
174  * @type: the #GType of a "sub-feature"
175  *
176  * Adds a "sub-feature" of type @type to the base feature @feature.
177  * This is used for features that can be extended with multiple
178  * different types. Eg, the authentication manager can be extended
179  * with subtypes of #SoupAuth.
180  *
181  * Return value: %TRUE if @feature accepted @type as a subfeature.
182  *
183  * Since: 2.34
184  */
185 gboolean
186 soup_session_feature_add_feature (SoupSessionFeature *feature,
187                                   GType               type)
188 {
189         SoupSessionFeatureInterface *feature_iface =
190               SOUP_SESSION_FEATURE_GET_CLASS (feature);
191
192         if (feature_iface->add_feature)
193                 return feature_iface->add_feature (feature, type);
194         else
195                 return FALSE;
196 }
197
198 /**
199  * soup_session_feature_remove_feature:
200  * @feature: the "base" feature
201  * @type: the #GType of a "sub-feature"
202  *
203  * Removes the "sub-feature" of type @type from the base feature
204  * @feature. See soup_session_feature_add_feature().
205  *
206  * Return value: %TRUE if @type was removed from @feature
207  *
208  * Since: 2.34
209  */
210 gboolean
211 soup_session_feature_remove_feature (SoupSessionFeature *feature,
212                                      GType               type)
213 {
214         SoupSessionFeatureInterface *feature_iface =
215               SOUP_SESSION_FEATURE_GET_CLASS (feature);
216
217         if (feature_iface->remove_feature)
218                 return feature_iface->remove_feature (feature, type);
219         else
220                 return FALSE;
221 }
222
223 /**
224  * soup_session_feature_has_feature:
225  * @feature: the "base" feature
226  * @type: the #GType of a "sub-feature"
227  *
228  * Tests if @feature has a "sub-feature" of type @type. See
229  * soup_session_feature_add_feature().
230  *
231  * Return value: %TRUE if @feature has a subfeature of type @type
232  *
233  * Since: 2.34
234  */
235 gboolean
236 soup_session_feature_has_feature (SoupSessionFeature *feature,
237                                   GType               type)
238 {
239         SoupSessionFeatureInterface *feature_iface =
240               SOUP_SESSION_FEATURE_GET_CLASS (feature);
241
242         if (feature_iface->has_feature)
243                 return feature_iface->has_feature (feature, type);
244         else
245                 return FALSE;
246 }