📄 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. *//*** SwfdecLoader ***/enum { PROP_0, PROP_ERROR, PROP_EOF, PROP_DATA_TYPE, PROP_SIZE, PROP_LOADED};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->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; 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_EOF: if (g_value_get_boolean (value) && !loader->eof) swfdec_loader_eof (loader); 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; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; }}static voidswfdec_loader_dispose (GObject *object){ SwfdecLoader *loader = SWFDEC_LOADER (object); swfdec_buffer_queue_free (loader->queue); g_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_SIZE, g_param_spec_ulong ("loaded", "loaded", "bytes already loaded", 0, G_MAXULONG, 0, G_PARAM_READWRITE));}static voidswfdec_loader_init (SwfdecLoader *loader){ loader->queue = swfdec_buffer_queue_new (); loader->data_type = SWFDEC_LOADER_DATA_UNKNOWN;}/*** SwfdecFileLoader ***/typedef struct _SwfdecFileLoader SwfdecFileLoader;typedef struct _SwfdecFileLoaderClass SwfdecFileLoaderClass;#define SWFDEC_TYPE_FILE_LOADER (swfdec_file_loader_get_type())#define SWFDEC_IS_FILE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_FILE_LOADER))#define SWFDEC_IS_FILE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_FILE_LOADER))#define SWFDEC_FILE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_FILE_LOADER, SwfdecFileLoader))#define SWFDEC_FILE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_FILE_LOADER, SwfdecFileLoaderClass))#define SWFDEC_FILE_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_FILE_LOADER, SwfdecFileLoaderClass))struct _SwfdecFileLoader{ SwfdecLoader loader; char * dir; /* base directory for load operations */};struct _SwfdecFileLoaderClass{ SwfdecLoaderClass loader_class;};G_DEFINE_TYPE (SwfdecFileLoader, swfdec_file_loader, SWFDEC_TYPE_LOADER)static voidswfdec_file_loader_dispose (GObject *object){ SwfdecFileLoader *file_loader = SWFDEC_FILE_LOADER (object); g_free (file_loader->dir); G_OBJECT_CLASS (swfdec_file_loader_parent_class)->dispose (object);}static SwfdecLoader *swfdec_file_loader_load (SwfdecLoader *loader, const char *url){ SwfdecBuffer *buffer; char *real_path; SwfdecLoader *ret; GError *error = NULL; if (g_path_is_absolute (url)) { SWFDEC_ERROR ("\"%s\" is an absolute path - using relative instead", url); while (*url == G_DIR_SEPARATOR) url++; } /* FIXME: need to rework seperators on windows? */ real_path = g_build_filename (SWFDEC_FILE_LOADER (loader)->dir, url, NULL); buffer = swfdec_buffer_new_from_file (real_path, &error); ret = g_object_new (SWFDEC_TYPE_FILE_LOADER, NULL); ret->url = real_path; SWFDEC_FILE_LOADER (ret)->dir = g_strdup (SWFDEC_FILE_LOADER (loader)->dir); if (buffer == NULL) { swfdec_loader_error (ret, error->message); g_error_free (error); } else { swfdec_loader_set_size (ret, buffer->length); swfdec_loader_push (ret, buffer); swfdec_loader_eof (ret); } return ret;}static voidswfdec_file_loader_class_init (SwfdecFileLoaderClass *klass){ GObjectClass *object_class = G_OBJECT_CLASS (klass); SwfdecLoaderClass *loader_class = SWFDEC_LOADER_CLASS (klass); object_class->dispose = swfdec_file_loader_dispose; loader_class->load = swfdec_file_loader_load;}static voidswfdec_file_loader_init (SwfdecFileLoader *loader){}/*** INTERNAL API ***/SwfdecLoader *swfdec_loader_load (SwfdecLoader *loader, const char *url){ SwfdecLoader *ret; SwfdecLoaderClass *klass; g_return_val_if_fail (SWFDEC_IS_LOADER (loader), NULL); g_return_val_if_fail (url != NULL, NULL); klass = SWFDEC_LOADER_GET_CLASS (loader); g_return_val_if_fail (klass->load != NULL, NULL); ret = klass->load (loader, url); g_assert (ret != NULL); return ret;}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)); loader->target = target;}static voidswfdec_loader_do_parse (gpointer empty, gpointer loaderp){ SwfdecLoader *loader = SWFDEC_LOADER (loaderp); swfdec_loader_target_parse (loader->target, loader);}voidswfdec_loader_queue_parse (SwfdecLoader *loader){ SwfdecPlayer *player; g_return_if_fail (SWFDEC_IS_LOADER (loader)); g_return_if_fail (loader->target != NULL); player = swfdec_loader_target_get_player (loader->target); /* HACK: using player as action object makes them get auto-removed */ swfdec_player_add_action (player, player, swfdec_loader_do_parse, loader);}/** PUBLIC API ***//** * swfdec_loader_new_from_file: * @filename: name of the file to load * @error: return loacation for an error or NULL * * Creates a new loader for local files. * * Returns: a new loader on success or NULL on failure **/SwfdecLoader *swfdec_loader_new_from_file (const char *filename, GError ** error){ SwfdecBuffer *buf; SwfdecLoader *loader; g_return_val_if_fail (filename != NULL, NULL); buf = swfdec_buffer_new_from_file (filename, error); if (buf == NULL) return NULL; loader = g_object_new (SWFDEC_TYPE_FILE_LOADER, NULL); if (g_path_is_absolute (filename)) { loader->url = g_strdup (filename); } else { char *cur = g_get_current_dir (); loader->url = g_build_filename (cur, filename, NULL); g_free (cur); } SWFDEC_FILE_LOADER (loader)->dir = g_path_get_dirname (loader->url); swfdec_loader_set_size (loader, buf->length); swfdec_loader_push (loader, buf); swfdec_loader_eof (loader); return loader;}/** * 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){ SwfdecPlayer *player; 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; } if (loader->target) { player = swfdec_loader_target_get_player (loader->target); swfdec_player_lock (player); swfdec_loader_error_locked (loader, error); swfdec_player_perform_actions (player); swfdec_player_unlock (player); } else { swfdec_loader_error_locked (loader, error); }}voidswfdec_loader_error_locked (SwfdecLoader *loader, const char *error)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -