예제 #1
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;
}
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);
}
예제 #3
0
void
swfdec_as_array_join (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
    SwfdecAsValue *argv, SwfdecAsValue *ret)
{
  int i;
  const char *var, *str, *sep;
  SwfdecAsValue val;

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

  if (argc > 0) {
    sep = swfdec_as_value_to_string (cx, &argv[0]);
  } else {
    sep = SWFDEC_AS_STR_COMMA;
  }

  // note: we don't cache length
  if (swfdec_as_array_length (object) > 0) {
    GString *string;
    swfdec_as_object_get_variable (object, SWFDEC_AS_STR_0, &val);
    str = swfdec_as_value_to_string (cx, &val);
    string = g_string_new (str);
    for (i = 1; i < swfdec_as_array_length (object); i++) {
      var = swfdec_as_integer_to_string (cx, i);
      swfdec_as_object_get_variable (object, var, &val);
      var = swfdec_as_value_to_string (cx, &val);
      g_string_append (string, sep);
      g_string_append (string, var);
    }
    str = swfdec_as_context_give_string (cx, g_string_free (string, FALSE));
  } else {
    str = SWFDEC_AS_STR_EMPTY;
  }

  SWFDEC_AS_VALUE_SET_STRING (ret, str);
}
예제 #4
0
void
swfdec_as_array_sortOn (SwfdecAsContext *cx, SwfdecAsObject *object,
    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
{
  const char **fields;
  SortOption *options;
  gint32 i, num_fields;
  SwfdecAsObject *array;
  SwfdecAsValue val;

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

  if (argc < 1)
    return;

  if (SWFDEC_AS_VALUE_IS_OBJECT (&argv[0])) {

    array = SWFDEC_AS_VALUE_GET_OBJECT (&argv[0]);
    if (!SWFDEC_IS_AS_ARRAY (array)) {
      SWFDEC_AS_VALUE_SET_OBJECT (ret, object);
      return;
    }

    num_fields = swfdec_as_array_get_length (SWFDEC_AS_ARRAY (array));
    if (num_fields <= 0) {
      SWFDEC_AS_VALUE_SET_OBJECT (ret, object);
      return;
    }

    fields = g_new (const char *, num_fields + 1);
    for (i = 0; i < num_fields; i++) {
      swfdec_as_array_get_value (SWFDEC_AS_ARRAY (array), i, &val);
      if (SWFDEC_AS_VALUE_IS_OBJECT (&val) &&
	  SWFDEC_IS_AS_STRING (SWFDEC_AS_VALUE_GET_OBJECT (&val))) {
	fields[i] =
	  SWFDEC_AS_STRING (SWFDEC_AS_VALUE_GET_OBJECT (&val))->string;
      } else {
	fields[i] = swfdec_as_value_to_string (cx, &val);
      }
    }

    fields[i] = NULL;
  } else {
/**
 * 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;
}
예제 #6
0
파일: swfdec_test.c 프로젝트: fengye/swfdec
int
main (int argc, char **argv)
{
    char *script_filename = NULL;
    GError *error = NULL;
    SwfdecAsContext *context;
    SwfdecAsObject *array;
    SwfdecScript *script;
    SwfdecAsValue val;
    int i, ret;
    gboolean dump = FALSE;
    gboolean no_check = FALSE, only_check = FALSE;

    GOptionEntry options[] = {
        { "dump", 'd', 0, G_OPTION_ARG_NONE, &dump, "dump informative output on failure", FALSE },
        { "no-check", 0, 0, G_OPTION_ARG_NONE, &no_check, "don't check if the system is ok for running the testsuite", FALSE },
        { "self-check", 0, 0, G_OPTION_ARG_NONE, &only_check, "run a system check and exit", FALSE },
        { "player", 'p', 0, G_OPTION_ARG_STRING, &swfdec_test_plugin_name, "player to test", "NAME" },
        { "script", 's', 0, G_OPTION_ARG_STRING, &script_filename, "script to execute if not ./default.sts", "FILENAME" },
        { NULL }
    };
    GOptionContext *ctx;

    /* set the right warning levels */
    g_log_set_always_fatal (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
    /* by default get rid of the loads of warnings the tests produce */
    g_setenv ("SWFDEC_DEBUG", "2", FALSE);

    g_thread_init (NULL);
    swfdec_init ();

    ctx = g_option_context_new ("");
    g_option_context_add_main_entries (ctx, options, "options");
    g_option_context_parse (ctx, &argc, &argv, &error);
    g_option_context_free (ctx);

    if (error) {
        g_printerr ("ERROR: wrong command line arguments: %s\n", error->message);
        g_error_free (error);
        return EXIT_FAILURE;
    }

    if (only_check || !no_check) {
        gboolean result = check_system (only_check);
        if (!result) {
            g_print ("ERROR: System checked failed, aborting. Use --no-check to disable.\n");
            return 1;
        } else if (only_check) {
            return 0;
        }
    }
    g_assert (!only_check);

    /* allow env vars instead of options - eases running make check with different settings */
    if (swfdec_test_plugin_name == NULL)
        swfdec_test_plugin_name = g_strdup (g_getenv ("SWFDEC_TEST_PLAYER"));

    script = load_script (script_filename);
    g_free (script_filename);
    if (script == NULL)
        return EXIT_FAILURE;

    context = g_object_new (SWFDEC_TYPE_AS_CONTEXT, NULL);
    swfdec_as_context_startup (context);

    SWFDEC_AS_VALUE_SET_BOOLEAN (&val, dump);
    swfdec_as_object_set_variable (context->global,
                                   swfdec_as_context_get_string (context, "dump"), &val);

    swfdec_test_function_init_context (context);
    swfdec_as_context_run_init_script (context, swfdec_test_initialize,
                                       sizeof (swfdec_test_initialize), SWFDEC_TEST_VERSION);

    array = swfdec_as_array_new (context);
    if (array == NULL) {
        g_print ("ERROR: Not enough memory");
        return EXIT_FAILURE;
    }
    if (argc < 2) {
        GDir *dir;
        const char *file;
        dir = g_dir_open (".", 0, NULL);
        while ((file = g_dir_read_name (dir))) {
            if (!g_str_has_suffix (file, ".swf"))
                continue;
            SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_get_string (context, file));
            swfdec_as_array_push (SWFDEC_AS_ARRAY (array), &val);
        }
        g_dir_close (dir);
    } else {
        for (i = 1; i < argc; i++) {
            SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_get_string (context, argv[i]));
            swfdec_as_array_push (SWFDEC_AS_ARRAY (array), &val);
        }
    }
    SWFDEC_AS_VALUE_SET_OBJECT (&val, array);
    swfdec_as_object_set_variable (context->global,
                                   swfdec_as_context_get_string (context, "filenames"), &val);
    swfdec_as_object_run (context->global, script);
    if (swfdec_as_context_catch (context, &val)) {
        g_print ("ERROR: %s\n", swfdec_as_value_to_string (context, &val));
        ret = EXIT_FAILURE;
    } else {
        g_print ("SUCCESS\n");
        ret = EXIT_SUCCESS;
    }

    swfdec_script_unref (script);
    g_object_unref (context);

    return ret;
}