⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swfdec_as_object.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Swfdec * Copyright (C) 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 <strings.h>#include "swfdec_as_object.h"#include "swfdec_as_context.h"#include "swfdec_as_frame_internal.h"#include "swfdec_as_internal.h"#include "swfdec_as_native_function.h"#include "swfdec_as_stack.h"#include "swfdec_as_strings.h"#include "swfdec_debug.h"#include "swfdec_movie.h"/** * SECTION:SwfdecAsObject * @title: SwfdecAsObject * @short_description: the base object type for scriptable objects * * This is the basic object type in Swfdec. Every object used by the script  * engine must be a #SwfdecAsObject. It handles memory management and assigning * variables to it. Almost all functions that are called on objects require that * the objects have been added to the garbage collector previously. For  * custom-created objects, you need to do this using swfdec_as_object_add(),  * built-in functions that create objects do this manually. * * Note that you cannot know the lifetime of a #SwfdecAsObject, since scripts  * may assign it as a variable to other objects. So you should not assume to  * know when an object gets removed. *//** * SwfdecAsObject: * * Every object value inside the Swfdec script engine must be a SwfdecAsObject. * If you want to add custom objects to your script engine, you need to create a * subclass. The class provides a number of virtual functions that you can  * override to achieve the desired behaviour. *//** * SwfdecAsVariableFlag: * @SWFDEC_AS_VARIABLE_HIDDEN: Do not include variable in enumerations and *                                swfdec_as_object_foreach(). * @SWFDEC_AS_VARIABLE_PERMANENT: Do not all swfdec_as_object_delete_variable() *                                to delete this variable. * @SWFDEC_AS_VARIABLE_CONSTANT: Do not allow changing the value with *                               swfdec_as_object_set_variable(). * @SWFDEC_AS_VARIABLE_VERSION_6_UP: This symbol is only visible in version 6  *                                   and above. * @SWFDEC_AS_VARIABLE_VERSION_NOT_6: This symbols is visible in all versions  *                                    but version 6. * @SWFDEC_AS_VARIABLE_VERSION_7_UP: This symbol is only visible in version 7  *                                   and above. * @SWFDEC_AS_VARIABLE_VERSION_8_UP: This symbol is only visible in version 8  *                                   and above. * * These flags are used to describe various properties of a variable inside * Swfdec. You can manually set them with swfdec_as_object_set_variable_flags(). *//** * SwfdecAsDeleteReturn: * @SWFDEC_AS_DELETE_NOT_FOUND: The variable was not found and therefore  *                              couldn't be deleted. * @SWFDEC_AS_DELETE_DELETED: The variable was deleted. * @SWFDEC_AS_DELETE_NOT_DELETED: The variable was found but could not be  *                                deleted. * * This is the return value used by swfdec_as_object_delete_variable(). It  * describes the various outcomes of trying to delete a variable. *//** * SwfdecAsVariableForeach: * @object: The object this function is run on * @variable: garbage-collected name of the current variables * @value: value of the current variable * @flags: Flags associated with the current variable * @data: User dta passed to swfdec_as_object_foreach() * * Function prototype for the swfdec_as_object_foreach() function. * * Returns: %TRUE to continue running the foreach function, %FALSE to stop */typedef struct _SwfdecAsVariable SwfdecAsVariable;struct _SwfdecAsVariable {  guint			flags;		/* SwfdecAsVariableFlag values */  SwfdecAsValue     	value;		/* value of property */  SwfdecAsFunction *	get;		/* getter set with swfdec_as_object_add_property */  SwfdecAsFunction *	set;		/* setter or %NULL */};G_DEFINE_TYPE (SwfdecAsObject, swfdec_as_object, G_TYPE_OBJECT)static voidswfdec_as_object_dispose (GObject *gobject){  SwfdecAsObject *object = SWFDEC_AS_OBJECT (gobject);  g_assert (object->properties == NULL);  G_OBJECT_CLASS (swfdec_as_object_parent_class)->dispose (gobject);}static voidswfdec_as_object_mark_property (gpointer key, gpointer value, gpointer unused){  SwfdecAsVariable *var = value;  swfdec_as_string_mark (key);  if (var->get) {    swfdec_as_object_mark (SWFDEC_AS_OBJECT (var->get));    if (var->set)      swfdec_as_object_mark (SWFDEC_AS_OBJECT (var->set));  } else {    swfdec_as_value_mark (&var->value);  }}static voidswfdec_as_object_do_mark (SwfdecAsObject *object){  if (object->prototype)    swfdec_as_object_mark (object->prototype);  g_hash_table_foreach (object->properties, swfdec_as_object_mark_property, NULL);}static voidswfdec_as_object_do_add (SwfdecAsObject *object){}static gbooleanswfdec_as_object_lookup_case_insensitive (gpointer key, gpointer value, gpointer user_data){  return strcasecmp (key, user_data) == 0;}static gbooleanswfdec_as_variable_name_is_valid (const char *name){  return name != SWFDEC_AS_STR_EMPTY;}static inline SwfdecAsVariable *swfdec_as_object_hash_lookup (SwfdecAsObject *object, const char *variable){  SwfdecAsVariable *var = g_hash_table_lookup (object->properties, variable);  if (var || object->context->version >= 7)    return var;  var = g_hash_table_find (object->properties, swfdec_as_object_lookup_case_insensitive, (gpointer) variable);  return var;}static inline SwfdecAsVariable *swfdec_as_object_hash_create (SwfdecAsObject *object, const char *variable, guint flags){  SwfdecAsVariable *var;  if (!swfdec_as_context_use_mem (object->context, sizeof (SwfdecAsVariable)))    return NULL;  if (!swfdec_as_variable_name_is_valid (variable))    return NULL;  var = g_slice_new0 (SwfdecAsVariable);  var->flags = flags;  g_hash_table_insert (object->properties, (gpointer) variable, var);  return var;}static gbooleanswfdec_as_object_do_get (SwfdecAsObject *object, SwfdecAsObject *orig,    const char *variable, SwfdecAsValue *val, guint *flags){  SwfdecAsVariable *var = swfdec_as_object_hash_lookup (object, variable);  if (var == NULL)    return FALSE;  /* variable flag checks */  if (var->flags & SWFDEC_AS_VARIABLE_VERSION_6_UP && object->context->version < 6)    return FALSE;  if (var->flags & SWFDEC_AS_VARIABLE_VERSION_NOT_6 && object->context->version == 6)    return FALSE;  if (var->flags & SWFDEC_AS_VARIABLE_VERSION_7_UP && object->context->version < 7)    return FALSE;  if (var->flags & SWFDEC_AS_VARIABLE_VERSION_8_UP && object->context->version < 8)    return FALSE;  if (var->get) {    swfdec_as_function_call (var->get, orig, 0, NULL, val);    swfdec_as_context_run (object->context);    *flags = var->flags;  } else {    *val = var->value;    *flags = var->flags;  }  return TRUE;}static voidswfdec_as_object_do_set (SwfdecAsObject *object, const char *variable,     const SwfdecAsValue *val, guint flags){  SwfdecAsVariable *var;  if (!swfdec_as_variable_name_is_valid (variable))    return;  if (variable == SWFDEC_AS_STR___proto__) {    if (SWFDEC_AS_VALUE_IS_OBJECT (val) &&	!SWFDEC_IS_MOVIE (SWFDEC_AS_VALUE_GET_OBJECT (val))) {      object->prototype = SWFDEC_AS_VALUE_GET_OBJECT (val);    } else {      object->prototype = NULL;    }  }  var = swfdec_as_object_hash_lookup (object, variable);  if (var == NULL) {    guint i;    SwfdecAsObject *proto = object->prototype;    for (i = 0; i < 256 && proto; i++) {      var = swfdec_as_object_hash_lookup (proto, variable);      if (var && var->get)	break;      proto = proto->prototype;      var = NULL;    }    if (i == 256) {      swfdec_as_context_abort (object->context, "Prototype recursion limit exceeded");      return;    }  }  if (var == NULL) {    var = swfdec_as_object_hash_create (object, variable, flags);    if (var == NULL)      return;  } else {    if (var->flags & SWFDEC_AS_VARIABLE_CONSTANT)      return;  }  if (var->get) {    if (var->set) {      SwfdecAsValue tmp;      swfdec_as_function_call (var->set, object, 1, val, &tmp);      swfdec_as_context_run (object->context);    }  } else {     var->value = *val;  }}static voidswfdec_as_object_do_set_flags (SwfdecAsObject *object, const char *variable, guint flags, guint mask){  SwfdecAsVariable *var = swfdec_as_object_hash_lookup (object, variable);  if (var)    var->flags = (var->flags & ~mask) | flags;}static voidswfdec_as_object_free_property (gpointer key, gpointer value, gpointer data){  SwfdecAsObject *object = data;  swfdec_as_context_unuse_mem (object->context, sizeof (SwfdecAsVariable));  g_slice_free (SwfdecAsVariable, value);}static SwfdecAsDeleteReturnswfdec_as_object_do_delete (SwfdecAsObject *object, const char *variable){  SwfdecAsVariable *var;  var = g_hash_table_lookup (object->properties, variable);  if (var == NULL)    return SWFDEC_AS_DELETE_NOT_FOUND;  if (var->flags & SWFDEC_AS_VARIABLE_PERMANENT)    return SWFDEC_AS_DELETE_NOT_DELETED;  swfdec_as_object_free_property (NULL, var, object);  if (!g_hash_table_remove (object->properties, variable)) {    g_assert_not_reached ();  }  return SWFDEC_AS_DELETE_DELETED;}typedef struct {  SwfdecAsObject *		object;  SwfdecAsVariableForeach	func;  gpointer			data;  gboolean			retval;} ForeachData;static voidswfdec_as_object_hash_foreach (gpointer key, gpointer value, gpointer data){  ForeachData *fdata = data;  SwfdecAsVariable *var = value;  if (!fdata->retval)    return;  fdata->retval = fdata->func (fdata->object, key, &var->value, var->flags, fdata->data);}/* FIXME: does not do Adobe Flash's order for Enumerate actions */static gbooleanswfdec_as_object_do_foreach (SwfdecAsObject *object, SwfdecAsVariableForeach func, gpointer data){  ForeachData fdata = { object, func, data, TRUE };  g_hash_table_foreach (object->properties, swfdec_as_object_hash_foreach, &fdata);  return fdata.retval;}typedef struct {  SwfdecAsObject *		object;  SwfdecAsVariableForeachRemove	func;  gpointer			data;} ForeachRemoveData;static gbooleanswfdec_as_object_hash_foreach_remove (gpointer key, gpointer value, gpointer data){  ForeachRemoveData *fdata = data;  SwfdecAsVariable *var = value;  if (!fdata->func (fdata->object, key, &var->value, var->flags, fdata->data))    return FALSE;  swfdec_as_object_free_property (NULL, var, fdata->object);  return TRUE;}/** * swfdec_as_object_foreach_remove: * @object: a #SwfdecAsObject * @func: function that determines which object to remove * @data: data to pass to @func * * Removes all variables form @object where @func returns %TRUE. This is an  * internal function for array operations. * * Returns: he number of variables removed **/guintswfdec_as_object_foreach_remove (SwfdecAsObject *object, SwfdecAsVariableForeach func,    gpointer data){  ForeachRemoveData fdata = { object, func, data };  g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), 0);  g_return_val_if_fail (func != NULL, 0);  return g_hash_table_foreach_remove (object->properties,      swfdec_as_object_hash_foreach_remove, &fdata);}typedef struct {  SwfdecAsObject *		object;  GHashTable *			properties_new;  SwfdecAsVariableForeachRename	func;  gpointer			data;} ForeachRenameData;static gbooleanswfdec_as_object_hash_foreach_rename (gpointer key, gpointer value, gpointer data){  ForeachRenameData *fdata = data;  SwfdecAsVariable *var = value;  const char *key_new;  key_new = fdata->func (fdata->object, key, &var->value, var->flags, fdata->data);  if (key_new) {    g_hash_table_insert (fdata->properties_new, (gpointer) key_new, var);  } else {    swfdec_as_object_free_property (NULL, var, fdata->object);  }  return TRUE;}/** * swfdec_as_object_foreach_rename: * @object: a #SwfdecAsObject * @func: function determining the new name

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -