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

📄 swfdec_as_array.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> *		 2007 Pekka Lampila <pekka.lampila@iki.fi> * * 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 <stdlib.h>#include <string.h>#include "swfdec_as_array.h"#include "swfdec_as_context.h"#include "swfdec_as_frame_internal.h"#include "swfdec_as_function.h"#include "swfdec_as_internal.h"#include "swfdec_as_native_function.h"#include "swfdec_as_strings.h"#include "swfdec_debug.h"#include "swfdec_player_internal.h"G_DEFINE_TYPE (SwfdecAsArray, swfdec_as_array, SWFDEC_TYPE_AS_OBJECT)/** * SECTION:SwfdecAsArray * @title: SwfdecAsArray * @short_description: the array object * * The array object provides some convenience functions for creating and * modifying arrays. *//** * SwfdecAsArray * * This is the type of the array object. *//* * Internal helper functions *//* NB: type is important for overflow */static inline gint32swfdec_as_array_to_index (const char *str){  char *end;  gulong l;  g_return_val_if_fail (str != NULL, -1);  l = strtoul (str, &end, 10);  if (*end != 0 || l > G_MAXINT32)    return -1;  return l;}static gint32swfdec_as_array_get_length_as_integer (SwfdecAsObject *object){  SwfdecAsValue val;  gint32 length;  g_return_val_if_fail (object != NULL, 0);  swfdec_as_object_get_variable (object, SWFDEC_AS_STR_length, &val);  length = swfdec_as_value_to_integer (object->context, &val);  return length;}static gint32swfdec_as_array_get_length (SwfdecAsObject *object){  gint32 length;  length = swfdec_as_array_get_length_as_integer (object);  if (length < 0)    return 0;  return length;}static voidswfdec_as_array_set_length (SwfdecAsObject *object, gint32 length){  SwfdecAsValue val;  g_return_if_fail (object != NULL);  SWFDEC_AS_VALUE_SET_INT (&val, length);  swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR_length, &val,      SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);}typedef struct {  gint32	start_index;  gint32	num;} ForeachRemoveRangeData;static gbooleanswfdec_as_array_foreach_remove_range (SwfdecAsObject *object,    const char *variable, SwfdecAsValue *value, guint flags, gpointer data){  ForeachRemoveRangeData *fdata = data;  gint32 idx;  idx = swfdec_as_array_to_index (variable);  if (idx == -1)    return FALSE;  if (idx >= fdata->start_index && idx < fdata->start_index + fdata->num)    return TRUE;  return FALSE;}static voidswfdec_as_array_remove_range (SwfdecAsArray *array, gint32 start_index,    gint32 num){  SwfdecAsObject *object = SWFDEC_AS_OBJECT (array);  g_return_if_fail (SWFDEC_IS_AS_ARRAY (array));  g_return_if_fail (start_index >= 0);  g_return_if_fail (num >= 0);  g_return_if_fail (start_index + num <= swfdec_as_array_get_length (object));  if (num == 0)    return;  // to avoid foreach loop, use special case when removing just one variable  if (num == 1) {    const char *var = swfdec_as_double_to_string (object->context, start_index);    swfdec_as_object_delete_variable (object, var);  } else {    ForeachRemoveRangeData fdata = { start_index, num };    swfdec_as_object_foreach_remove (object,	swfdec_as_array_foreach_remove_range, &fdata);  }}typedef struct {  gint32	start_index;  gint32	num;  gint32	to_index;} ForeachMoveRangeData;static const char *swfdec_as_array_foreach_move_range (SwfdecAsObject *object,    const char *variable, SwfdecAsValue *value, guint flags, gpointer data){  ForeachMoveRangeData *fdata = data;  gint32 idx;  idx = swfdec_as_array_to_index (variable);  if (idx == -1)    return variable;  if (idx >= fdata->start_index && idx < fdata->start_index + fdata->num) {    return swfdec_as_double_to_string (object->context,	fdata->to_index + idx - fdata->start_index);  } else if (idx >= fdata->to_index && idx < fdata->to_index + fdata->num) {    return NULL;  } else {    return variable;  }}static voidswfdec_as_array_move_range (SwfdecAsObject *object, gint32 from_index,    gint32 num, gint32 to_index){  ForeachMoveRangeData fdata = { from_index, num, to_index };  g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));  g_return_if_fail (from_index >= 0);  g_return_if_fail (num >= 0);  g_return_if_fail (from_index + num <= swfdec_as_array_get_length (object));  g_return_if_fail (to_index >= 0);  if (num == 0 || from_index == to_index)    return;  swfdec_as_object_foreach_rename (object, swfdec_as_array_foreach_move_range,      &fdata);  // only changes length if it becomes bigger, not if it becomes smaller  if (to_index + num > swfdec_as_array_get_length (object))    swfdec_as_array_set_length (object, to_index + num);}static voidswfdec_as_array_set_range (SwfdecAsObject *object, gint32 start_index,    gint32 num, const SwfdecAsValue *value){  gint32 i;  const char *var;  // allow negative indexes  g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));  g_return_if_fail (num >= 0);  g_return_if_fail (value != NULL);  for (i = 0; i < num; i++) {    var = swfdec_as_double_to_string (object->context, start_index + i);    swfdec_as_object_set_variable (object, var, &value[i]);  }}static voidswfdec_as_array_append_internal (SwfdecAsObject *object, guint n,    const SwfdecAsValue *value){  // allow negative length  swfdec_as_array_set_range (object,      swfdec_as_array_get_length_as_integer (object), n, value);}/** * swfdec_as_array_push: * @array: a #SwfdecAsArray * @value: the value to add * * Adds the given value to the array. This a macro that just calls * swfdec_as_array_append(). *//** * swfdec_as_array_append: * @array: a #SwfdecAsArray * @n: number of values to add * @values: the values to add * * Appends the given @values to the array. **/voidswfdec_as_array_append (SwfdecAsArray *array, guint n,    const SwfdecAsValue *value){  // don't allow negative length  swfdec_as_array_set_range (SWFDEC_AS_OBJECT (array),      swfdec_as_array_get_length (SWFDEC_AS_OBJECT (array)), n, value);}typedef struct {  SwfdecAsObject		*object_to;  gint32			offset;  gint32			start_index;  gint32			num;} ForeachAppendArrayRangeData;static gbooleanswfdec_as_array_foreach_append_array_range (SwfdecAsObject *object,    const char *variable, SwfdecAsValue *value, guint flags, gpointer data){  ForeachAppendArrayRangeData *fdata = data;  gint32 idx;  const char *var;  idx = swfdec_as_array_to_index (variable);  if (idx >= fdata->start_index && idx < fdata->start_index + fdata->num) {    var = swfdec_as_double_to_string (fdata->object_to->context,	fdata->offset + (idx - fdata->start_index));    swfdec_as_object_set_variable (fdata->object_to, var, value);  }  return TRUE;}static voidswfdec_as_array_append_array_range (SwfdecAsArray *array_to,    SwfdecAsObject *object_from, gint32 start_index, gint32 num){  ForeachAppendArrayRangeData fdata;  g_return_if_fail (SWFDEC_IS_AS_ARRAY (array_to));  g_return_if_fail (SWFDEC_IS_AS_OBJECT (object_from));  g_return_if_fail (start_index >= 0);  g_return_if_fail (      start_index + num <= swfdec_as_array_get_length (object_from));  if (num == 0)    return;  fdata.object_to = SWFDEC_AS_OBJECT (array_to);  fdata.offset = swfdec_as_array_get_length (SWFDEC_AS_OBJECT (array_to));  fdata.start_index = start_index;  fdata.num = num;  swfdec_as_array_set_length (fdata.object_to, fdata.offset + fdata.num);  swfdec_as_object_foreach (object_from,      swfdec_as_array_foreach_append_array_range, &fdata);}static voidswfdec_as_array_append_array (SwfdecAsArray *array_to, SwfdecAsObject *object_from){  swfdec_as_array_append_array_range (array_to, object_from, 0,      swfdec_as_array_get_length (object_from));}/* * Class functions */static voidswfdec_as_array_set (SwfdecAsObject *object, const char *variable,    const SwfdecAsValue *val, guint flags){  char *end;  gboolean indexvar = TRUE;  gint32 l = strtoul (variable, &end, 10);  if (*end != 0 || l > G_MAXINT32)    indexvar = FALSE;  // if we changed to smaller length, destroy all values that are outside it  if (!strcmp (variable, SWFDEC_AS_STR_length)) {    gint32 length_old = swfdec_as_array_get_length (object);    gint32 length_new = MAX (0,	swfdec_as_value_to_integer (object->context, val));    if (length_old > length_new) {      swfdec_as_array_remove_range (SWFDEC_AS_ARRAY (object), length_new,	  length_old - length_new);    }  }  SWFDEC_AS_OBJECT_CLASS (swfdec_as_array_parent_class)->set (object, variable,      val, flags);  // if we added new value outside the current length, set a bigger length  if (indexvar) {    if (++l > swfdec_as_array_get_length_as_integer (object))      swfdec_as_array_set_length (object, l);  }}static voidswfdec_as_array_class_init (SwfdecAsArrayClass *klass){  SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (klass);  asobject_class->set = swfdec_as_array_set;}static voidswfdec_as_array_init (SwfdecAsArray *array){}/* * The rest *//** * swfdec_as_array_new: * @context: a #SwfdecAsContext *

⌨️ 快捷键说明

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