remove SWFDEC_IS_AS_VALUE check
[swfdec.git] / swfdec-gtk / swfdec_gtk_loader.c
blobef950089f0a69aa5e18684bf418bc5e658742db7
1 /* Swfdec
2 * Copyright (C) 2006 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include <libsoup/soup.h>
25 #include <errno.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include "swfdec_gtk_loader.h"
30 /*** GTK-DOC ***/
32 /**
33 * SECTION:GtkExtensions
34 * @title: Gtk extensions
35 * @short_description: extension objects for @SwfdecGtkPlayer
37 * Swfdec-Gtk provides some objects that implement the various extensions
38 * provided by the @SwfdecPlayer object. They are used by default in the
39 * #SwfdecGtkPlayer object, but you can use them outside of it, too.
40 * However, they require certain Gtk functionality, such as a running glib
41 * main loop.
44 /**
45 * SwfdecGtkLoader:
47 * #SwfdecGtkLoader is a #SwfdecLoader that is intended as an easy way to be
48 * access ressources that are not stored in files, such as HTTP. It is a
49 * private object.
52 struct _SwfdecGtkLoader
54 SwfdecLoader loader;
56 SoupMessage * message; /* the message we're sending */
57 gboolean opened; /* set after first bytes of data have arrived */
60 struct _SwfdecGtkLoaderClass {
61 SwfdecLoaderClass loader_class;
63 SoupSession * session; /* the session used by the loader */
66 /*** SwfdecGtkLoader ***/
68 G_DEFINE_TYPE (SwfdecGtkLoader, swfdec_gtk_loader, SWFDEC_TYPE_FILE_LOADER)
70 static void
71 swfdec_gtk_loader_ensure_open (SwfdecGtkLoader *gtk)
73 char *real_uri;
75 if (gtk->opened)
76 return;
78 real_uri = soup_uri_to_string (soup_message_get_uri (gtk->message), FALSE);
79 swfdec_loader_set_url (SWFDEC_LOADER (gtk), real_uri);
80 g_free (real_uri);
81 if (soup_message_headers_get_encoding (gtk->message->response_headers) == SOUP_ENCODING_CONTENT_LENGTH) {
82 swfdec_loader_set_size (SWFDEC_LOADER (gtk),
83 soup_message_headers_get_content_length (gtk->message->response_headers));
85 swfdec_stream_open (SWFDEC_STREAM (gtk));
86 gtk->opened = TRUE;
89 static void
90 swfdec_gtk_loader_push (SoupMessage *msg, SoupBuffer *chunk, gpointer loader)
92 SwfdecGtkLoader *gtk = SWFDEC_GTK_LOADER (loader);
93 SwfdecBuffer *buffer;
95 chunk = soup_buffer_copy (chunk);
97 swfdec_gtk_loader_ensure_open (gtk);
98 buffer = swfdec_buffer_new_full ((unsigned char *) chunk->data, chunk->length,
99 (SwfdecBufferFreeFunc) soup_buffer_free, chunk);
100 swfdec_stream_push (loader, buffer);
103 static void
104 swfdec_gtk_loader_finished (SoupMessage *msg, gpointer loader)
106 if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
107 swfdec_gtk_loader_ensure_open (loader);
108 swfdec_stream_close (loader);
109 } else {
110 if (!SWFDEC_GTK_LOADER (loader)->opened) {
111 char *real_uri = soup_uri_to_string (soup_message_get_uri (msg), FALSE);
112 swfdec_loader_set_url (loader, real_uri);
113 g_free (real_uri);
115 swfdec_stream_error (loader, "%u %s", msg->status_code, msg->reason_phrase);
119 static void
120 swfdec_gtk_loader_dispose (GObject *object)
122 SwfdecGtkLoader *gtk = SWFDEC_GTK_LOADER (object);
124 if (gtk->message) {
125 g_signal_handlers_disconnect_by_func (gtk->message, swfdec_gtk_loader_push, gtk);
126 g_signal_handlers_disconnect_by_func (gtk->message, swfdec_gtk_loader_finished, gtk);
127 g_object_unref (gtk->message);
128 gtk->message = NULL;
131 G_OBJECT_CLASS (swfdec_gtk_loader_parent_class)->dispose (object);
134 static void
135 swfdec_gtk_loader_load (SwfdecLoader *loader, SwfdecPlayer *player,
136 const char *url_string, SwfdecBuffer *buffer, guint n_headers,
137 const char **header_names, const char **header_values)
139 SwfdecURL *url;
140 guint i;
142 if (swfdec_url_path_is_relative (url_string)) {
143 url = swfdec_url_new_relative (swfdec_player_get_base_url (player), url_string);
144 } else {
145 url = swfdec_url_new (url_string);
148 if (url == NULL) {
149 swfdec_stream_error (SWFDEC_STREAM (loader), "invalid URL %s", url_string);
150 return;
152 if (!swfdec_url_has_protocol (url, "http") &&
153 !swfdec_url_has_protocol (url, "https")) {
154 SWFDEC_LOADER_CLASS (swfdec_gtk_loader_parent_class)->load (loader, player,
155 url_string, buffer, n_headers, header_names, header_values);
156 } else {
157 SwfdecGtkLoader *gtk = SWFDEC_GTK_LOADER (loader);
158 SwfdecGtkLoaderClass *klass = SWFDEC_GTK_LOADER_GET_CLASS (gtk);
160 gtk->message = soup_message_new (buffer != NULL ? "POST" : "GET",
161 swfdec_url_get_url (url));
162 soup_message_set_flags (gtk->message, SOUP_MESSAGE_OVERWRITE_CHUNKS);
164 for (i = 0; i < n_headers; i++) {
165 soup_message_headers_append (gtk->message->request_headers,
166 header_names[i], header_values[i]);
169 g_signal_connect (gtk->message, "got-chunk", G_CALLBACK (swfdec_gtk_loader_push), gtk);
170 g_signal_connect (gtk->message, "finished", G_CALLBACK (swfdec_gtk_loader_finished), gtk);
171 if (buffer)
172 soup_message_set_request (gtk->message, "appliation/x-www-form-urlencoded",
173 SOUP_MEMORY_COPY, (char *) buffer->data, buffer->length);
174 g_object_ref (gtk->message);
175 soup_session_queue_message (klass->session, gtk->message, NULL, NULL);
177 swfdec_url_free (url);
180 static void
181 swfdec_gtk_loader_close (SwfdecStream *stream)
183 SwfdecGtkLoader *gtk = SWFDEC_GTK_LOADER (stream);
185 if (gtk->message && !swfdec_stream_is_complete (stream)) {
186 SwfdecGtkLoaderClass *klass = SWFDEC_GTK_LOADER_GET_CLASS (gtk);
188 soup_session_cancel_message (klass->session, gtk->message, SOUP_STATUS_CANCELLED);
189 g_object_unref (gtk->message);
190 gtk->message = NULL;
194 static void
195 swfdec_gtk_loader_class_init (SwfdecGtkLoaderClass *klass)
197 GObjectClass *object_class = G_OBJECT_CLASS (klass);
198 SwfdecStreamClass *stream_class = SWFDEC_STREAM_CLASS (klass);
199 SwfdecLoaderClass *loader_class = SWFDEC_LOADER_CLASS (klass);
201 object_class->dispose = swfdec_gtk_loader_dispose;
203 stream_class->close = swfdec_gtk_loader_close;
205 loader_class->load = swfdec_gtk_loader_load;
207 klass->session = soup_session_async_new ();
210 static void
211 swfdec_gtk_loader_init (SwfdecGtkLoader *gtk_loader)