static void swfdec_load_object_stream_target_close (SwfdecStreamTarget *target, SwfdecStream *stream) { SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (target); char *text; // get text text = swfdec_buffer_queue_pull_text (swfdec_stream_get_queue (stream), load_object->version); /* break reference to the loader */ swfdec_stream_set_target (stream, NULL); load_object->loader = NULL; g_object_unref (stream); /* call finish */ swfdec_sandbox_use (load_object->sandbox); if (text != NULL) { load_object->finish (load_object->target, swfdec_as_context_give_string (swfdec_gc_object_get_context (load_object->target), text)); } else { load_object->finish (load_object->target, SWFDEC_AS_STR_EMPTY); } swfdec_sandbox_unuse (load_object->sandbox); /* unroot */ swfdec_player_unroot (SWFDEC_PLAYER ( swfdec_gc_object_get_context (load_object->sandbox)), load_object); }
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); }
void swfdec_as_array_do_shift (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { gint32 length; const char *var; if (object == NULL || SWFDEC_IS_MOVIE (object)) return; // don't allow negative length length = swfdec_as_array_length (object); if (length <= 0) return; swfdec_as_object_get_variable (object, SWFDEC_AS_STR_0, ret); swfdec_as_array_move_range (object, 1, length - 1, 0); // if not Array, leave the length unchanged, and don't remove the element if (SWFDEC_IS_AS_ARRAY (object)) { swfdec_as_array_set_length_object (object, length - 1); } else { // we have to put the last element back, because we used move, not copy SwfdecAsValue val; if (length > 1) { var = swfdec_as_integer_to_string (swfdec_gc_object_get_context (object), length - 2); swfdec_as_object_get_variable (object, var, &val); } else { val = *ret; } var = swfdec_as_integer_to_string (swfdec_gc_object_get_context (object), length - 1); swfdec_as_object_set_variable (object, var, &val); } }
void swfdec_load_object_create (SwfdecAsObject *target, const char *url, SwfdecBuffer *data, guint header_count, char **header_names, char **header_values, SwfdecLoadObjectProgress progress, SwfdecLoadObjectFinish finish) { SwfdecPlayer *player; SwfdecLoadObject *load; g_return_if_fail (SWFDEC_IS_AS_OBJECT (target)); g_return_if_fail (url != NULL); g_return_if_fail (header_count == 0 || header_names != NULL); g_return_if_fail (header_count == 0 || header_values != NULL); g_return_if_fail (finish != NULL); player = SWFDEC_PLAYER (swfdec_gc_object_get_context (target)); load = g_object_new (SWFDEC_TYPE_LOAD_OBJECT, NULL); swfdec_player_root_full (player, load, swfdec_load_object_mark, g_object_unref); load->target = target; load->url = url; load->buffer = data; load->header_count = header_count; load->header_names = header_names; load->header_values = header_values; load->progress = progress; load->finish = finish; /* get the current security */ g_assert (SWFDEC_AS_CONTEXT (player)->frame); load->sandbox = SWFDEC_SANDBOX (SWFDEC_AS_CONTEXT (player)->global); load->version = SWFDEC_AS_CONTEXT (player)->version; swfdec_player_request_resource (player, swfdec_load_object_request, load, NULL); }
SwfdecAsObject * swfdec_as_super_resolve_property (SwfdecAsSuper *super, const char *name) { SwfdecAsObject *ref; SwfdecAsContext *context; g_return_val_if_fail (SWFDEC_IS_AS_SUPER (super), NULL); if (super->object == NULL) return NULL; ref = super->object->prototype; if (ref == NULL) return NULL; context = swfdec_gc_object_get_context (super); if (name && context->version > 6) { /* skip prototypes to find the next one that has this function defined */ SwfdecAsObject *res; if (swfdec_as_object_get_variable_and_flags (ref, name, NULL, NULL, &res) && ref != res) { while (ref->prototype != res) { ref = ref->prototype; g_assert (ref); } } } return ref; }
static void swfdec_as_super_call (SwfdecAsFunction *function, SwfdecAsObject *thisp, gboolean construct, SwfdecAsObject *super_reference, guint n_args, const SwfdecAsValue *args, SwfdecAsValue *return_value) { SwfdecAsSuper *super = SWFDEC_AS_SUPER (function); SwfdecAsFunction *fun; SwfdecAsValue val; if (super->object == NULL) { SWFDEC_WARNING ("super () called without an object."); return; } swfdec_as_object_get_variable (super->object, SWFDEC_AS_STR___constructor__, &val); if (!SWFDEC_AS_VALUE_IS_OBJECT (&val) || !SWFDEC_IS_AS_FUNCTION (fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&val))) return; if (construct) { SWFDEC_FIXME ("What happens with \"new super()\"?"); } swfdec_as_function_call_full (fun, super->thisp, construct || swfdec_as_context_is_constructing (swfdec_gc_object_get_context (super)), super->object->prototype, n_args, args, return_value); }
static gboolean swfdec_as_super_get (SwfdecAsObject *object, SwfdecAsObject *orig, const char *variable, SwfdecAsValue *val, guint *flags) { SwfdecAsSuper *super = SWFDEC_AS_SUPER (object); SwfdecAsObjectClass *klass; SwfdecAsObject *cur; guint i; if (super->object == NULL) { SWFDEC_WARNING ("super.%s () called without an object.", variable); return FALSE; } cur = super->object->prototype; for (i = 0; i <= SWFDEC_AS_OBJECT_PROTOTYPE_RECURSION_LIMIT && cur != NULL; i++) { klass = SWFDEC_AS_OBJECT_GET_CLASS (cur); /* FIXME: is the orig pointer correct? */ if (klass->get (cur, super->object, variable, val, flags)) return TRUE; /* FIXME: need get_prototype_internal here? */ cur = swfdec_as_object_get_prototype (cur); } if (i > SWFDEC_AS_OBJECT_PROTOTYPE_RECURSION_LIMIT) { swfdec_as_context_abort (swfdec_gc_object_get_context (object), "Prototype recursion limit exceeded"); } SWFDEC_AS_VALUE_SET_UNDEFINED (val); *flags = 0; return FALSE; }
void swfdec_as_array_do_pop (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { gint32 length; const char *var; if (object == NULL || SWFDEC_IS_MOVIE (object)) return; // we allow negative indexes here, but not 0 length = swfdec_as_array_length_as_integer (object); if (length == 0) return; var = swfdec_as_integer_to_string (swfdec_gc_object_get_context (object), length - 1); swfdec_as_object_get_variable (object, var, ret); swfdec_as_object_delete_variable (object, var); // if Array, the length is reduced by one // else the length is not reduced at all, but the variable is still deleted if (SWFDEC_IS_AS_ARRAY (object)) swfdec_as_array_set_length_object (object, length - 1); }
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; }
void swfdec_as_super_new (SwfdecAsFrame *frame, SwfdecAsObject *thisp, SwfdecAsObject *ref) { SwfdecAsContext *context; SwfdecAsSuper *super; g_return_if_fail (frame != NULL); g_return_if_fail (SWFDEC_IS_AS_OBJECT (thisp)); g_return_if_fail (ref == NULL || SWFDEC_IS_AS_OBJECT (ref)); if (frame->super != NULL) return; context = swfdec_gc_object_get_context (thisp); if (context->version <= 5) return; super = g_object_new (SWFDEC_TYPE_AS_SUPER, "context", context, NULL); frame->super = SWFDEC_AS_OBJECT (super); super->thisp = swfdec_as_object_resolve (thisp); if (context->version <= 5) { super->object = NULL; } else { super->object = ref; } }
static void swfdec_morph_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matrix, gboolean last) { SwfdecRect rect; swfdec_rect_transform (&rect, &movie->original_extents, matrix); swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)), &rect); }
// 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; }
static void swfdec_test_test_error (SwfdecTestPlugin *plugin, const char *description) { SwfdecTestTest *test = SWFDEC_TEST_TEST_FROM_PLUGIN (plugin); if (test->plugin_error) return; test->plugin_error = TRUE; swfdec_test_throw (swfdec_gc_object_get_context (test), description); }
static void swfdec_video_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matrix, gboolean last) { SwfdecVideo *org = SWFDEC_VIDEO (movie->graphic); SwfdecRect rect = { 0, 0, SWFDEC_TWIPS_SCALE_FACTOR * org->width, SWFDEC_TWIPS_SCALE_FACTOR * org->height }; swfdec_rect_transform (&rect, &rect, matrix); swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)), &rect); }
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); }
static const char * swfdec_as_array_foreach_reverse (SwfdecAsObject *object, const char *variable, SwfdecAsValue *value, guint flags, gpointer data) { gint32 *length = data; gint32 idx; idx = swfdec_as_array_to_index (variable); if (idx == -1 || idx >= *length) return variable; return swfdec_as_integer_to_string (swfdec_gc_object_get_context (object), *length - 1 - idx); }
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; }
/** * swfdec_as_array_set_value: * @array: a #SwfdecAsArray * @idx: index of the value to set * @value: a pointer to #SwfdecAsValue * * Sets a @value to given index. The @array's length will be increased if * necessary. **/ void swfdec_as_array_set_value (SwfdecAsArray *array, gint32 idx, SwfdecAsValue *value) { const char *var; g_assert (SWFDEC_IS_AS_ARRAY (array)); g_assert (idx >= 0); g_assert (SWFDEC_IS_AS_VALUE (value)); var = swfdec_as_integer_to_string (swfdec_gc_object_get_context (array), idx); swfdec_as_object_set_variable (SWFDEC_AS_OBJECT (array), var, value); }
static void swfdec_test_test_request_socket (SwfdecTestPlugin *plugin, SwfdecTestPluginSocket *psock) { SwfdecTestTest *test = SWFDEC_TEST_TEST_FROM_PLUGIN (plugin); SwfdecAsContext *cx = swfdec_gc_object_get_context (test); SwfdecTestSocket *sock; SwfdecAsValue val; sock = swfdec_test_socket_new (test, psock); SWFDEC_AS_VALUE_SET_OBJECT (&val, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (sock))); swfdec_as_relay_call (SWFDEC_AS_RELAY (test), swfdec_as_context_get_string (cx, "onSocket"), 1, &val, NULL); }
static void swfdec_xml_socket_ensure_closed (SwfdecXmlSocket *xml) { SwfdecPlayer *player = SWFDEC_PLAYER (swfdec_gc_object_get_context (xml)); if (xml->socket == NULL) return; swfdec_buffer_queue_clear (xml->send_queue); swfdec_stream_set_target (SWFDEC_STREAM (xml->socket), NULL); g_object_unref (xml->socket); xml->socket = NULL; player->priv->xml_sockets = g_slist_remove (player->priv->xml_sockets, xml); }
static void swfdec_video_movie_set_variable (SwfdecAsObject *object, const char *variable, const SwfdecAsValue *val, guint flags) { guint version = swfdec_gc_object_get_context (object)->version; if (swfdec_strcmp (version, variable, SWFDEC_AS_STR_deblocking) == 0) { SWFDEC_STUB ("Video.deblocking (set)"); } else if (swfdec_strcmp (version, variable, SWFDEC_AS_STR_smoothing) == 0) { SWFDEC_STUB ("Video.smoothing (set)"); } else { SWFDEC_AS_OBJECT_CLASS (swfdec_video_movie_parent_class)->set (object, variable, val, flags); } }
static void swfdec_bitmap_data_clear (SwfdecBitmapData *bitmap) { int w, h; if (bitmap->surface == NULL) return; w = cairo_image_surface_get_width (bitmap->surface); h = cairo_image_surface_get_height (bitmap->surface); swfdec_bitmap_data_invalidate (bitmap, 0, 0, w, h); swfdec_as_context_unuse_mem (swfdec_gc_object_get_context (bitmap), 4 * w * h); cairo_surface_destroy (bitmap->surface); bitmap->surface = NULL; }
static void swfdec_bitmap_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matrix, gboolean last) { SwfdecBitmapMovie *bitmap = SWFDEC_BITMAP_MOVIE (movie); SwfdecRect rect = { 0, 0, 0, 0 }; if (bitmap->bitmap->surface == NULL) return; rect.x1 = cairo_image_surface_get_width (bitmap->bitmap->surface) * SWFDEC_TWIPS_SCALE_FACTOR; rect.y1 = cairo_image_surface_get_height (bitmap->bitmap->surface) * SWFDEC_TWIPS_SCALE_FACTOR; swfdec_rect_transform (&rect, &rect, matrix); swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)), &rect); }
static gboolean swfdec_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_integer_to_string (swfdec_gc_object_get_context (fdata->object_to), fdata->offset + (idx - fdata->start_index)); swfdec_as_object_set_variable (fdata->object_to, var, value); } return TRUE; }
static void swfdec_as_array_set_range_with_flags (SwfdecAsObject *object, gint32 start_index, gint32 num, const SwfdecAsValue *value, SwfdecAsVariableFlag flags) { 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 (num == 0 || value != NULL); for (i = 0; i < num; i++) { var = swfdec_as_integer_to_string (swfdec_gc_object_get_context (object), start_index + i); swfdec_as_object_set_variable_and_flags (object, var, &value[i], flags); } }
SwfdecMovie * swfdec_bitmap_movie_new (SwfdecMovie *parent, SwfdecBitmapData *bitmap, int depth) { SwfdecBitmapMovie *movie; g_return_val_if_fail (SWFDEC_IS_MOVIE (parent), NULL); g_return_val_if_fail (SWFDEC_IS_BITMAP_DATA (bitmap), NULL); movie = g_object_new (SWFDEC_TYPE_BITMAP_MOVIE, "context", swfdec_gc_object_get_context (parent), "depth", depth, "parent", parent, "resource", parent->resource, NULL); movie->bitmap = bitmap; /* we ref the bitmap here to enforce the order for destruction, which makes our signals work */ g_object_ref (bitmap); /* FIXME: be smarter in what we invalidate, use the rectangle */ g_signal_connect_swapped (movie->bitmap, "invalidate", G_CALLBACK (swfdec_movie_invalidate_last), movie); return SWFDEC_MOVIE (movie); }
static void swfdec_as_array_remove_range (SwfdecAsObject *object, gint32 start_index, gint32 num) { g_return_if_fail (start_index >= 0); g_return_if_fail (num >= 0); if (num == 0) return; // to avoid foreach loop, use special case when removing just one variable if (num == 1) { swfdec_as_object_delete_variable (object, swfdec_as_integer_to_string ( swfdec_gc_object_get_context (object), start_index)); } else { ForeachRemoveRangeData fdata = { start_index, num }; swfdec_as_object_foreach_remove (object, swfdec_as_array_foreach_remove_range, &fdata); } }
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_integer_to_string (swfdec_gc_object_get_context (object), 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 void swfdec_test_test_load_plugin (SwfdecTestTest *test, const char *filename) { memset (&test->plugin, 0, sizeof (SwfdecTestPlugin)); /* initialize test->plugin */ /* FIXME: This assumes filenames - do we wanna allow http? */ if (g_path_is_absolute (filename)) { test->plugin.filename = g_strdup (filename); } else { char *cur = g_get_current_dir (); test->plugin.filename = g_build_filename (cur, filename, NULL); g_free (cur); } test->plugin.trace = swfdec_test_test_trace; test->plugin.launch = swfdec_test_test_launch; test->plugin.quit = swfdec_test_test_quit; test->plugin.error = swfdec_test_test_error; test->plugin.request_socket = swfdec_test_test_request_socket; /* load the right values */ if (swfdec_test_plugin_name) { void (*init) (SwfdecTestPlugin *plugin); char *dir = g_build_filename (g_get_home_dir (), ".swfdec-test", NULL); char *name = g_module_build_path (dir, swfdec_test_plugin_name); g_free (dir); test->module = g_module_open (name, G_MODULE_BIND_LOCAL); if (test->module == NULL) { swfdec_test_throw (swfdec_gc_object_get_context (test), "could not find player \"%s\"", swfdec_test_plugin_name); return; } if (!g_module_symbol (test->module, "swfdec_test_plugin_init", (gpointer) &init)) { g_module_close (test->module); test->module = NULL; } init (&test->plugin); } else { swfdec_test_plugin_swfdec_new (&test->plugin); } test->plugin_loaded = TRUE; }
static void swfdec_load_object_stream_target_error (SwfdecStreamTarget *target, SwfdecStream *stream) { SwfdecLoader *loader = SWFDEC_LOADER (stream); SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (target); /* break reference to the loader */ swfdec_stream_set_target (SWFDEC_STREAM (loader), NULL); load_object->loader = NULL; g_object_unref (loader); /* call finish */ swfdec_sandbox_use (load_object->sandbox); load_object->finish (load_object->target, NULL); swfdec_sandbox_unuse (load_object->sandbox); /* unroot */ swfdec_player_unroot (SWFDEC_PLAYER ( swfdec_gc_object_get_context (load_object->sandbox)), load_object); }