[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
Benjamin Otte
company at kemper.freedesktop.org
Thu Sep 6 00:35:42 PDT 2007
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
More information about the Swfdec
mailing list