Exemple #1
0
static gboolean
swfdec_rectangle_from_as_object (SwfdecRectangle *rect, SwfdecAsObject *object)
{
  SwfdecAsValue *val;
  SwfdecAsContext *cx = swfdec_gc_object_get_context (object);

  /* FIXME: This function is untested */
  val = swfdec_as_object_peek_variable (object, SWFDEC_AS_STR_x);
  if (val)
    rect->x = swfdec_as_value_to_integer (cx, val);
  else
    rect->x = 0;
  val = swfdec_as_object_peek_variable (object, SWFDEC_AS_STR_y);
  if (val)
    rect->y = swfdec_as_value_to_integer (cx, val);
  else
    rect->y = 0;
  val = swfdec_as_object_peek_variable (object, SWFDEC_AS_STR_width);
  if (val)
    rect->width = swfdec_as_value_to_integer (cx, val);
  else
    rect->width = 0;
  val = swfdec_as_object_peek_variable (object, SWFDEC_AS_STR_height);
  if (val)
    rect->height = swfdec_as_value_to_integer (cx, val);
  else
    rect->height = 0;
  return rect->width > 0 && rect->height > 0;
}
Exemple #2
0
static void
swfdec_point_from_as_object (int *x, int *y, SwfdecAsObject *object)
{
  SwfdecAsValue *val;
  SwfdecAsContext *cx = swfdec_gc_object_get_context (object);

  /* FIXME: This function is untested */
  val = swfdec_as_object_peek_variable (object, SWFDEC_AS_STR_x);
  *x = swfdec_as_value_to_integer (cx, val);
  val = swfdec_as_object_peek_variable (object, SWFDEC_AS_STR_y);
  *y = swfdec_as_value_to_integer (cx, val);
}
Exemple #3
0
void
swfdec_as_array_splice (SwfdecAsContext *cx, SwfdecAsObject *object,
    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
{
  gint32 length, start_index, num_remove, num_add, at_end;
  SwfdecAsArray *array_new;

  if (object == NULL || SWFDEC_IS_MOVIE (object) || argc == 0)
    return;

  length = swfdec_as_array_length (object);

  start_index = swfdec_as_value_to_integer (cx, &argv[0]);
  if (start_index < 0)
    start_index = length + start_index;
  start_index = CLAMP (start_index, 0, length);

  if (argc > 1) {
    int tmp = swfdec_as_value_to_integer (cx, &argv[1]);
    if (tmp < 0)
      return;
    num_remove = MIN (tmp, length - start_index);
  } else {
    num_remove = length - start_index;
  }

  num_add = (argc > 2 ? argc - 2 : 0);
  at_end = length - num_remove - start_index;

  /* create return value */
  array_new = SWFDEC_AS_ARRAY (swfdec_as_array_new (cx));
  swfdec_as_array_append_array_range (array_new, object, start_index,
      num_remove);
  SWFDEC_AS_VALUE_SET_OBJECT (ret, SWFDEC_AS_OBJECT (array_new));

  /* move old data to the right spot */
  swfdec_as_array_move_range (object, start_index + num_remove,
      at_end, start_index + num_add);
  if (num_remove > at_end) {
    swfdec_as_array_remove_range (object, start_index + at_end + num_add,
	length - (start_index + at_end + num_add));
  }
  if (num_remove > num_add)
    swfdec_as_array_set_length_object (object, length - (num_remove - num_add));

  /* add new data */
  if (argc > 2)
    swfdec_as_array_set_range (object, start_index, argc - 2, argv + 2);
}
Exemple #4
0
static void
swfdec_as_array_set (SwfdecAsObject *object, const char *variable,
    const SwfdecAsValue *val, guint flags)
{
  gboolean indexvar;
  char *end;
  gint32 l;

  // we have to allow negative values here
  l = strtoul (variable, &end, 10);
  indexvar = (*end == 0);

  // if we changed to smaller length, destroy all values that are outside it
  //
  if (SWFDEC_AS_ARRAY (object)->check_length &&
      !swfdec_strcmp (swfdec_gc_object_get_context (object)->version, variable,
	SWFDEC_AS_STR_length))
  {
    gint32 length_old = swfdec_as_array_length (object);
    gint32 length_new = swfdec_as_value_to_integer (swfdec_gc_object_get_context (object), val);
    length_new = MAX (0, length_new);
    if (length_old > length_new) {
      swfdec_as_array_remove_range (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 && ++l > swfdec_as_array_length_as_integer (object))
    swfdec_as_array_set_length_object (object, l);
}
Exemple #5
0
void
swfdec_as_array_sort (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
    SwfdecAsValue *argv, SwfdecAsValue *ret)
{
  guint pos;
  SortOption options;
  SwfdecAsFunction *custom_function;

  if (object == NULL || SWFDEC_IS_MOVIE (object))
    return;

  pos = 0;

  if (argc > pos && !SWFDEC_AS_VALUE_IS_NUMBER (&argv[pos])) {
    SwfdecAsFunction *fun;
    if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv[pos]) ||
	!SWFDEC_IS_AS_FUNCTION (
	  fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&argv[pos])))
	return;
    custom_function = fun;
    pos++;
  } else {
    custom_function = NULL;
  }

  if (argc > pos) {
    options = swfdec_as_value_to_integer (cx, &argv[pos]) & MASK_SORT_OPTION;
  } else {
    options = 0;
  }

  swfdec_as_array_do_sort (cx, object, &options, custom_function, NULL, ret);
}
Exemple #6
0
// inner function for swfdec_as_array_sort_compare
static int
swfdec_as_array_sort_compare_values (SwfdecAsContext *cx,
    const SwfdecAsValue *a, const SwfdecAsValue *b, SortOption options,
    SwfdecAsFunction *custom_function)
{
  int retval;

  g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (cx), 0);
  g_return_val_if_fail (SWFDEC_IS_AS_VALUE (a), 0);
  g_return_val_if_fail (SWFDEC_IS_AS_VALUE (b), 0);
  g_return_val_if_fail (custom_function == NULL ||
      SWFDEC_IS_AS_FUNCTION (custom_function), 0);

  if (custom_function != NULL)
  {
    SwfdecAsValue argv[2] = { *a, *b };
    SwfdecAsValue ret;
    SwfdecAsContext *context = swfdec_gc_object_get_context (custom_function);
    swfdec_as_function_call (custom_function, NULL, 2, argv, &ret);
    retval = swfdec_as_value_to_integer (context, &ret);
  }
  else if (options & SORT_OPTION_NUMERIC &&
      (SWFDEC_AS_VALUE_IS_NUMBER (a) ||
       SWFDEC_AS_VALUE_IS_NUMBER (b)) &&
      !SWFDEC_AS_VALUE_IS_UNDEFINED (a) &&
      !SWFDEC_AS_VALUE_IS_UNDEFINED (b))
  {
    if (!SWFDEC_AS_VALUE_IS_NUMBER (a)) {
      retval = 1;
    } else if (!SWFDEC_AS_VALUE_IS_NUMBER (b)) {
      retval = -1;
    } else {
      double an = swfdec_as_value_to_number (cx, a);
      double bn = swfdec_as_value_to_number (cx, b);
      retval = (an < bn ? -1 : (an > bn ? 1 : 0));
    }
  }
  else
  {
    // can't pass swfdec_as_value_to_string calls directly to compare
    // functions, since the order of these is important
    const char *a_str = swfdec_as_value_to_string (cx, a);
    const char *b_str = swfdec_as_value_to_string (cx, b);

    if (options & SORT_OPTION_CASEINSENSITIVE) {
      retval = g_strcasecmp (a_str, b_str);
    } else {
      retval = strcmp (a_str, b_str);
    }
  }

  if (options & SORT_OPTION_DESCENDING)
    retval = -retval;

  return retval;
}
Exemple #7
0
void
swfdec_as_array_slice (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
    SwfdecAsValue *argv, SwfdecAsValue *ret)
{
  gint32 length, start_index, num;
  SwfdecAsArray *array_new;

  if (object == NULL || SWFDEC_IS_MOVIE (object))
    return;

  length = swfdec_as_array_length (object);

  if (argc > 0) {
    start_index = swfdec_as_value_to_integer (cx, &argv[0]);
    if (start_index < 0)
      start_index = length + start_index;
    start_index = CLAMP (start_index, 0, length);
  } else {
    start_index = 0;
  }

  if (argc > 1) {
    gint32 endIndex = swfdec_as_value_to_integer (cx, &argv[1]);
    if (endIndex < 0)
      endIndex = length + endIndex;
    endIndex = CLAMP (endIndex, start_index, length);
    num = endIndex - start_index;
  } else {
    num = length - start_index;
  }

  array_new = SWFDEC_AS_ARRAY (swfdec_as_array_new (cx));
  if (array_new == NULL)
    return;

  swfdec_as_array_append_array_range (array_new, object, start_index, num);

  SWFDEC_AS_VALUE_SET_OBJECT (ret, SWFDEC_AS_OBJECT (array_new));
}
Exemple #8
0
static gint32
swfdec_as_array_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 (swfdec_gc_object_get_context (object), &val);

  return length;
}
void
broadcastMessage (SwfdecAsContext *cx, SwfdecAsObject *object,
    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
{
  SwfdecAsValue val;
  SwfdecAsObject *listeners, *o;
  gint i, length;
  const char *name;
  GSList *list = NULL, *walk;

  if (object == NULL)
    return;

  if (argc < 1)
    return;
  name = swfdec_as_value_to_string (cx, argv[0]);
  argv += 1;
  argc--;

  swfdec_as_object_get_variable (object, SWFDEC_AS_STR__listeners, &val);
  if (!SWFDEC_AS_VALUE_IS_COMPOSITE (val))
    return;

  listeners = SWFDEC_AS_VALUE_GET_COMPOSITE (val);
  swfdec_as_object_get_variable (listeners, SWFDEC_AS_STR_length, &val);
  length = swfdec_as_value_to_integer (cx, val);

  /* return undefined if we won't try to call anything */
  if (length <= 0)
    return;

  /* FIXME: solve this wth foreach, so it gets faster for weird cases */
  for (i = 0; i < length; i++) {
    swfdec_as_object_get_variable (listeners, swfdec_as_integer_to_string (cx, i), &val);
    o = swfdec_as_value_to_object (cx, val);
    if (o == NULL)
      continue;
    list = g_slist_prepend (list, o);
  }
  if (list == NULL)
    return;

  list = g_slist_reverse (list);
  for (walk = list; walk; walk = walk->next) {
    swfdec_as_object_call (walk->data, name, argc, argv, &val);
  }
  g_slist_free (list);

  SWFDEC_AS_VALUE_SET_BOOLEAN (ret, TRUE);
}
Exemple #10
0
void
swfdec_as_function_apply (SwfdecAsContext *cx, SwfdecAsObject *object,
    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
{
  SwfdecAsValue *argv_pass = NULL;
  int length = 0;
  SwfdecAsFunction *fun;
  SwfdecAsObject *thisp = NULL;

  SWFDEC_AS_CHECK (SWFDEC_TYPE_AS_FUNCTION, &fun, "|O", &thisp);

  if (thisp == NULL)
    thisp = swfdec_as_object_new_empty (cx);

  if (argc > 1 && SWFDEC_AS_VALUE_IS_OBJECT (&argv[1])) {
    int i;
    SwfdecAsObject *array;
    SwfdecAsValue val;

    array = SWFDEC_AS_VALUE_GET_OBJECT (&argv[1]);

    swfdec_as_object_get_variable (array, SWFDEC_AS_STR_length, &val);
    length = swfdec_as_value_to_integer (cx, &val);

    if (length > 0) {
      /* FIXME: find a smarter way to do this, like providing argv not as an array */
      if (!swfdec_as_context_try_use_mem (cx, sizeof (SwfdecAsValue) * length)) {
	swfdec_as_context_abort (cx, "too many arguments to Function.apply");
	return;
      }
      argv_pass = g_malloc (sizeof (SwfdecAsValue) * length);

      for (i = 0; i < length; i++) {
	swfdec_as_object_get_variable (array,
	    swfdec_as_integer_to_string (cx, i), &argv_pass[i]);
      }
    } else {
      length = 0;
    }
  }

  swfdec_as_function_call (fun, thisp, length, argv_pass, ret);

  if (argv_pass) {
    swfdec_as_context_unuse_mem (cx, sizeof (SwfdecAsValue) * length);
    g_free (argv_pass);
  }
}
/**
 * swfdec_as_native_function_checkv:
 * @cx: a #SwfdecAsContext
 * @object: this object passed to the native function
 * @type: expected type of @object
 * @result: pointer to variable taking cast result of @object
 * @argc: count of arguments passed to the function
 * @argv: arguments passed to the function
 * @args: argument conversion string
 * @varargs: pointers to variables taking converted arguments
 *
 * This is the valist version of swfdec_as_native_function_check(). See that
 * function for details.
 *
 * Returns: %TRUE if the conversion succeeded, %FALSE otherwise
 **/
gboolean
swfdec_as_native_function_checkv (SwfdecAsContext *cx, SwfdecAsObject *object, 
    GType type, gpointer *result, guint argc, SwfdecAsValue *argv, 
    const char *args, va_list varargs)
{
  guint i;
  gboolean optional = FALSE;

  g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (cx), FALSE);
  g_return_val_if_fail (type == 0 || result != NULL, FALSE);

  /* check that we got a valid type */
  if (type) {
    if (G_TYPE_CHECK_INSTANCE_TYPE (object, type)) {
      *result = object;
    } else if (object && G_TYPE_CHECK_INSTANCE_TYPE (object->relay, type)) {
      *result = object->relay;
    } else {
	return FALSE;
    }
  }
  for (i = 0; *args && i < argc; i++, args++) {
    switch (*args) {
      case 'v':
	{
	  SwfdecAsValue *val = va_arg (varargs, SwfdecAsValue *);
	  *val = argv[i];
	}
	break;
      case 'b':
	{
	  gboolean *b = va_arg (varargs, gboolean *);
	  *b = swfdec_as_value_to_boolean (cx, argv[i]);
	}
	break;
      case 'i':
	{
	  int *j = va_arg (varargs, int *);
	  *j = swfdec_as_value_to_integer (cx, argv[i]);
	}
	break;
      case 'm':
      case 'M':
	{
	  SwfdecMovie *m;
	  SwfdecMovie **arg = va_arg (varargs, SwfdecMovie **);
	  if (SWFDEC_AS_VALUE_IS_MOVIE (argv[i])) {
	    m = SWFDEC_AS_VALUE_GET_MOVIE (argv[i]);
	  } else {
	    m = NULL;
	  }
	  if (m == NULL && *args != 'M')
	    return FALSE;
	  *arg = m;
	}
	break;
      case 'n':
	{
	  double *d = va_arg (varargs, double *);
	  *d = swfdec_as_value_to_number (cx, argv[i]);
	}
	break;
      case 's':
	{
	  const char **s = va_arg (varargs, const char **);
	  *s = swfdec_as_value_to_string (cx, argv[i]);
	}
	break;
      case 'o':
      case 'O':
	{
	  SwfdecAsObject **o = va_arg (varargs, SwfdecAsObject **);
	  *o = swfdec_as_value_to_object (cx, argv[i]);
	  if (*o == NULL && *args != 'O')
	    return FALSE;
	}
	break;
      case '|':
	g_return_val_if_fail (optional == FALSE, FALSE);
	optional = TRUE;
	i--;
	break;
      default:
	g_warning ("'%c' is not a valid type conversion", *args);
	return FALSE;
    }
  }
  if (*args && !optional && *args != '|')
    return FALSE;
  return TRUE;
}