back to development
[swfdec.git] / swfdec / swfdec_loader.c
blob0b7cff267f351ae588f6b7862ec463b10f0db804
1 /* Swfdec
2 * Copyright (C) 2006-2007 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 <string.h>
25 #include "swfdec_loader_internal.h"
26 #include "swfdec_buffer.h"
27 #include "swfdec_debug.h"
28 #include "swfdec_player_internal.h"
30 /*** gtk-doc ***/
32 /**
33 * SECTION:SwfdecLoader
34 * @title: SwfdecLoader
35 * @short_description: object used for input
37 * SwfdecLoader is the base class used for reading input. Since developers
38 * normally need to adapt input to the needs of their application, this class
39 * is provided to be adapted to their needs. It is used both for HTTP and
40 * RTMP access.
42 * Since Flash files can load new resources while operating, a #SwfdecLoader
43 * can be instructed to load another resource.
45 * For convenience, a #SwfdecLoader for file access is provided by Swfdec.
48 /**
49 * SwfdecLoader:
51 * This is the base object used for providing input. It is abstract, use a
52 * subclass to provide your input.
55 /**
56 * SwfdecLoaderClass:
57 * @load: initialize a new loader based on a parent loader object. The new
58 * loader will already have its URL set.
60 * This is the base class used for input. If you create a subclass, you are
61 * supposed to set the function pointers listed above.
64 /**
65 * SwfdecLoaderDataType:
66 * @SWFDEC_LOADER_DATA_UNKNOWN: Unidentified data or data that cannot be
67 * identified.
68 * @SWFDEC_LOADER_DATA_SWF: Data describing a normal Flash file.
69 * @SWFDEC_LOADER_DATA_FLV: Data describing a Flash video stream.
70 * @SWFDEC_LOADER_DATA_XML: Data in XML format.
71 * @SWFDEC_LOADER_DATA_TEXT: Textual data.
72 * @SWFDEC_LOADER_DATA_JPEG: a JPEG image
73 * @SWFDEC_LOADER_DATA_PNG: a PNG image
75 * This type describes the different types of data that can be loaded inside
76 * Swfdec. Swfdec identifies its data streams and you can use the
77 * swfdec_loader_get_data_type() to acquire more information about the data
78 * inside a #SwfdecLoader.
81 /*** SwfdecLoader ***/
83 enum {
84 PROP_0,
85 PROP_DATA_TYPE,
86 PROP_SIZE,
87 PROP_LOADED,
88 PROP_URL
91 G_DEFINE_ABSTRACT_TYPE (SwfdecLoader, swfdec_loader, SWFDEC_TYPE_STREAM)
93 static const char *
94 swfdec_loader_describe (SwfdecStream *stream)
96 const SwfdecURL *url = SWFDEC_LOADER (stream)->url;
98 if (url) {
99 return swfdec_url_get_url (url);
100 } else {
101 return "unknown url";
105 static void
106 swfdec_loader_get_property (GObject *object, guint param_id, GValue *value,
107 GParamSpec * pspec)
109 SwfdecLoader *loader = SWFDEC_LOADER (object);
111 switch (param_id) {
112 case PROP_DATA_TYPE:
113 g_value_set_enum (value, loader->data_type);
114 break;
115 case PROP_SIZE:
116 g_value_set_long (value, loader->size);
117 break;
118 case PROP_LOADED:
119 g_value_set_ulong (value, swfdec_loader_get_loaded (loader));
120 break;
121 case PROP_URL:
122 g_value_set_boxed (value, loader->url);
123 break;
124 default:
125 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
126 break;
130 static void
131 swfdec_loader_set_property (GObject *object, guint param_id, const GValue *value,
132 GParamSpec *pspec)
134 SwfdecLoader *loader = SWFDEC_LOADER (object);
136 switch (param_id) {
137 case PROP_SIZE:
138 if (loader->size == -1 && g_value_get_long (value) >= 0)
139 swfdec_loader_set_size (loader, g_value_get_long (value));
140 break;
141 default:
142 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
143 break;
147 static void
148 swfdec_loader_dispose (GObject *object)
150 SwfdecLoader *loader = SWFDEC_LOADER (object);
152 if (loader->url) {
153 swfdec_url_free (loader->url);
154 loader->url = NULL;
157 G_OBJECT_CLASS (swfdec_loader_parent_class)->dispose (object);
160 static void
161 swfdec_loader_class_init (SwfdecLoaderClass *klass)
163 GObjectClass *object_class = G_OBJECT_CLASS (klass);
164 SwfdecStreamClass *stream_class = SWFDEC_STREAM_CLASS (klass);
166 object_class->dispose = swfdec_loader_dispose;
167 object_class->get_property = swfdec_loader_get_property;
168 object_class->set_property = swfdec_loader_set_property;
170 g_object_class_install_property (object_class, PROP_DATA_TYPE,
171 g_param_spec_enum ("data-type", "data type", "the data's type as identified by Swfdec",
172 SWFDEC_TYPE_LOADER_DATA_TYPE, SWFDEC_LOADER_DATA_UNKNOWN, G_PARAM_READABLE));
173 g_object_class_install_property (object_class, PROP_SIZE,
174 g_param_spec_long ("size", "size", "amount of bytes in loader",
175 -1, G_MAXLONG, -1, G_PARAM_READWRITE));
176 g_object_class_install_property (object_class, PROP_LOADED,
177 g_param_spec_ulong ("loaded", "loaded", "bytes already loaded",
178 0, G_MAXULONG, 0, G_PARAM_READWRITE));
179 g_object_class_install_property (object_class, PROP_URL,
180 g_param_spec_boxed ("url", "url", "URL for this file",
181 SWFDEC_TYPE_URL, G_PARAM_READABLE));
183 stream_class->describe = swfdec_loader_describe;
186 static void
187 swfdec_loader_init (SwfdecLoader *loader)
189 loader->data_type = SWFDEC_LOADER_DATA_UNKNOWN;
191 loader->size = -1;
194 /** PUBLIC API ***/
197 * swfdec_loader_set_url:
198 * @loader: the loader to update
199 * @url: string specifying the new URL. The url must be a valid absolute URL.
201 * Updates the url of the given @loader to point to the new @url. This is useful
202 * whe encountering HTTP redirects, as the loader is supposed to reference the
203 * final URL after all rdirections.
204 * This function may only be called once and must have been called before
205 * calling swfdec_stream_open() on @loader.
207 void
208 swfdec_loader_set_url (SwfdecLoader *loader, const char *url)
210 SwfdecURL *real;
212 g_return_if_fail (SWFDEC_IS_LOADER (loader));
213 g_return_if_fail (loader->url == NULL);
214 g_return_if_fail (url != NULL);
216 real = swfdec_url_new (url);
217 g_return_if_fail (real != NULL);
218 loader->url = real;
222 * swfdec_loader_get_url:
223 * @loader: a #SwfdecLoader
225 * Gets the url this loader is handling. This is mostly useful for writing
226 * subclasses of #SwfdecLoader.
228 * Returns: a #SwfdecURL describing @loader or %NULL if the @url is not known
229 * yet.
231 const SwfdecURL *
232 swfdec_loader_get_url (SwfdecLoader *loader)
234 g_return_val_if_fail (SWFDEC_IS_LOADER (loader), NULL);
236 return loader->url;
240 * swfdec_loader_get_data_type:
241 * @loader: a #SwfdecLoader
243 * Queries the type of data this loader provides. The type is determined
244 * automatically by Swfdec.
246 * Returns: the type this data was identified to be in or
247 * #SWFDEC_LOADER_DATA_UNKNOWN if not identified
249 SwfdecLoaderDataType
250 swfdec_loader_get_data_type (SwfdecLoader *loader)
252 g_return_val_if_fail (SWFDEC_IS_LOADER (loader), SWFDEC_LOADER_DATA_UNKNOWN);
254 return loader->data_type;
257 void
258 swfdec_loader_set_data_type (SwfdecLoader *loader, SwfdecLoaderDataType type)
260 g_return_if_fail (SWFDEC_IS_LOADER (loader));
261 g_return_if_fail (loader->data_type == SWFDEC_LOADER_DATA_UNKNOWN);
262 g_return_if_fail (type != SWFDEC_LOADER_DATA_UNKNOWN);
264 loader->data_type = type;
265 g_object_notify (G_OBJECT (loader), "data-type");
269 * swfdec_loader_set_size:
270 * @loader: a #SwfdecLoader
271 * @size: the amount of bytes in this loader
273 * Sets the size of bytes in this loader. This function may only be called once.
275 void
276 swfdec_loader_set_size (SwfdecLoader *loader, gulong size)
278 g_return_if_fail (SWFDEC_IS_LOADER (loader));
279 g_return_if_fail (loader->size == -1);
280 g_return_if_fail (size <= G_MAXLONG);
282 loader->size = size;
283 g_object_notify (G_OBJECT (loader), "size");
287 * swfdec_loader_get_size:
288 * @loader: a #SwfdecLoader
290 * Queries the amount of bytes inside @loader. If the size is unknown, -1 is
291 * returned. Otherwise the number is greater or equal to 0.
293 * Returns: the total number of bytes for this loader or -1 if unknown
295 glong
296 swfdec_loader_get_size (SwfdecLoader *loader)
298 g_return_val_if_fail (SWFDEC_IS_LOADER (loader), -1);
300 return loader->size;
304 * swfdec_loader_get_loaded:
305 * @loader: a #SwfdecLoader
307 * Gets the amount of bytes that have already been pushed into @loader and are
308 * available to Swfdec.
310 * Returns: Amount of bytes in @loader
312 gulong
313 swfdec_loader_get_loaded (SwfdecLoader *loader)
315 SwfdecBufferQueue *queue;
317 g_return_val_if_fail (SWFDEC_IS_LOADER (loader), 0);
319 queue = swfdec_stream_get_queue (SWFDEC_STREAM (loader));
320 return swfdec_buffer_queue_get_depth (queue) +
321 swfdec_buffer_queue_get_offset (queue);
325 * swfdec_loader_data_type_get_extension:
326 * @type: a #SwfdecLoaderDataType
328 * Queries the extension to be used for data of the given @type.
330 * Returns: the typical extension for this data type or the empty string
331 * if the type has no extension
333 const char *
334 swfdec_loader_data_type_get_extension (SwfdecLoaderDataType type)
336 switch (type) {
337 case SWFDEC_LOADER_DATA_UNKNOWN:
338 return "";
339 case SWFDEC_LOADER_DATA_SWF:
340 return "swf";
341 case SWFDEC_LOADER_DATA_FLV:
342 return "flv";
343 case SWFDEC_LOADER_DATA_XML:
344 return "xml";
345 case SWFDEC_LOADER_DATA_TEXT:
346 return "txt";
347 case SWFDEC_LOADER_DATA_JPEG:
348 return "jpg";
349 case SWFDEC_LOADER_DATA_PNG:
350 return "png";
351 default:
352 g_warning ("unknown data type %u", type);
353 return "";