📄 swfdec_loader.c
字号:
/* Swfdec * Copyright (C) 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include "swfdec_loader_internal.h"#include "swfdec_buffer.h"#include "swfdec_debug.h"#include "swfdec_loadertarget.h"#include "swfdec_player_internal.h"/*** gtk-doc ***//** * SECTION:SwfdecLoader * @title: SwfdecLoader * @short_description: object used for input * * SwfdecLoader is the base class used for input. Since developers normally * need to adapt input to the needs of their application, this class is * provided to be adapted to their needs. * * Since Flash files can load new resources while operating, a #SwfdecLoader * can be instructed to load another resource. It's the loader's responsibility * to make sure the player is allowed to access the resource and provide its * data. * * For convenience, a #SwfdecLoader for file access is provided by Swfdec. *//** * SwfdecLoader: * * This is the base class used for providing input. It is abstract, use a * subclass to provide your input. *//** * SwfdecLoaderDataType: * @SWFDEC_LOADER_DATA_UNKNOWN: Unidentified data or data that cannot be * identified. * @SWFDEC_LOADER_DATA_SWF: Data describing a normal Flash file. * @SWFDEC_LOADER_DATA_FLV: Data describing a Flash video stream. * @SWFDEC_LOADER_DATA_XML: Data in XML format. * @SWFDEC_LOADER_DATA_TEXT: Textual data. * * This type describes the different types of data that can be loaded inside * Swfdec. Swfdec identifies its data streams and you can use the * swfdec_loader_get_data_type() to acquire more information about the data * inside a #SwfdecLoader. *//** * SwfdecLoaderRequest: * @SWFDEC_LOADER_REQUEST_DEFAULT: Use the default method (this most likely is * equal to HTTPget) * @SWFDEC_LOADER_REQUEST_GET: Use HTTP get * @SWFDEC_LOADER_REQUEST_POST: Use HTTP post * * Describes the moethod to use for requesting a given URL. These methods map * naturally to HTTP methods, since HTTP is the common method for requesting * Flash content. *//*** SwfdecLoader ***/enum { PROP_0, PROP_ERROR, PROP_EOF, PROP_DATA_TYPE, PROP_SIZE, PROP_LOADED, PROP_URL};G_DEFINE_ABSTRACT_TYPE (SwfdecLoader, swfdec_loader, G_TYPE_OBJECT)static voidswfdec_loader_get_property (GObject *object, guint param_id, GValue *value, GParamSpec * pspec){ SwfdecLoader *loader = SWFDEC_LOADER (object); switch (param_id) { case PROP_ERROR: g_value_set_string (value, loader->error); break; case PROP_EOF: g_value_set_boolean (value, loader->state == SWFDEC_LOADER_STATE_EOF); break; case PROP_DATA_TYPE: g_value_set_enum (value, loader->data_type); break; case PROP_SIZE: g_value_set_ulong (value, loader->size); break; case PROP_LOADED: g_value_set_ulong (value, swfdec_loader_get_loaded (loader)); break; case PROP_URL: g_value_set_boxed (value, loader->url); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; }}static voidswfdec_loader_set_property (GObject *object, guint param_id, const GValue *value, GParamSpec *pspec){ SwfdecLoader *loader = SWFDEC_LOADER (object); switch (param_id) { case PROP_ERROR: swfdec_loader_error (loader, g_value_get_string (value)); break; case PROP_SIZE: if (loader->size == 0 && g_value_get_ulong (value) > 0) swfdec_loader_set_size (loader, g_value_get_ulong (value)); break; case PROP_URL: loader->url = g_value_dup_boxed (value); if (loader->url == NULL) { g_warning ("must set a valid URL"); loader->url = swfdec_url_new (""); } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; }}static voidswfdec_loader_dispose (GObject *object){ SwfdecLoader *loader = SWFDEC_LOADER (object); /* targets are supposed to keep a reference around */ g_assert (loader->target == NULL); swfdec_buffer_queue_unref (loader->queue); swfdec_url_free (loader->url); g_free (loader->error); G_OBJECT_CLASS (swfdec_loader_parent_class)->dispose (object);}static voidswfdec_loader_class_init (SwfdecLoaderClass *klass){ GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->dispose = swfdec_loader_dispose; object_class->get_property = swfdec_loader_get_property; object_class->set_property = swfdec_loader_set_property; g_object_class_install_property (object_class, PROP_ERROR, g_param_spec_string ("error", "error", "NULL when no error or string describing error", NULL, G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_EOF, g_param_spec_boolean ("eof", "eof", "TRUE when all data has been handed to the loader", FALSE, G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_DATA_TYPE, g_param_spec_enum ("data-type", "data type", "the data's type as identified by Swfdec", SWFDEC_TYPE_LOADER_DATA_TYPE, SWFDEC_LOADER_DATA_UNKNOWN, G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_SIZE, g_param_spec_ulong ("size", "size", "amount of bytes in loader", 0, G_MAXULONG, 0, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_LOADED, g_param_spec_ulong ("loaded", "loaded", "bytes already loaded", 0, G_MAXULONG, 0, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_URL, g_param_spec_boxed ("url", "url", "URL for this file", SWFDEC_TYPE_URL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));}static voidswfdec_loader_init (SwfdecLoader *loader){ loader->queue = swfdec_buffer_queue_new (); loader->data_type = SWFDEC_LOADER_DATA_UNKNOWN;}/*** INTERNAL API ***/static voidswfdec_loader_perform_open (gpointer loaderp, gpointer unused){ SwfdecLoader *loader = loaderp; swfdec_loader_target_open (loader->target, loader);}static voidswfdec_loader_perform_eof (gpointer loaderp, gpointer unused){ SwfdecLoader *loader = loaderp; swfdec_loader_target_eof (loader->target, loader);}static voidswfdec_loader_perform_error (gpointer loaderp, gpointer unused){ SwfdecLoader *loader = loaderp; swfdec_loader_target_error (loader->target, loader);}static voidswfdec_loader_perform_push (gpointer loaderp, gpointer unused){ SwfdecLoader *loader = loaderp; swfdec_loader_target_parse (loader->target, loader);}SwfdecLoader *swfdec_loader_load (SwfdecLoader *loader, const char *url_string, SwfdecLoaderRequest request, const char *data, gsize data_len){ SwfdecLoader *ret; SwfdecLoaderClass *klass; SwfdecURL *url; g_return_val_if_fail (SWFDEC_IS_LOADER (loader), NULL); g_return_val_if_fail (url_string != NULL, NULL); g_return_val_if_fail (data != NULL || data_len == 0, NULL); klass = SWFDEC_LOADER_GET_CLASS (loader); g_return_val_if_fail (klass->load != NULL, NULL); url = swfdec_url_new_relative (loader->url, url_string); ret = g_object_new (G_OBJECT_CLASS_TYPE (klass), "url", url, NULL); swfdec_url_free (url); klass->load (ret, loader, request, data, data_len); return ret;}voidswfdec_loader_close (SwfdecLoader *loader){ SwfdecLoaderClass *klass; g_return_if_fail (SWFDEC_IS_LOADER (loader)); klass = SWFDEC_LOADER_GET_CLASS (loader); if (klass->close) klass->close (loader); if (loader->state != SWFDEC_LOADER_STATE_ERROR) loader->state = SWFDEC_LOADER_STATE_CLOSED;}voidswfdec_loader_set_target (SwfdecLoader *loader, SwfdecLoaderTarget *target){ g_return_if_fail (SWFDEC_IS_LOADER (loader)); g_return_if_fail (target == NULL || SWFDEC_IS_LOADER_TARGET (target)); if (loader->target) { swfdec_player_remove_all_external_actions (loader->player, loader); } loader->target = target; if (target) { loader->player = swfdec_loader_target_get_player (target); switch (loader->state) { case SWFDEC_LOADER_STATE_NEW: break; case SWFDEC_LOADER_STATE_OPEN: swfdec_player_add_external_action (loader->player, loader, swfdec_loader_perform_open, NULL); break; case SWFDEC_LOADER_STATE_READING: swfdec_player_add_external_action (loader->player, loader, swfdec_loader_perform_open, NULL); swfdec_player_add_external_action (loader->player, loader, swfdec_loader_perform_push, NULL); break; case SWFDEC_LOADER_STATE_EOF: swfdec_player_add_external_action (loader->player, loader, swfdec_loader_perform_open, NULL); swfdec_player_add_external_action (loader->player, loader, swfdec_loader_perform_push, NULL); swfdec_player_add_external_action (loader->player, loader, swfdec_loader_perform_eof, NULL); break; case SWFDEC_LOADER_STATE_ERROR: swfdec_player_add_external_action (loader->player, loader, swfdec_loader_perform_error, NULL); break; default: g_assert_not_reached (); break; } } else { loader->player = NULL; }}/** PUBLIC API ***//** * swfdec_loader_error: * @loader: a #SwfdecLoader * @error: a string describing the error * * Moves the loader in the error state if it wasn't before. A loader that is in * the error state will not process any more data. Also, internal error * handling scripts may be executed. **/voidswfdec_loader_error (SwfdecLoader *loader, const char *error){ g_return_if_fail (SWFDEC_IS_LOADER (loader)); g_return_if_fail (error != NULL); if (loader->error) { SWFDEC_ERROR ("another error in loader %p: %s", loader, error); return; } SWFDEC_ERROR ("error in loader %p: %s", loader, error); loader->state = SWFDEC_LOADER_STATE_ERROR; loader->error = g_strdup (error); if (loader->target) swfdec_player_add_external_action (loader->player, loader, swfdec_loader_perform_error, NULL);}/** * swfdec_loader_open: * @loader: a #SwfdecLoader * @url: the real URL used for this loader if it has changed (e.g. after HTTP * redirects) or %NULL if it hasn't changed * * Call this function when your loader opened the resulting file. For HTTP this * is when having received the headers. You must call this function before * swfdec_laoder_push() can be called. **/voidswfdec_loader_open (SwfdecLoader *loader, const char *url){ g_return_if_fail (SWFDEC_IS_LOADER (loader)); g_return_if_fail (loader->state == SWFDEC_LOADER_STATE_NEW); loader->state = SWFDEC_LOADER_STATE_OPEN; if (url) { swfdec_url_free (loader->url); loader->url = swfdec_url_new (url); g_object_notify (G_OBJECT (loader), "url"); } if (loader->player) swfdec_player_add_external_action (loader->player, loader, swfdec_loader_perform_open, NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -