Benjamin Otte
2007-Sep-06 07:35 UTC
[Swfdec] 3 commits - libswfdec/swfdec_as_date.c libswfdec/swfdec_as_interpret.c libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_sprite_movie.c
libswfdec/swfdec_as_date.c | 16 ++-- libswfdec/swfdec_as_interpret.c | 146 ++++++++++++++++++++++++++++++++++++++-- libswfdec/swfdec_movie.c | 43 +++++++---- libswfdec/swfdec_movie.h | 2 libswfdec/swfdec_sprite_movie.c | 37 ---------- 5 files changed, 179 insertions(+), 65 deletions(-) New commits: diff-tree 89d295a9455fead858e48ffcae0cc5808d72ee22 (from 8fc53e764a741a293e8037d2caa0af55bc9df645) Author: Benjamin Otte <otte at gnome.org> Date: Wed Sep 5 23:25:22 2007 +0200 implement swfdec_action_get_movie_by_path() and use it for GetVariable This is the second try to make FLash 4-style variables work. Tests will follow tomorrow diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c index fcbd035..a94d3ca 100644 --- a/libswfdec/swfdec_as_interpret.c +++ b/libswfdec/swfdec_as_interpret.c @@ -409,18 +409,156 @@ swfdec_action_push (SwfdecAsContext *cx, } } +/** + * swfdec_action_get_movie_by_path: + * @cx: a #SwfdecAsContext + * @path: the path to look up + * @variable: pointer that takes variable part of the path or %NULL if not + * allowed + * + * Looks up a Flash4-compatible path using "/", ":" and "." style syntax. If + * @variable is %NULL, no variable path is allowed. + * + * Returns: The #SwfdecMovie that was looked up or %NULL if the path does not + * specify a valid movie. + **/ +static gboolean +swfdec_action_get_movie_by_path (SwfdecAsContext *cx, const char *path, + SwfdecAsObject **object, const char **variable) +{ + SwfdecAsObject *movie; + const char *s; + SwfdecAsValue val; + gboolean was_slash = FALSE; + + /* shortcut for the general case */ + if (strpbrk (path, ".:/") == NULL) { + *object = NULL; + *variable = path; + return TRUE; + } + + /* in general, any combination of dot, colon and slash is allowed, but there + * is some weird stuff that is not allowed. WE check this first: */ + /* if a slash is last, no colon or dot may be before it. */ + s = strrchr (path, '/'); + if (s != NULL) { + const char *dot = strrchr (path, '.'); + const char *colon = strrchr (path, ':'); + if (!(dot > s || colon > s) && + (dot != NULL || colon != NULL)) + return FALSE; + } + /* if a dot follows a slash, it must be the last seperator */ + s = strchr (path, '/'); + if (s) { + const char *dot = strchr (s, '.'); + if (dot && strpbrk (dot + 1, ".:")) + return FALSE; + } + /* a colon at the beginning may not be the only separator */ + if (path[0] == ':') { + if (strpbrk (path + 1, ".:/") == NULL) + return FALSE; + else + path++; + } + + movie = cx->frame->target; + if (!SWFDEC_IS_MOVIE (movie)) { + SWFDEC_FIXME ("target is not a movie"); + } else { + if (path[0] == '/') { + /* if path starts with a slash, start from the root movie */ + while (SWFDEC_MOVIE (movie)->parent) + movie = SWFDEC_AS_OBJECT (SWFDEC_MOVIE (movie)->parent); + path++; + was_slash = TRUE; + } else { + /* if path starts with "..", move to parent */ + while (path[0] == '.') { + if (path[1] != '.') + return FALSE; + movie = SWFDEC_AS_OBJECT (SWFDEC_MOVIE (movie)->parent); + if (movie == NULL) + return FALSE; + path++; + if (path[0] == '/') { + was_slash = TRUE; + path++; + } else if (path[0] == ':' || path[0] == '.') { + SWFDEC_FIXME ("what now?"); + path++; + was_slash = FALSE; + break; + } else { + return FALSE; + } + } + } + } + while ((s = strpbrk (path, ".:/"))) { + const char *var; + + if (s == path) { + if (*s == '/') + return FALSE; + was_slash = FALSE; + path++; + continue; + } + was_slash = *s == '/'; + var = swfdec_as_context_give_string (cx, g_strndup (path, s - path)); + if (!swfdec_as_object_get_variable (movie, var, &val) || + !SWFDEC_AS_VALUE_IS_OBJECT (&val) || + !SWFDEC_IS_MOVIE ((movie = SWFDEC_AS_VALUE_GET_OBJECT (&val)))) + return FALSE; + path = s + 1; + } + if (was_slash) { + if (*path) { + const char *var = swfdec_as_context_get_string (cx, path); + movie = SWFDEC_AS_OBJECT (swfdec_movie_get_by_name (SWFDEC_MOVIE (movie), var)); + if (movie == NULL) + return FALSE; + } + *object = movie; + *variable = NULL; + return TRUE; + } else { + *object = movie; + *variable = path; + return TRUE; + } +} + static void swfdec_action_get_variable (SwfdecAsContext *cx, guint action, const guint8 *data, guint len) { + SwfdecAsValue *val; const char *s; + SwfdecAsObject *object; - s = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 1)); - swfdec_as_context_eval (cx, NULL, s, swfdec_as_stack_peek (cx, 1)); + val = swfdec_as_stack_peek (cx, 1); + s = swfdec_as_value_to_string (cx, val); + if (swfdec_action_get_movie_by_path (cx, s, &object, &s)) { + if (object == NULL) + object = swfdec_as_frame_find_variable (cx->frame, s); + } else { + object = NULL; + } + if (object != NULL) { + if (s) { + swfdec_as_object_get_variable (object, swfdec_as_context_get_string (cx, s), val); + } else { + SWFDEC_AS_VALUE_SET_OBJECT (val, object); + } + } else { + SWFDEC_AS_VALUE_SET_UNDEFINED (val); #ifdef SWFDEC_WARN_MISSING_PROPERTIES - if (SWFDEC_AS_VALUE_IS_UNDEFINED (swfdec_as_stack_peek (cx, 1))) { SWFDEC_WARNING ("no variable named %s", s); - } #endif + } } static void diff-tree 8fc53e764a741a293e8037d2caa0af55bc9df645 (from bef93cc3654b365ede21b7620ea309292d6a0a1d) Author: Benjamin Otte <otte at gnome.org> Date: Wed Sep 5 23:23:45 2007 +0200 merge the too get_variable functions, so we can export swfdec_movie_get_by_path() diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c index c9755ea..82fa40a 100644 --- a/libswfdec/swfdec_movie.c +++ b/libswfdec/swfdec_movie.c @@ -40,6 +40,7 @@ #include "swfdec_sprite_movie.h" #include "swfdec_swf_instance.h" #include "swfdec_system.h" +#include "swfdec_utils.h" /*** MOVIE ***/ @@ -916,30 +917,40 @@ swfdec_movie_mark (SwfdecAsObject *objec } /* FIXME: This function can definitely be implemented easier */ -static SwfdecMovie * -swfdec_movie_get_by_name (SwfdecPlayer *player, const char *name) +SwfdecMovie * +swfdec_movie_get_by_name (SwfdecMovie *movie, const char *name) { GList *walk; - int i = SWFDEC_AS_CONTEXT (player)->version; + int i; gulong l; + guint version = SWFDEC_AS_OBJECT (movie)->context->version; char *end; + SwfdecPlayer *player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context); - if ((i >= 7 && !g_str_has_prefix (name, "_level")) || - strncasecmp (name, "_level", 6) != 0) - return NULL; + if ((version >= 7 && g_str_has_prefix (name, "_level")) || + strncasecmp (name, "_level", 6) == 0) { + errno = 0; + l = strtoul (name + 6, &end, 10); + if (errno != 0 || *end != 0 || l > G_MAXINT) + return NULL; + i = l - 16384; + for (walk = player->roots; walk; walk = walk->next) { + SwfdecMovie *cur = walk->data; + if (cur->depth < i) + continue; + if (cur->depth == i) + return cur; + break; + } + } - errno = 0; - l = strtoul (name + 6, &end, 10); - if (errno != 0 || *end != 0 || l > G_MAXINT) - return NULL; - i = l - 16384; - for (walk = player->roots; walk; walk = walk->next) { + for (walk = movie->list; walk; walk = walk->next) { SwfdecMovie *cur = walk->data; - if (cur->depth < i) + if (cur->original_name == SWFDEC_AS_STR_EMPTY) continue; - if (cur->depth == i) + if ((version >= 7 && cur->name == name) || + swfdec_str_case_equal (cur->name, name)) return cur; - break; } return NULL; } @@ -974,7 +985,7 @@ swfdec_movie_get_variable (SwfdecAsObjec return TRUE; } - movie = swfdec_movie_get_by_name (SWFDEC_PLAYER (object->context), variable); + movie = swfdec_movie_get_by_name (movie, variable); if (movie) { SWFDEC_AS_VALUE_SET_OBJECT (val, SWFDEC_AS_OBJECT (movie)); *flags = 0; diff --git a/libswfdec/swfdec_movie.h b/libswfdec/swfdec_movie.h index d383c98..dce5e2c 100644 --- a/libswfdec/swfdec_movie.h +++ b/libswfdec/swfdec_movie.h @@ -174,6 +174,8 @@ SwfdecMovie * swfdec_movie_duplicate (S void swfdec_movie_initialize (SwfdecMovie * movie); SwfdecMovie * swfdec_movie_find (SwfdecMovie * movie, int depth); +SwfdecMovie * swfdec_movie_get_by_name (SwfdecMovie * movie, + const char * name); void swfdec_movie_remove (SwfdecMovie * movie); void swfdec_movie_destroy (SwfdecMovie * movie); void swfdec_movie_set_static_properties diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c index 8658bd3..31d8cf7 100644 --- a/libswfdec/swfdec_sprite_movie.c +++ b/libswfdec/swfdec_sprite_movie.c @@ -37,7 +37,6 @@ #include "swfdec_sprite.h" #include "swfdec_swf_instance.h" #include "swfdec_tag.h" -#include "swfdec_utils.h" /*** SWFDEC_SPRITE_MOVIE ***/ @@ -638,41 +637,6 @@ swfdec_sprite_movie_finish_movie (Swfdec } } -static SwfdecMovie * -swfdec_sprite_movie_get_by_name (SwfdecMovie *movie, const char *name) -{ - GList *walk; - guint version = SWFDEC_AS_OBJECT (movie)->context->version; - - for (walk = movie->list; walk; walk = walk->next) { - SwfdecMovie *cur = walk->data; - if (cur->original_name == SWFDEC_AS_STR_EMPTY) - continue; - if ((version >= 7 && cur->name == name) || - swfdec_str_case_equal (cur->name, name)) - return cur; - } - return NULL; -} - -static gboolean -swfdec_sprite_movie_get_variable (SwfdecAsObject *object, SwfdecAsObject *orig, - const char *variable, SwfdecAsValue *val, guint *flags) -{ - SwfdecMovie *movie; - - if (SWFDEC_AS_OBJECT_CLASS (swfdec_sprite_movie_parent_class)->get (object, orig, variable, val, flags)) - return TRUE; - - movie = swfdec_sprite_movie_get_by_name (SWFDEC_MOVIE (object), variable); - if (movie == NULL) - return FALSE; - - SWFDEC_AS_VALUE_SET_OBJECT (val, SWFDEC_AS_OBJECT (movie)); - *flags = 0; - return TRUE; -} - static void swfdec_sprite_movie_mark (SwfdecAsObject *object) { @@ -696,7 +660,6 @@ swfdec_sprite_movie_class_init (SwfdecSp object_class->dispose = swfdec_sprite_movie_dispose; - asobject_class->get = swfdec_sprite_movie_get_variable; asobject_class->mark = swfdec_sprite_movie_mark; movie_class->init_movie = swfdec_sprite_movie_init_movie; diff-tree bef93cc3654b365ede21b7620ea309292d6a0a1d (from 49049ba4180c1ee8491bb69c395cc2c5e8fff09e) Author: Benjamin Otte <otte at gnome.org> Date: Wed Sep 5 23:23:02 2007 +0200 make this work when time_t is 32bit, too diff --git a/libswfdec/swfdec_as_date.c b/libswfdec/swfdec_as_date.c index c7c3c89..6e2e30a 100644 --- a/libswfdec/swfdec_as_date.c +++ b/libswfdec/swfdec_as_date.c @@ -138,7 +138,7 @@ swfdec_as_date_get_milliseconds_local (c g_assert (swfdec_as_date_is_valid (date)); if (isfinite (date->milliseconds)) { - return date->milliseconds + date->utc_offset * 60 * 1000; + return date->milliseconds + (double) date->utc_offset * 60 * 1000; } else { return 0; } @@ -148,7 +148,7 @@ static void swfdec_as_date_set_milliseconds_local (SwfdecAsDate *date, gint64 milliseconds) { date->milliseconds - milliseconds - date->utc_offset * 60 * 1000; + milliseconds - (double) date->utc_offset * 60 * 1000; } static void @@ -181,7 +181,7 @@ swfdec_as_date_set_brokentime_utc (Swfde } else { date->milliseconds = 0; } - date->milliseconds += seconds * 1000; + date->milliseconds += (gint64) seconds * 1000; } static void @@ -215,7 +215,7 @@ swfdec_as_date_set_brokentime_local (Swf } else { date->milliseconds = 0; } - date->milliseconds += seconds * 1000; + date->milliseconds += (gint64) seconds * 1000; } // set and get function helpers @@ -489,9 +489,9 @@ swfdec_as_date_getUTCMilliseconds (Swfde milliseconds = swfdec_as_date_get_milliseconds_utc (date); if (milliseconds >= 0 || (milliseconds % 1000 == 0)) { - SWFDEC_AS_VALUE_SET_INT (ret, milliseconds % 1000); + SWFDEC_AS_VALUE_SET_NUMBER (ret, milliseconds % 1000); } else { - SWFDEC_AS_VALUE_SET_INT (ret, 1000 + milliseconds % 1000); + SWFDEC_AS_VALUE_SET_NUMBER (ret, 1000 + milliseconds % 1000); } } @@ -894,7 +894,7 @@ swfdec_as_date_UTC (SwfdecAsContext *cx, brokentime.tm_year = year; } - milliseconds = timegm (&brokentime) * 1000; + milliseconds = (gint64) timegm (&brokentime) * 1000; if (argc > i) { if (swfdec_as_date_value_to_number_and_integer (cx, &argv[i++], &d, @@ -906,7 +906,7 @@ swfdec_as_date_UTC (SwfdecAsContext *cx, } } - SWFDEC_AS_VALUE_SET_INT (ret, milliseconds); + SWFDEC_AS_VALUE_SET_NUMBER (ret, milliseconds); } // Constructor
Reasonably Related Threads
- 9 commits - libswfdec/swfdec_as_context.c libswfdec/swfdec_as_internal.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_movie.c libswfdec/swfdec_player.c libswfdec/swfdec_video_movie_as.c
- libswfdec-gtk/swfdec_gtk_player.c libswfdec/swfdec_as_date.c libswfdec/swfdec_audio.c libswfdec/swfdec_audio_event.c libswfdec/swfdec_button_movie.c libswfdec/swfdec_interval.c libswfdec/swfdec_key_as.c libswfdec/swfdec_mouse_as.c libswfdec/swfdec_movie.c
- Branch 'as' - libswfdec/swfdec_graphic_movie.c libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_sprite_movie.c
- Branch 'as' - 6 commits - libswfdec/swfdec_as_interpret.c libswfdec/swfdec_movie_asprops.c libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_sprite.c libswfdec/swfdec_sprite.h libswfdec/swfdec_sprite_movie_as.c
- 7 commits - configure.ac libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_sprite_movie.c test/trace