[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