[Swfdec] Branch 'interpreter' - 28 commits - configure.ac
libswfdec/js libswfdec/swfdec_buffer.c
libswfdec/swfdec_edittext_movie.c libswfdec/swfdec_js.c
libswfdec/swfdec_js_global.c libswfdec/swfdec_js.h
libswfdec/swfdec_js_movie.c libswfdec/swfdec_player.c
libswfdec/swfdec_player_internal.h libswfdec/swfdec_script.c
libswfdec/swfdec_swf_decoder.c test/.gitignore
test/Makefile.am test/swfdec_out.c test/swfdec_out.h
test/swfedit.c test/swfedit_file.c test/swfedit_file.h
test/swfedit_tag.c test/swfedit_tag.h test/swfedit_token.c
test/swfedit_token.h
Benjamin Otte
company at kemper.freedesktop.org
Wed Jan 24 06:13:59 PST 2007
configure.ac | 2
libswfdec/js/jsatom.c | 6
libswfdec/js/jsatom.h | 1
libswfdec/swfdec_buffer.c | 7
libswfdec/swfdec_edittext_movie.c | 4
libswfdec/swfdec_js.c | 39 +-
libswfdec/swfdec_js.h | 3
libswfdec/swfdec_js_global.c | 5
libswfdec/swfdec_js_movie.c | 1
libswfdec/swfdec_player.c | 10
libswfdec/swfdec_player_internal.h | 2
libswfdec/swfdec_script.c | 538 +++++++++++++++++++++++++++++++++++--
libswfdec/swfdec_swf_decoder.c | 2
test/.gitignore | 1
test/Makefile.am | 2
test/swfdec_out.c | 236 ++++++++++++++++
test/swfdec_out.h | 73 +++++
test/swfedit.c | 58 +++
test/swfedit_file.c | 114 ++++++-
test/swfedit_file.h | 6
test/swfedit_tag.c | 132 +++++++++
test/swfedit_tag.h | 16 -
test/swfedit_token.c | 151 ++++++----
test/swfedit_token.h | 11
24 files changed, 1275 insertions(+), 145 deletions(-)
New commits:
diff-tree 4d09855e83ee699d590e8916e4af318ab79cc99b (from 82e3f5645e07b82da355444ae96ccbb6eba637dd)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Jan 24 15:14:12 2007 +0100
implement saving
diff --git a/test/Makefile.am b/test/Makefile.am
index d168cfd..33a647c 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -19,12 +19,14 @@ swfedit_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_
swfedit_LDFLAGS = $(SWF_LIBS) $(GTK_LIBS)
swfedit_SOURCES = \
+ swfdec_out.c \
swfedit.c \
swfedit_file.c \
swfedit_tag.c \
swfedit_token.c
noinst_HEADERS = \
+ swfdec_out.h \
swfedit_file.h \
swfedit_tag.h \
swfedit_token.h
diff --git a/test/swfdec_out.c b/test/swfdec_out.c
new file mode 100644
index 0000000..70dcc7c
--- /dev/null
+++ b/test/swfdec_out.c
@@ -0,0 +1,236 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "swfdec_out.h"
+
+SwfdecOut *
+swfdec_out_open (void)
+{
+ SwfdecOut *out = g_new0 (SwfdecOut, 1);
+
+ out->data = g_malloc (SWFDEC_OUT_INITIAL);
+ out->ptr = out->data;
+ out->end = out->data + SWFDEC_OUT_INITIAL;
+
+ return out;
+}
+
+static void
+swfdec_out_syncbits (SwfdecOut *out)
+{
+ g_return_if_fail (out != NULL);
+
+ if (out->idx > 0) {
+ out->ptr++;
+ out->idx = 0;
+ }
+}
+
+SwfdecBuffer *
+swfdec_out_close (SwfdecOut *out)
+{
+ SwfdecBuffer *buffer;
+
+ g_return_val_if_fail (out != NULL, NULL);
+
+ swfdec_out_syncbits (out);
+
+ buffer = swfdec_buffer_new ();
+ buffer->data = out->data;
+ buffer->length = out->ptr - out->data;
+
+ g_free (out);
+
+ return buffer;
+}
+
+unsigned int
+swfdec_out_left (SwfdecOut *out)
+{
+ g_return_val_if_fail (out != NULL, 0);
+
+ return (out->end - out->ptr) * 8 - out->idx;
+}
+
+void
+swfdec_out_ensure_bits (SwfdecOut *out, unsigned int bits)
+{
+ unsigned int current, taken, needed;
+
+ g_return_if_fail (out != NULL);
+
+ current = swfdec_out_left (out);
+ if (current >= bits)
+ return;
+ taken = out->ptr - out->data;
+ needed = (bits - current + 7) / 8;
+ needed += SWFDEC_OUT_STEP;
+ needed -= needed % SWFDEC_OUT_STEP;
+ needed += out->end - out->data;
+ out->data = g_realloc (out->data, needed);
+ out->ptr = out->data + taken;
+ out->end = out->data + needed;
+}
+
+void
+swfdec_out_prepare_bytes (SwfdecOut *out, unsigned int bytes)
+{
+ g_return_if_fail (out != NULL);
+
+ swfdec_out_syncbits (out);
+ swfdec_out_ensure_bits (out, bytes * 8);
+}
+
+void
+swfdec_out_put_buffer (SwfdecOut *out, SwfdecBuffer *buffer)
+{
+ g_return_if_fail (out != NULL);
+
+ swfdec_out_prepare_bytes (out, buffer->length);
+ memcpy (out->ptr, buffer->data, buffer->length);
+ out->ptr += buffer->length;
+}
+
+void
+swfdec_out_put_u8 (SwfdecOut *out, guint i)
+{
+ g_return_if_fail (i <= G_MAXUINT8);
+
+ swfdec_out_prepare_bytes (out, 1);
+ *out->ptr = i;
+ out->ptr++;
+}
+
+void
+swfdec_out_put_u16 (SwfdecOut *out, guint i)
+{
+ g_return_if_fail (i <= G_MAXUINT16);
+
+ swfdec_out_prepare_bytes (out, 2);
+ *(guint16 *)out->ptr = GUINT16_TO_LE (i);
+ out->ptr += 2;
+}
+
+void
+swfdec_out_put_u32 (SwfdecOut *out, guint i)
+{
+ g_return_if_fail (i <= G_MAXUINT32);
+
+ swfdec_out_prepare_bytes (out, 4);
+ *(guint32 *)out->ptr = GUINT32_TO_LE (i);
+ out->ptr += 4;
+}
+
+void
+swfdec_out_put_bit (SwfdecOut *out, gboolean bit)
+{
+ g_return_if_fail (out != NULL);
+
+ swfdec_out_put_bits (out, bit ? 1 : 0, 1);
+}
+
+void
+swfdec_out_put_bits (SwfdecOut *out, guint bits, guint n_bits)
+{
+ g_return_if_fail (out != NULL);
+
+ swfdec_out_ensure_bits (out, n_bits);
+
+ /* FIXME: implement this less braindead */
+ while (n_bits) {
+ guint bits_now = MIN (n_bits, 8 - out->idx);
+ guint value = bits >> (n_bits - bits_now);
+
+ /* clear data if necessary */
+ if (out->idx == 0)
+ *out->ptr = 0;
+ value &= (1 << bits_now) - 1;
+ value <<= 8 - out->idx - bits_now;
+ g_print ("putting %02X in the next %u bits\n", value, bits_now);
+ *out->ptr |= value;
+ out->idx += bits_now;
+ g_assert (out->idx <= 8);
+ if (out->idx == 8) {
+ out->ptr ++;
+ out->idx = 0;
+ }
+ n_bits -= bits_now;
+ }
+}
+
+void
+swfdec_out_put_sbits (SwfdecOut *out, int bits, guint n_bits)
+{
+ g_return_if_fail (out != NULL);
+ swfdec_out_put_bits (out, bits, n_bits);
+}
+
+static guint
+swfdec_out_bits_required (guint x)
+{
+ guint ret = 0;
+
+ while (x > 0) {
+ x >>= 1;
+ ret++;
+ }
+ return ret;
+}
+
+static guint
+swfdec_out_sbits_required (int x)
+{
+ if (x < 0)
+ x = -x;
+ return swfdec_out_bits_required (x) + 1;
+}
+
+void
+swfdec_out_put_rect (SwfdecOut *out, SwfdecRect *rect)
+{
+ int x0, x1, y0, y1;
+ guint req, tmp;
+
+ g_return_if_fail (out != NULL);
+
+ x0 = rect->x0;
+ y0 = rect->y0;
+ x1 = rect->x1;
+ y1 = rect->y1;
+ req = swfdec_out_sbits_required (x0);
+ tmp = swfdec_out_sbits_required (y0);
+ req = MAX (req, tmp);
+ tmp = swfdec_out_sbits_required (x1);
+ req = MAX (req, tmp);
+ tmp = swfdec_out_sbits_required (y1);
+ req = MAX (req, tmp);
+ swfdec_out_syncbits (out);
+ swfdec_out_put_bits (out, req, 5);
+ swfdec_out_put_sbits (out, x0, req);
+ swfdec_out_put_sbits (out, x1, req);
+ swfdec_out_put_sbits (out, y0, req);
+ swfdec_out_put_sbits (out, y1, req);
+ swfdec_out_syncbits (out);
+}
diff --git a/test/swfdec_out.h b/test/swfdec_out.h
new file mode 100644
index 0000000..b6d155f
--- /dev/null
+++ b/test/swfdec_out.h
@@ -0,0 +1,73 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef __SWFDEC_OUT_H__
+#define __SWFDEC_OUT_H__
+
+#include <libswfdec/swfdec_buffer.h>
+#include <libswfdec/swfdec_rect.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _SwfdecOut SwfdecOut;
+
+struct _SwfdecOut {
+ unsigned char * data;
+ unsigned char * ptr;
+ unsigned int idx;
+ unsigned char * end;
+};
+
+#define SWFDEC_OUT_INITIAL (32)
+#define SWFDEC_OUT_STEP (32)
+
+SwfdecOut * swfdec_out_open (void);
+SwfdecBuffer * swfdec_out_close (SwfdecOut * out);
+
+unsigned int swfdec_out_left (SwfdecOut * out);
+void swfdec_out_ensure_bits (SwfdecOut * out,
+ unsigned int bits);
+void swfdec_out_prepare_bytes (SwfdecOut * out,
+ unsigned int bytes);
+
+void swfdec_out_put_bit (SwfdecOut * out,
+ gboolean bit);
+void swfdec_out_put_bits (SwfdecOut * out,
+ guint bits,
+ guint n_bits);
+void swfdec_out_put_sbits (SwfdecOut * out,
+ int bits,
+ guint n_bits);
+void swfdec_out_put_buffer (SwfdecOut * out,
+ SwfdecBuffer * buffer);
+void swfdec_out_put_u8 (SwfdecOut * out,
+ guint i);
+void swfdec_out_put_u16 (SwfdecOut * out,
+ guint i);
+void swfdec_out_put_u32 (SwfdecOut * out,
+ guint i);
+
+void swfdec_out_put_rect (SwfdecOut * out,
+ SwfdecRect * rect);
+
+
+G_END_DECLS
+
+#endif
diff --git a/test/swfedit.c b/test/swfedit.c
index e16d645..258f25e 100644
--- a/test/swfedit.c
+++ b/test/swfedit.c
@@ -27,12 +27,26 @@
static void
save (GtkButton *button, SwfeditFile *file)
{
+ GtkWidget *dialog;
GError *error = NULL;
- if (!swfedit_file_save (file, &error)) {
- g_printerr ("Error saving fils: %s\n", error->message);
- g_error_free (error);
+ dialog = gtk_file_chooser_dialog_new ("Save file...",
+ GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (button))),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_OK,
+ NULL);
+ gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
+ gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog), file->filename);
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
+ g_free (file->filename);
+ file->filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+ if (!swfedit_file_save (file, &error)) {
+ g_printerr ("Error saving file: %s\n", error->message);
+ g_error_free (error);
+ }
}
+ gtk_widget_destroy (dialog);
}
static void
diff --git a/test/swfedit_file.c b/test/swfedit_file.c
index d660655..dd5e035 100644
--- a/test/swfedit_file.c
+++ b/test/swfedit_file.c
@@ -27,6 +27,7 @@
#include "libswfdec/swfdec_buffer.h"
#include "libswfdec/swfdec_debug.h"
#include "libswfdec/swfdec_swf_decoder.h"
+#include "swfdec_out.h"
#include "swfedit_file.h"
#include "swfedit_tag.h"
@@ -103,7 +104,7 @@ swf_parse_header1 (SwfeditFile *file, Sw
swfedit_token_add (SWFEDIT_TOKEN (file), "version", SWFEDIT_TOKEN_UINT8,
GUINT_TO_POINTER (swfdec_bits_get_u8 (bits)));
- bytes_total = swfdec_bits_get_u32 (bits);
+ bytes_total = swfdec_bits_get_u32 (bits) - 8;
if (sig1 == 'C') {
/* compressed */
@@ -113,7 +114,7 @@ swf_parse_header1 (SwfeditFile *file, Sw
"Unable to uncompress file");
return ret;
} else {
- SwfdecBuffer *ret = swfdec_bits_get_buffer (bits, -1);
+ SwfdecBuffer *ret = swfdec_bits_get_buffer (bits, bytes_total);
if (ret == NULL)
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
"File too small");
@@ -124,14 +125,9 @@ swf_parse_header1 (SwfeditFile *file, Sw
static void
swf_parse_header2 (SwfeditFile *file, SwfdecBits *bits)
{
- SwfdecRect rect;
-
- swfdec_bits_get_rect (bits, &rect);
- swfdec_bits_syncbits (bits);
- swfedit_token_add (SWFEDIT_TOKEN (file), "rate", SWFEDIT_TOKEN_UINT16,
- GUINT_TO_POINTER (swfdec_bits_get_u16 (bits)));
- swfedit_token_add (SWFEDIT_TOKEN (file), "frames", SWFEDIT_TOKEN_UINT16,
- GUINT_TO_POINTER (swfdec_bits_get_u16 (bits)));
+ swfedit_tag_read_token (SWFEDIT_TOKEN (file), bits, "rect", SWFEDIT_TOKEN_RECT);
+ swfedit_tag_read_token (SWFEDIT_TOKEN (file), bits, "rate", SWFEDIT_TOKEN_UINT16);
+ swfedit_tag_read_token (SWFEDIT_TOKEN (file), bits, "frames", SWFEDIT_TOKEN_UINT16);
}
static gboolean
@@ -193,13 +189,21 @@ swfedit_file_new (const char *filename,
SwfeditFile *file;
SwfdecBuffer *buffer;
SwfdecBits bits;
+ char *absolute;
+ if (g_path_is_absolute (filename)) {
+ absolute = g_strdup (filename);
+ } else {
+ char *dir = g_get_current_dir ();
+ absolute = g_build_filename (dir, filename, NULL);
+ g_free (dir);
+ }
buffer = swfdec_buffer_new_from_file (filename, error);
if (buffer == NULL)
return NULL;
swfdec_bits_init (&bits, buffer);
file = g_object_new (SWFEDIT_TYPE_FILE, NULL);
- file->filename = g_strdup (filename);
+ file->filename = absolute;
if (!swfedit_file_parse (file, &bits, error)) {
swfdec_buffer_unref (buffer);
g_object_unref (file);
@@ -212,7 +216,53 @@ swfedit_file_new (const char *filename,
static SwfdecBuffer *
swfedit_file_write (SwfeditFile *file)
{
- return NULL;
+ guint i;
+ SwfeditToken *token = SWFEDIT_TOKEN (file);
+ SwfdecBufferQueue *queue;
+ SwfdecBuffer *buffer;
+ SwfdecOut *out;
+
+ queue = swfdec_buffer_queue_new ();
+ /* write second part of header */
+ out = swfdec_out_open ();
+ swfedit_tag_write_token (token, out, 1);
+ swfedit_tag_write_token (token, out, 2);
+ swfedit_tag_write_token (token, out, 3);
+ swfdec_buffer_queue_push (queue, swfdec_out_close (out));
+
+ for (i = 4; i < token->tokens->len; i++) {
+ SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, i);
+ g_assert (entry->type == SWFEDIT_TOKEN_OBJECT);
+
+ buffer = swfedit_tag_write (entry->value);
+ out = swfdec_out_open ();
+ swfdec_out_put_u16 (out, SWFEDIT_TAG (entry->value)->tag << 6 |
+ MIN (buffer->length, 0x3f));
+ if (buffer->length >= 0x3f) {
+ swfdec_out_put_u32 (out, buffer->length);
+ }
+ swfdec_buffer_queue_push (queue, swfdec_out_close (out));
+ swfdec_buffer_queue_push (queue, buffer);
+ }
+ /* write closing tag */
+ buffer = swfdec_buffer_new_and_alloc0 (2);
+ swfdec_buffer_queue_push (queue, buffer);
+
+ /* FIXME: implement compression */
+ out = swfdec_out_open ();
+ swfdec_out_put_u8 (out, 'F');
+ swfdec_out_put_u8 (out, 'W');
+ swfdec_out_put_u8 (out, 'S');
+ swfedit_tag_write_token (token, out, 0);
+ g_print ("length: %u", swfdec_buffer_queue_get_depth (queue));
+ swfdec_out_put_u32 (out, swfdec_buffer_queue_get_depth (queue) + 8);
+ swfdec_out_prepare_bytes (out, swfdec_buffer_queue_get_depth (queue));
+ while ((buffer = swfdec_buffer_queue_pull_buffer (queue))) {
+ swfdec_out_put_buffer (out, buffer);
+ swfdec_buffer_unref (buffer);
+ }
+ swfdec_buffer_queue_free (queue);
+ return swfdec_out_close (out);
}
gboolean
diff --git a/test/swfedit_tag.c b/test/swfedit_tag.c
index 94ac4f9..0a9fb9b 100644
--- a/test/swfedit_tag.c
+++ b/test/swfedit_tag.c
@@ -23,7 +23,134 @@
#include <stdlib.h>
#include <gtk/gtk.h>
+
+#include <libswfdec/swfdec_bits.h>
#include "swfedit_tag.h"
+#include "swfdec_out.h"
+
+/*** LOAD/SAVE ***/
+
+static void
+swfedit_binary_write (gpointer data, SwfdecOut *out)
+{
+ swfdec_out_put_buffer (out, data);
+}
+
+static gpointer
+swfedit_binary_read (SwfdecBits *bits)
+{
+ SwfdecBuffer *buffer = swfdec_bits_get_buffer (bits, -1);
+ if (buffer == NULL)
+ buffer = swfdec_buffer_new ();
+ return buffer;
+}
+
+static void
+swfedit_u8_write (gpointer data, SwfdecOut *out)
+{
+ swfdec_out_put_u8 (out, GPOINTER_TO_UINT (data));
+}
+
+static gpointer
+swfedit_u8_read (SwfdecBits *bits)
+{
+ return GUINT_TO_POINTER (swfdec_bits_get_u8 (bits));
+}
+
+static void
+swfedit_u16_write (gpointer data, SwfdecOut *out)
+{
+ swfdec_out_put_u16 (out, GPOINTER_TO_UINT (data));
+}
+
+static gpointer
+swfedit_u16_read (SwfdecBits *bits)
+{
+ return GUINT_TO_POINTER (swfdec_bits_get_u16 (bits));
+}
+
+static void
+swfedit_u32_write (gpointer data, SwfdecOut *out)
+{
+ swfdec_out_put_u32 (out, GPOINTER_TO_UINT (data));
+}
+
+static gpointer
+swfedit_u32_read (SwfdecBits *bits)
+{
+ return GUINT_TO_POINTER (swfdec_bits_get_u32 (bits));
+}
+
+static void
+swfedit_rect_write (gpointer data, SwfdecOut *out)
+{
+ swfdec_out_put_rect (out, data);
+}
+
+static gpointer
+swfedit_rect_read (SwfdecBits *bits)
+{
+ SwfdecRect *rect = g_new (SwfdecRect, 1);
+ swfdec_bits_get_rect (bits, rect);
+ return rect;
+}
+
+struct {
+ void (* write) (gpointer data, SwfdecOut *out);
+ gpointer (* read) (SwfdecBits *bits);
+} operations[SWFEDIT_N_TOKENS] = {
+ { NULL, NULL },
+ { swfedit_binary_write, swfedit_binary_read },
+ { swfedit_u8_write, swfedit_u8_read },
+ { swfedit_u16_write, swfedit_u16_read },
+ { swfedit_u32_write, swfedit_u32_read },
+ { swfedit_rect_write, swfedit_rect_read },
+};
+
+void
+swfedit_tag_write_token (SwfeditToken *token, SwfdecOut *out, guint i)
+{
+ SwfeditTokenEntry *entry;
+
+ g_return_if_fail (SWFEDIT_IS_TOKEN (token));
+ g_return_if_fail (i < token->tokens->len);
+
+ entry = &g_array_index (token->tokens,
+ SwfeditTokenEntry, i);
+ g_assert (operations[entry->type].write != NULL);
+ operations[entry->type].write (entry->value, out);
+}
+
+SwfdecBuffer *
+swfedit_tag_write (SwfeditTag *tag)
+{
+ guint i;
+ SwfdecOut *out;
+
+ g_return_val_if_fail (SWFEDIT_IS_TAG (tag), NULL);
+
+ out = swfdec_out_open ();
+ for (i = 0; i < SWFEDIT_TOKEN (tag)->tokens->len; i++) {
+ swfedit_tag_write_token (SWFEDIT_TOKEN (tag), out, i);
+ }
+ return swfdec_out_close (out);
+}
+
+void
+swfedit_tag_read_token (SwfeditToken *token, SwfdecBits *bits,
+ const char *name, SwfeditTokenType type)
+{
+ gpointer data;
+
+ g_return_if_fail (SWFEDIT_IS_TOKEN (token));
+ g_return_if_fail (name != NULL);
+
+ g_assert (operations[type].read != NULL);
+ data = operations[type].read (bits);
+ swfedit_token_add (token, name, type, data);
+}
+
+/*** SWFEDIT_TAG ***/
G_DEFINE_TYPE (SwfeditTag, swfedit_tag, SWFEDIT_TYPE_TOKEN)
diff --git a/test/swfedit_tag.h b/test/swfedit_tag.h
index 07c11f2..46fdb5f 100644
--- a/test/swfedit_tag.h
+++ b/test/swfedit_tag.h
@@ -21,6 +21,7 @@
#define __SWFEDIT_TAG_H__
#include <libswfdec/swfdec_buffer.h>
+#include "swfdec_out.h"
#include "swfedit_token.h"
G_BEGIN_DECLS
@@ -47,10 +48,18 @@ struct _SwfeditTagClass {
GType swfedit_tag_get_type (void);
-SwfeditTag * swfedit_tag_new (SwfeditToken * parent,
- guint tag,
- SwfdecBuffer * buffer);
-
+SwfeditTag * swfedit_tag_new (SwfeditToken * parent,
+ guint tag,
+ SwfdecBuffer * buffer);
+
+SwfdecBuffer * swfedit_tag_write (SwfeditTag * tag);
+void swfedit_tag_write_token (SwfeditToken * token,
+ SwfdecOut * out,
+ guint i);
+void swfedit_tag_read_token (SwfeditToken * token,
+ SwfdecBits * bits,
+ const char * name,
+ SwfeditTokenType type);
G_END_DECLS
diff --git a/test/swfedit_token.c b/test/swfedit_token.c
index f3623fc..b2210fd 100644
--- a/test/swfedit_token.c
+++ b/test/swfedit_token.c
@@ -125,6 +125,21 @@ swfedit_to_string_unsigned (gconstpointe
return g_strdup_printf ("%u", GPOINTER_TO_UINT (value));
}
+static gboolean
+swfedit_rect_from_string (const char *s, gpointer* result)
+{
+ return FALSE;
+}
+
+static char *
+swfedit_rect_to_string (gconstpointer value)
+{
+ const SwfdecRect *rect = value;
+
+ return g_strdup_printf ("%d, %d, %d, %d", (int) rect->x0, (int) rect->y0,
+ (int) rect->x1, (int) rect->y1);
+}
+
struct {
gboolean (* from_string) (const char *s, gpointer *);
char * (* to_string) (gconstpointer value);
@@ -135,6 +150,7 @@ struct {
{ swfedit_uint8_from_string, swfedit_to_string_unsigned, NULL },
{ swfedit_uint16_from_string, swfedit_to_string_unsigned, NULL },
{ swfedit_uint32_from_string, swfedit_to_string_unsigned, NULL },
+ { swfedit_rect_from_string, swfedit_rect_to_string, g_free },
};
/*** GTK_TREE_MODEL ***/
diff --git a/test/swfedit_token.h b/test/swfedit_token.h
index 5235d03..8dec753 100644
--- a/test/swfedit_token.h
+++ b/test/swfedit_token.h
@@ -31,6 +31,7 @@ typedef enum {
SWFEDIT_TOKEN_UINT8,
SWFEDIT_TOKEN_UINT16,
SWFEDIT_TOKEN_UINT32,
+ SWFEDIT_TOKEN_RECT,
SWFEDIT_N_TOKENS
} SwfeditTokenType;
diff-tree 82e3f5645e07b82da355444ae96ccbb6eba637dd (from 89df12bea205242dd0554a48a0e7721de67d531b)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Jan 24 15:13:58 2007 +0100
add swfedit
diff --git a/test/.gitignore b/test/.gitignore
index ef52ce4..9280a20 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -11,3 +11,4 @@ Makefile.in
dump
parse
swfdec-extract
+swfedit
diff-tree 89df12bea205242dd0554a48a0e7721de67d531b (from 91403c6d7fbda752ba3403e676d679afdb2bf1b0)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Jan 24 15:11:05 2007 +0100
We need at least gtk-2.8
diff --git a/configure.ac b/configure.ac
index eb69535..fbf58c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -78,7 +78,7 @@ fi
AC_SUBST(PANGO_LIBS)
AC_SUBST(PANGO_CFLAGS)
-PKG_CHECK_MODULES(GTK, gtk+-2.0, HAVE_GTK=yes, HAVE_GTK=no)
+PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.8.0, HAVE_GTK=yes, HAVE_GTK=no)
AC_SUBST(GTK_LIBS)
AC_SUBST(GTK_CFLAGS)
if test "$HAVE_GTK" = "no"; then
diff-tree 91403c6d7fbda752ba3403e676d679afdb2bf1b0 (from 800b8b573d0d3553336f8541163a4731888bfbbb)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Jan 24 15:10:35 2007 +0100
we don't have the header in the uncompressed buffer
diff --git a/libswfdec/swfdec_swf_decoder.c b/libswfdec/swfdec_swf_decoder.c
index 6539921..0bc1099 100644
--- a/libswfdec/swfdec_swf_decoder.c
+++ b/libswfdec/swfdec_swf_decoder.c
@@ -143,7 +143,7 @@ swf_inflate_init (SwfdecSwfDecoder * s)
ret = inflateInit (z);
SWFDEC_DEBUG ("inflateInit returned %d", ret);
- s->uncompressed_buffer = swfdec_buffer_new_and_alloc (dec->bytes_total);
+ s->uncompressed_buffer = swfdec_buffer_new_and_alloc (dec->bytes_total - 8);
z->next_out = s->uncompressed_buffer->data;
z->avail_out = s->uncompressed_buffer->length;
z->opaque = NULL;
diff-tree 800b8b573d0d3553336f8541163a4731888bfbbb (from b32e8c5b76f4dfde34c72057feb9d9970bea2e7a)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Jan 24 15:10:04 2007 +0100
ignore 0-length buffers in bufferqueue
diff --git a/libswfdec/swfdec_buffer.c b/libswfdec/swfdec_buffer.c
index 3e9af24..c4ac67e 100644
--- a/libswfdec/swfdec_buffer.c
+++ b/libswfdec/swfdec_buffer.c
@@ -177,6 +177,13 @@ swfdec_buffer_queue_free (SwfdecBufferQu
void
swfdec_buffer_queue_push (SwfdecBufferQueue * queue, SwfdecBuffer * buffer)
{
+ g_return_if_fail (queue != NULL);
+ g_return_if_fail (buffer != NULL);
+
+ if (buffer->length == 0) {
+ swfdec_buffer_unref (buffer);
+ return;
+ }
queue->buffers = g_list_append (queue->buffers, buffer);
queue->depth += buffer->length;
}
diff-tree b32e8c5b76f4dfde34c72057feb9d9970bea2e7a (from 3d7f4a9fd93c17adc999370d40eff49d1983f126)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Jan 23 15:16:17 2007 +0100
export the entry format and rename it to SwfeditTokenEntry
diff --git a/test/swfedit_token.c b/test/swfedit_token.c
index bb1e76b..f3623fc 100644
--- a/test/swfedit_token.c
+++ b/test/swfedit_token.c
@@ -137,14 +137,6 @@ struct {
{ swfedit_uint32_from_string, swfedit_to_string_unsigned, NULL },
};
-/*** STRUCTS ***/
-
-typedef struct {
- char * name;
- SwfeditTokenType type;
- gpointer value;
-} Entry;
-
/*** GTK_TREE_MODEL ***/
#if 0
@@ -191,12 +183,12 @@ swfedit_token_get_iter (GtkTreeModel *tr
{
SwfeditToken *token = SWFEDIT_TOKEN (tree_model);
guint i = gtk_tree_path_get_indices (path)[0];
- Entry *entry;
+ SwfeditTokenEntry *entry;
REPORT;
if (i > token->tokens->len)
return FALSE;
- entry = &g_array_index (token->tokens, Entry, i);
+ entry = &g_array_index (token->tokens, SwfeditTokenEntry, i);
if (gtk_tree_path_get_depth (path) > 1) {
GtkTreePath *new;
int j;
@@ -232,7 +224,7 @@ swfedit_token_get_path (GtkTreeModel *tr
guint i;
SwfeditToken *parent = token->parent;
for (i = 0; i < parent->tokens->len; i++) {
- Entry *entry = &g_array_index (parent->tokens, Entry, i);
+ SwfeditTokenEntry *entry = &g_array_index (parent->tokens, SwfeditTokenEntry, i);
if (entry->type != SWFEDIT_TOKEN_OBJECT)
continue;
if (entry->value == token)
@@ -249,7 +241,7 @@ swfedit_token_get_value (GtkTreeModel *t
gint column, GValue *value)
{
SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data);
- Entry *entry = &g_array_index (token->tokens, Entry, GPOINTER_TO_INT (iter->user_data2));
+ SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (iter->user_data2));
REPORT;
switch (column) {
@@ -289,12 +281,12 @@ static gboolean
swfedit_token_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
{
SwfeditToken *token;
- Entry *entry;
+ SwfeditTokenEntry *entry;
REPORT;
if (parent) {
token = SWFEDIT_TOKEN (parent->user_data);
- entry = &g_array_index (token->tokens, Entry, GPOINTER_TO_INT (parent->user_data2));
+ entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (parent->user_data2));
if (entry->type != SWFEDIT_TOKEN_OBJECT)
return FALSE;
token = entry->value;
@@ -311,7 +303,7 @@ static gboolean
swfedit_token_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter)
{
SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data);
- Entry *entry = &g_array_index (token->tokens, Entry, GPOINTER_TO_INT (iter->user_data2));
+ SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (iter->user_data2));
REPORT;
return entry->type == SWFEDIT_TOKEN_OBJECT;
@@ -321,7 +313,7 @@ static gint
swfedit_token_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *iter)
{
SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data);
- Entry *entry = &g_array_index (token->tokens, Entry, GPOINTER_TO_INT (iter->user_data2));
+ SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (iter->user_data2));
REPORT;
if (entry->type != SWFEDIT_TOKEN_OBJECT)
@@ -336,12 +328,12 @@ swfedit_token_iter_nth_child (GtkTreeMod
GtkTreeIter *parent, gint n)
{
SwfeditToken *token;
- Entry *entry;
+ SwfeditTokenEntry *entry;
REPORT;
if (parent) {
token = SWFEDIT_TOKEN (parent->user_data);
- entry = &g_array_index (token->tokens, Entry, GPOINTER_TO_INT (parent->user_data2));
+ entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (parent->user_data2));
if (entry->type != SWFEDIT_TOKEN_OBJECT)
return FALSE;
@@ -370,7 +362,7 @@ swfedit_token_iter_parent (GtkTreeModel
return FALSE;
for (i = 0; i < parent->tokens->len; i++) {
- Entry *entry = &g_array_index (parent->tokens, Entry, i);
+ SwfeditTokenEntry *entry = &g_array_index (parent->tokens, SwfeditTokenEntry, i);
if (entry->type != SWFEDIT_TOKEN_OBJECT)
continue;
if (entry->value == token)
@@ -411,7 +403,7 @@ swfedit_token_dispose (GObject *object)
guint i;
for (i = 0; i < token->tokens->len; i++) {
- Entry *entry = &g_array_index (token->tokens, Entry, i);
+ SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, i);
g_free (entry->name);
if (converters[entry->type].free)
converters[entry->type].free (entry->value);
@@ -432,7 +424,7 @@ swfedit_token_class_init (SwfeditTokenCl
static void
swfedit_token_init (SwfeditToken *token)
{
- token->tokens = g_array_new (FALSE, FALSE, sizeof (Entry));
+ token->tokens = g_array_new (FALSE, FALSE, sizeof (SwfeditTokenEntry));
}
SwfeditToken *
@@ -447,7 +439,7 @@ swfedit_token_new (void)
void
swfedit_token_add (SwfeditToken *token, const char *name, SwfeditTokenType type, gpointer value)
{
- Entry entry = { NULL, type, value };
+ SwfeditTokenEntry entry = { NULL, type, value };
g_return_if_fail (SWFEDIT_IS_TOKEN (token));
g_return_if_fail (name != NULL);
@@ -461,7 +453,7 @@ void
swfedit_token_set (SwfeditToken *token, GtkTreeIter *iter, const char *value)
{
GtkTreeModel *model;
- Entry *entry;
+ SwfeditTokenEntry *entry;
guint i;
gpointer new;
GtkTreePath *path;
@@ -473,7 +465,7 @@ swfedit_token_set (SwfeditToken *token,
model = GTK_TREE_MODEL (token);
token = iter->user_data;
i = GPOINTER_TO_UINT (iter->user_data2);
- entry = &g_array_index (token->tokens, Entry, i);
+ entry = &g_array_index (token->tokens, SwfeditTokenEntry, i);
if (converters[entry->type].from_string == NULL)
return;
if (!converters[entry->type].from_string (value, &new))
diff --git a/test/swfedit_token.h b/test/swfedit_token.h
index 1640027..5235d03 100644
--- a/test/swfedit_token.h
+++ b/test/swfedit_token.h
@@ -40,6 +40,8 @@ typedef enum {
SWFEDIT_COLUMN_VALUE
} SwfeditColumn;
+typedef struct _SwfeditTokenEntry SwfeditTokenEntry;
+
typedef struct _SwfeditToken SwfeditToken;
typedef struct _SwfeditTokenClass SwfeditTokenClass;
@@ -50,12 +52,18 @@ typedef struct _SwfeditTokenClass Swfedi
#define SWFEDIT_TOKEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFEDIT_TYPE_TOKEN, SwfeditTokenClass))
#define SWFEDIT_TOKEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFEDIT_TYPE_TOKEN, SwfeditTokenClass))
+struct _SwfeditTokenEntry {
+ char * name;
+ SwfeditTokenType type;
+ gpointer value;
+};
+
struct _SwfeditToken {
GObject object;
SwfeditToken * parent; /* parent of this token or NULL */
gchar * name; /* name of token */
- GArray * tokens; /* list of tokens */
+ GArray * tokens; /* of SwfeditTokenEntry */
};
struct _SwfeditTokenClass {
diff-tree 3d7f4a9fd93c17adc999370d40eff49d1983f126 (from 705e9e78e30cdb063445873c670cdbdfb918d07e)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Jan 23 14:41:40 2007 +0100
add stubs for saving
diff --git a/test/swfedit.c b/test/swfedit.c
index 5dd2535..e16d645 100644
--- a/test/swfedit.c
+++ b/test/swfedit.c
@@ -25,6 +25,17 @@
#include "swfedit_file.h"
static void
+save (GtkButton *button, SwfeditFile *file)
+{
+ GError *error = NULL;
+
+ if (!swfedit_file_save (file, &error)) {
+ g_printerr ("Error saving fils: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
cell_renderer_edited (GtkCellRenderer *renderer, char *path,
char *new_text, SwfeditFile *file)
{
@@ -41,26 +52,29 @@ static gboolean
open_window (char *filename)
{
SwfeditFile *file;
- GtkWidget *window, *scroll, *treeview;
+ GtkWidget *window, *scroll, *box, *button, *treeview;
GError *error = NULL;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
file = swfedit_file_new (filename, &error);
if (file == NULL) {
- g_printerr ("Error openeing file %s: %s\n", filename, error->message);
+ g_printerr ("Error opening file %s: %s\n", filename, error->message);
g_error_free (error);
return FALSE;
}
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (window), filename);
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+ box = gtk_vbox_new (FALSE, 3);
+ gtk_container_add (GTK_CONTAINER (window), box);
+
scroll = gtk_scrolled_window_new (NULL, NULL);
- gtk_container_add (GTK_CONTAINER (window), scroll);
+ gtk_box_pack_start (GTK_BOX (box), scroll, TRUE, TRUE, 0);
treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (file));
gtk_container_add (GTK_CONTAINER (scroll), treeview);
- gtk_widget_show_all (window);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Name", renderer,
@@ -76,6 +90,11 @@ open_window (char *filename)
gtk_tree_view_column_set_resizable (column, TRUE);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+ button = gtk_button_new_from_stock (GTK_STOCK_SAVE);
+ g_signal_connect (button, "clicked", G_CALLBACK (save), file);
+ gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0);
+
+ gtk_widget_show_all (window);
return TRUE;
}
diff --git a/test/swfedit_file.c b/test/swfedit_file.c
index 7f2f240..d660655 100644
--- a/test/swfedit_file.c
+++ b/test/swfedit_file.c
@@ -37,8 +37,6 @@ swfedit_file_dispose (GObject *object)
{
SwfeditFile *file = SWFEDIT_FILE (object);
- g_list_foreach (file->tags, (GFunc) g_object_unref, NULL);
- g_list_free (file->tags);
g_free (file->filename);
G_OBJECT_CLASS (swfedit_file_parent_class)->dispose (object);
@@ -210,3 +208,30 @@ swfedit_file_new (const char *filename,
swfdec_buffer_unref (buffer);
return file;
}
+
+static SwfdecBuffer *
+swfedit_file_write (SwfeditFile *file)
+{
+ return NULL;
+}
+
+gboolean
+swfedit_file_save (SwfeditFile *file, GError **error)
+{
+ SwfdecBuffer *buffer;
+ gboolean ret;
+
+ g_return_val_if_fail (SWFEDIT_IS_FILE (file), FALSE);
+
+ buffer = swfedit_file_write (file);
+ if (buffer == NULL) {
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ "Failed to render file");
+ return FALSE;
+ }
+ ret = g_file_set_contents (file->filename, (char *) buffer->data,
+ buffer->length, error);
+ swfdec_buffer_unref (buffer);
+ return ret;
+}
+
diff --git a/test/swfedit_file.h b/test/swfedit_file.h
index 39a89c5..e904950 100644
--- a/test/swfedit_file.h
+++ b/test/swfedit_file.h
@@ -39,9 +39,6 @@ struct _SwfeditFile {
SwfeditToken token;
char * filename; /* name this file is saved to */
-
- /* defined objects */
- GList * tags; /* ordered list of all tags in the file */
};
struct _SwfeditFileClass {
@@ -53,6 +50,9 @@ GType swfedit_file_get_type (void);
SwfeditFile * swfedit_file_new (const char * filename,
GError ** error);
+gboolean swfedit_file_save (SwfeditFile * file,
+ GError ** error);
+
G_END_DECLS
diff-tree 705e9e78e30cdb063445873c670cdbdfb918d07e (from ce02af774584cc4bb00655d77b6e7e350b77402c)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Jan 23 14:41:24 2007 +0100
change read/write to from_string/to_string
diff --git a/test/swfedit_token.c b/test/swfedit_token.c
index 2819b52..bb1e76b 100644
--- a/test/swfedit_token.c
+++ b/test/swfedit_token.c
@@ -12,7 +12,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
+ * License along with this library; if not, to_string to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
@@ -29,7 +29,7 @@
/*** CONVERTERS ***/
static gboolean
-swfedit_binary_read (const char *s, gpointer* result)
+swfedit_binary_from_string (const char *s, gpointer* result)
{
GByteArray *array = g_byte_array_new ();
guint8 byte;
@@ -71,7 +71,7 @@ swfedit_binary_read (const char *s, gpoi
}
static char *
-swfedit_binary_write (gconstpointer value)
+swfedit_binary_to_string (gconstpointer value)
{
guint i;
const SwfdecBuffer *buffer = value;
@@ -86,7 +86,7 @@ swfedit_binary_write (gconstpointer valu
}
static gboolean
-swfedit_read_unsigned (const char *s, gulong max, gpointer* result)
+swfedit_from_string_unsigned (const char *s, gulong max, gpointer* result)
{
char *end;
gulong u;
@@ -102,39 +102,39 @@ swfedit_read_unsigned (const char *s, gu
}
static gboolean
-swfedit_uint8_read (const char *s, gpointer* result)
+swfedit_uint8_from_string (const char *s, gpointer* result)
{
- return swfedit_read_unsigned (s, G_MAXUINT8, result);
+ return swfedit_from_string_unsigned (s, G_MAXUINT8, result);
}
static gboolean
-swfedit_uint16_read (const char *s, gpointer* result)
+swfedit_uint16_from_string (const char *s, gpointer* result)
{
- return swfedit_read_unsigned (s, G_MAXUINT16, result);
+ return swfedit_from_string_unsigned (s, G_MAXUINT16, result);
}
static gboolean
-swfedit_uint32_read (const char *s, gpointer* result)
+swfedit_uint32_from_string (const char *s, gpointer* result)
{
- return swfedit_read_unsigned (s, G_MAXUINT32, result);
+ return swfedit_from_string_unsigned (s, G_MAXUINT32, result);
}
static char *
-swfedit_write_unsigned (gconstpointer value)
+swfedit_to_string_unsigned (gconstpointer value)
{
return g_strdup_printf ("%u", GPOINTER_TO_UINT (value));
}
struct {
- gboolean (* read) (const char *s, gpointer *);
- char * (* write) (gconstpointer value);
+ gboolean (* from_string) (const char *s, gpointer *);
+ char * (* to_string) (gconstpointer value);
void (* free) (gpointer value);
} converters[SWFEDIT_N_TOKENS] = {
{ NULL, NULL, g_object_unref },
- { swfedit_binary_read, swfedit_binary_write, (GDestroyNotify) swfdec_buffer_unref },
- { swfedit_uint8_read, swfedit_write_unsigned, NULL },
- { swfedit_uint16_read, swfedit_write_unsigned, NULL },
- { swfedit_uint32_read, swfedit_write_unsigned, NULL },
+ { swfedit_binary_from_string, swfedit_binary_to_string, (GDestroyNotify) swfdec_buffer_unref },
+ { swfedit_uint8_from_string, swfedit_to_string_unsigned, NULL },
+ { swfedit_uint16_from_string, swfedit_to_string_unsigned, NULL },
+ { swfedit_uint32_from_string, swfedit_to_string_unsigned, NULL },
};
/*** STRUCTS ***/
@@ -259,12 +259,12 @@ swfedit_token_get_value (GtkTreeModel *t
return;
case SWFEDIT_COLUMN_VALUE_VISIBLE:
g_value_init (value, G_TYPE_BOOLEAN);
- g_value_set_boolean (value, converters[entry->type].write != NULL);
+ g_value_set_boolean (value, converters[entry->type].to_string != NULL);
return;
case SWFEDIT_COLUMN_VALUE:
g_value_init (value, G_TYPE_STRING);
- if (converters[entry->type].write)
- g_value_take_string (value, converters[entry->type].write (entry->value));
+ if (converters[entry->type].to_string)
+ g_value_take_string (value, converters[entry->type].to_string (entry->value));
return;
default:
break;
@@ -474,9 +474,9 @@ swfedit_token_set (SwfeditToken *token,
token = iter->user_data;
i = GPOINTER_TO_UINT (iter->user_data2);
entry = &g_array_index (token->tokens, Entry, i);
- if (converters[entry->type].read == NULL)
+ if (converters[entry->type].from_string == NULL)
return;
- if (!converters[entry->type].read (value, &new))
+ if (!converters[entry->type].from_string (value, &new))
return;
if (converters[entry->type].free != NULL)
converters[entry->type].free (entry->value);
diff-tree ce02af774584cc4bb00655d77b6e7e350b77402c (from b5b36b679993d6c5576dc83f4deacd80fe2e5ce3)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Jan 23 10:05:46 2007 +0100
enable editing of properties
diff --git a/test/swfedit.c b/test/swfedit.c
index 71a86aa..5dd2535 100644
--- a/test/swfedit.c
+++ b/test/swfedit.c
@@ -24,6 +24,19 @@
#include <gtk/gtk.h>
#include "swfedit_file.h"
+static void
+cell_renderer_edited (GtkCellRenderer *renderer, char *path,
+ char *new_text, SwfeditFile *file)
+{
+ GtkTreeIter iter;
+
+ if (!gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (file),
+ &iter, path)) {
+ g_assert_not_reached ();
+ }
+ swfedit_token_set (SWFEDIT_TOKEN (file), &iter, new_text);
+}
+
static gboolean
open_window (char *filename)
{
@@ -57,6 +70,7 @@ open_window (char *filename)
renderer = gtk_cell_renderer_text_new ();
g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
+ g_signal_connect (renderer, "edited", G_CALLBACK (cell_renderer_edited), file);
column = gtk_tree_view_column_new_with_attributes ("Value", renderer,
"text", SWFEDIT_COLUMN_VALUE, "visible", SWFEDIT_COLUMN_VALUE_VISIBLE, NULL);
gtk_tree_view_column_set_resizable (column, TRUE);
diff-tree b5b36b679993d6c5576dc83f4deacd80fe2e5ce3 (from d6679238c4929bf1d9cbb997b1ba9987c018e01e)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Jan 23 10:05:35 2007 +0100
make parsing binary data work
diff --git a/test/swfedit_token.c b/test/swfedit_token.c
index 4e027eb..2819b52 100644
--- a/test/swfedit_token.c
+++ b/test/swfedit_token.c
@@ -45,13 +45,13 @@ swfedit_binary_read (const char *s, gpoi
else
break;
s++;
- byte *= 255;
+ byte *= 16;
if (s[0] >= '0' && s[0] <= '9')
- byte = s[0] - '0';
+ byte += s[0] - '0';
else if (s[0] >= 'a' && s[0] <= 'f')
- byte = s[0] + 10 - 'a';
+ byte += s[0] + 10 - 'a';
else if (s[0] >= 'A' && s[0] <= 'F')
- byte = s[0] + 10 - 'A';
+ byte += s[0] + 10 - 'A';
else
break;
s++;
diff-tree d6679238c4929bf1d9cbb997b1ba9987c018e01e (from 1af4da9dd02f8d5cd65b06bf25c6ac013bc26450)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Jan 23 10:04:05 2007 +0100
ensure _get_nth_child works with token == NULL
I hate it that you need -O2 to catch uninitialized variables
diff --git a/test/swfedit_token.c b/test/swfedit_token.c
index 704b98b..4e027eb 100644
--- a/test/swfedit_token.c
+++ b/test/swfedit_token.c
@@ -347,9 +347,11 @@ swfedit_token_iter_nth_child (GtkTreeMod
return FALSE;
token = entry->value;
- if ((guint) n >= token->tokens->len)
- return FALSE;
+ } else {
+ token = SWFEDIT_TOKEN (tree_model);
}
+ if ((guint) n >= token->tokens->len)
+ return FALSE;
iter->stamp = 0; /* FIXME */
iter->user_data = token;
iter->user_data2 = GINT_TO_POINTER (n);
diff-tree 1af4da9dd02f8d5cd65b06bf25c6ac013bc26450 (from 97ce107c67c3bcbd363eaf12e3669ca8226e4143)
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Jan 22 22:05:34 2007 +0100
print the actual tag name
diff --git a/test/swfedit_file.c b/test/swfedit_file.c
index 2ae8fa2..7f2f240 100644
--- a/test/swfedit_file.c
+++ b/test/swfedit_file.c
@@ -26,6 +26,7 @@
#include "libswfdec/swfdec_bits.h"
#include "libswfdec/swfdec_buffer.h"
#include "libswfdec/swfdec_debug.h"
+#include "libswfdec/swfdec_swf_decoder.h"
#include "swfedit_file.h"
#include "swfedit_tag.h"
@@ -152,7 +153,7 @@ swfedit_file_parse (SwfeditFile *file, S
guint tag_len = x & 0x3f;
SwfdecBuffer *buffer;
SwfeditTag *item;
- char *name;
+
if (tag_len == 0x3f)
tag_len = swfdec_bits_get_u32 (bits);
if (tag == 0)
@@ -167,9 +168,9 @@ swfedit_file_parse (SwfeditFile *file, S
return FALSE;
}
item = swfedit_tag_new (SWFEDIT_TOKEN (file), tag, buffer);
- name = g_strdup_printf ("Tag %u", tag);
- swfedit_token_add (SWFEDIT_TOKEN (file), name, SWFEDIT_TOKEN_OBJECT, item);
- g_free (name);
+ swfedit_token_add (SWFEDIT_TOKEN (file),
+ swfdec_swf_decoder_get_tag_name (tag),
+ SWFEDIT_TOKEN_OBJECT, item);
}
swfdec_buffer_unref (next);
return TRUE;
diff-tree 97ce107c67c3bcbd363eaf12e3669ca8226e4143 (from bd5adea0669a5dbbbe75e887a400d6e538de0555)
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Jan 22 22:03:11 2007 +0100
make it not crash
includes adding optional debugging help for the treeview
diff --git a/test/swfedit.c b/test/swfedit.c
index 76fa744..71a86aa 100644
--- a/test/swfedit.c
+++ b/test/swfedit.c
@@ -28,7 +28,7 @@ static gboolean
open_window (char *filename)
{
SwfeditFile *file;
- GtkWidget *window, *treeview;
+ GtkWidget *window, *scroll, *treeview;
GError *error = NULL;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
@@ -42,8 +42,11 @@ open_window (char *filename)
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+ scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (window), scroll);
+
treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (file));
- gtk_container_add (GTK_CONTAINER (window), treeview);
+ gtk_container_add (GTK_CONTAINER (scroll), treeview);
gtk_widget_show_all (window);
renderer = gtk_cell_renderer_text_new ();
diff --git a/test/swfedit_file.c b/test/swfedit_file.c
index e995c1b..2ae8fa2 100644
--- a/test/swfedit_file.c
+++ b/test/swfedit_file.c
@@ -155,6 +155,8 @@ swfedit_file_parse (SwfeditFile *file, S
char *name;
if (tag_len == 0x3f)
tag_len = swfdec_bits_get_u32 (bits);
+ if (tag == 0)
+ break;
if (tag_len > 0)
buffer = swfdec_bits_get_buffer (bits, tag_len);
else
@@ -164,7 +166,7 @@ swfedit_file_parse (SwfeditFile *file, S
"Invalid contents in file");
return FALSE;
}
- item = swfedit_tag_new (tag, buffer);
+ item = swfedit_tag_new (SWFEDIT_TOKEN (file), tag, buffer);
name = g_strdup_printf ("Tag %u", tag);
swfedit_token_add (SWFEDIT_TOKEN (file), name, SWFEDIT_TOKEN_OBJECT, item);
g_free (name);
diff --git a/test/swfedit_tag.c b/test/swfedit_tag.c
index 9bbebeb..94ac4f9 100644
--- a/test/swfedit_tag.c
+++ b/test/swfedit_tag.c
@@ -49,12 +49,15 @@ swfedit_tag_init (SwfeditTag *tag)
}
SwfeditTag *
-swfedit_tag_new (guint tag, SwfdecBuffer *buffer)
+swfedit_tag_new (SwfeditToken *parent, guint tag, SwfdecBuffer *buffer)
{
SwfeditTag *item;
+ g_return_val_if_fail (SWFEDIT_IS_TOKEN (parent), NULL);
+
item = g_object_new (SWFEDIT_TYPE_TAG, NULL);
item->tag = tag;
+ SWFEDIT_TOKEN (item)->parent = parent;
swfedit_token_add (SWFEDIT_TOKEN (item), "contents", SWFEDIT_TOKEN_BINARY, buffer);
return item;
}
diff --git a/test/swfedit_tag.h b/test/swfedit_tag.h
index aad879e..07c11f2 100644
--- a/test/swfedit_tag.h
+++ b/test/swfedit_tag.h
@@ -47,7 +47,8 @@ struct _SwfeditTagClass {
GType swfedit_tag_get_type (void);
-SwfeditTag * swfedit_tag_new (guint tag,
+SwfeditTag * swfedit_tag_new (SwfeditToken * parent,
+ guint tag,
SwfdecBuffer * buffer);
diff --git a/test/swfedit_token.c b/test/swfedit_token.c
index 78951f2..704b98b 100644
--- a/test/swfedit_token.c
+++ b/test/swfedit_token.c
@@ -80,7 +80,7 @@ swfedit_binary_write (gconstpointer valu
for (i = 0; i < buffer->length; i++) {
if (i && i % 4 == 0)
g_string_append_c (string, ' ');
- g_string_append_printf (string, "%2X", buffer->data[i]);
+ g_string_append_printf (string, "%02X", buffer->data[i]);
}
return g_string_free (string, FALSE);
}
@@ -147,9 +147,15 @@ typedef struct {
/*** GTK_TREE_MODEL ***/
+#if 0
+# define REPORT g_print ("%s\n", G_STRFUNC)
+#else
+# define REPORT
+#endif
static GtkTreeModelFlags
swfedit_token_get_flags (GtkTreeModel *tree_model)
{
+ REPORT;
return 0;
}
@@ -158,12 +164,14 @@ swfedit_token_get_n_columns (GtkTreeMode
{
SwfeditToken *token = SWFEDIT_TOKEN (tree_model);
+ REPORT;
return token->tokens->len;
}
static GType
swfedit_token_get_column_type (GtkTreeModel *tree_model, gint index_)
{
+ REPORT;
switch (index_) {
case SWFEDIT_COLUMN_NAME:
return G_TYPE_STRING;
@@ -185,6 +193,7 @@ swfedit_token_get_iter (GtkTreeModel *tr
guint i = gtk_tree_path_get_indices (path)[0];
Entry *entry;
+ REPORT;
if (i > token->tokens->len)
return FALSE;
entry = &g_array_index (token->tokens, Entry, i);
@@ -199,7 +208,7 @@ swfedit_token_get_iter (GtkTreeModel *tr
new = gtk_tree_path_new ();
indices = gtk_tree_path_get_indices (path);
for (j = 1; j < gtk_tree_path_get_depth (path); j++) {
- gtk_tree_path_append_index (path, indices[j]);
+ gtk_tree_path_append_index (new, indices[j]);
}
ret = swfedit_token_get_iter (GTK_TREE_MODEL (entry->value), iter, new);
gtk_tree_path_free (new);
@@ -218,6 +227,7 @@ swfedit_token_get_path (GtkTreeModel *tr
SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data);
GtkTreePath *path = gtk_tree_path_new_from_indices (GPOINTER_TO_INT (iter->user_data2), -1);
+ REPORT;
while (token->parent) {
guint i;
SwfeditToken *parent = token->parent;
@@ -241,6 +251,7 @@ swfedit_token_get_value (GtkTreeModel *t
SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data);
Entry *entry = &g_array_index (token->tokens, Entry, GPOINTER_TO_INT (iter->user_data2));
+ REPORT;
switch (column) {
case SWFEDIT_COLUMN_NAME:
g_value_init (value, G_TYPE_STRING);
@@ -266,6 +277,7 @@ swfedit_token_iter_next (GtkTreeModel *t
{
SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data);
+ REPORT;
if ((guint) GPOINTER_TO_INT (iter->user_data2) + 1 >= token->tokens->len)
return FALSE;
@@ -276,14 +288,21 @@ swfedit_token_iter_next (GtkTreeModel *t
static gboolean
swfedit_token_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
{
- SwfeditToken *token = SWFEDIT_TOKEN (parent->user_data);
- Entry *entry = &g_array_index (token->tokens, Entry, GPOINTER_TO_INT (parent->user_data2));
-
- if (entry->type != SWFEDIT_TOKEN_OBJECT)
- return FALSE;
+ SwfeditToken *token;
+ Entry *entry;
+ REPORT;
+ if (parent) {
+ token = SWFEDIT_TOKEN (parent->user_data);
+ entry = &g_array_index (token->tokens, Entry, GPOINTER_TO_INT (parent->user_data2));
+ if (entry->type != SWFEDIT_TOKEN_OBJECT)
+ return FALSE;
+ token = entry->value;
+ } else {
+ token = SWFEDIT_TOKEN (tree_model);
+ }
iter->stamp = 0; /* FIXME */
- iter->user_data = entry->value;
+ iter->user_data = token;
iter->user_data2 = GINT_TO_POINTER (0);
return TRUE;
}
@@ -294,6 +313,7 @@ swfedit_token_iter_has_child (GtkTreeMod
SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data);
Entry *entry = &g_array_index (token->tokens, Entry, GPOINTER_TO_INT (iter->user_data2));
+ REPORT;
return entry->type == SWFEDIT_TOKEN_OBJECT;
}
@@ -303,6 +323,7 @@ swfedit_token_iter_n_children (GtkTreeMo
SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data);
Entry *entry = &g_array_index (token->tokens, Entry, GPOINTER_TO_INT (iter->user_data2));
+ REPORT;
if (entry->type != SWFEDIT_TOKEN_OBJECT)
return FALSE;
@@ -317,6 +338,7 @@ swfedit_token_iter_nth_child (GtkTreeMod
SwfeditToken *token;
Entry *entry;
+ REPORT;
if (parent) {
token = SWFEDIT_TOKEN (parent->user_data);
entry = &g_array_index (token->tokens, Entry, GPOINTER_TO_INT (parent->user_data2));
@@ -341,6 +363,7 @@ swfedit_token_iter_parent (GtkTreeModel
SwfeditToken *token = SWFEDIT_TOKEN (child->user_data);
SwfeditToken *parent = token->parent;
+ REPORT;
if (parent == NULL)
return FALSE;
@@ -352,7 +375,7 @@ swfedit_token_iter_parent (GtkTreeModel
break;
}
iter->stamp = 0; /* FIXME */
- iter->user_data = token;
+ iter->user_data = parent;
iter->user_data2 = GINT_TO_POINTER (i);
return TRUE;
}
diff-tree bd5adea0669a5dbbbe75e887a400d6e538de0555 (from parents)
Merge: 8c426c32f7343fff4ff23015f5f7eee647b5aee7 72caf9482e2e7eb4bdc6cc0fa7578beb31645bac
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Jan 22 18:40:04 2007 +0100
Merge branch 'interpreter' of ssh://company@git.freedesktop.org/git/swfdec into interpreter
diff-tree 8c426c32f7343fff4ff23015f5f7eee647b5aee7 (from f2e4bc2ff2bfa289f325e525619b79dcf4815f9c)
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Jan 22 10:54:05 2007 +0100
implement Increment and Decrement
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 909cba4..171877f 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -753,6 +753,26 @@ swfdec_action_if (JSContext *cx, guint a
return JS_TRUE;
}
+static JSBool
+swfdec_action_decrement (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ double d;
+
+ d = swfdec_action_to_number (cx, cx->fp->sp[-1]);
+ d--;
+ return JS_NewNumberValue (cx, d, &cx->fp->sp[-1]);
+}
+
+static JSBool
+swfdec_action_increment (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ double d;
+
+ d = swfdec_action_to_number (cx, cx->fp->sp[-1]);
+ d++;
+ return JS_NewNumberValue (cx, d, &cx->fp->sp[-1]);
+}
+
/*** PRINT FUNCTIONS ***/
static char *
@@ -967,8 +987,8 @@ static const SwfdecActionSpec actions[25
[0x4d] = { "Swap", NULL },
[0x4e] = { "GetMember", NULL, 2, 1, { NULL, swfdec_action_get_member, swfdec_action_get_member, swfdec_action_get_member, swfdec_action_get_member } },
[0x4f] = { "SetMember", NULL, 3, 0, { NULL, swfdec_action_set_member, swfdec_action_set_member, swfdec_action_set_member, swfdec_action_set_member } },
- [0x50] = { "Increment", NULL },
- [0x51] = { "Decrement", NULL },
+ [0x50] = { "Increment", NULL, 1, 1, { NULL, NULL, swfdec_action_increment, swfdec_action_increment, swfdec_action_increment } },
+ [0x51] = { "Decrement", NULL, 1, 1, { NULL, NULL, swfdec_action_decrement, swfdec_action_decrement, swfdec_action_decrement } },
[0x52] = { "CallMethod", NULL, -1, 1, { NULL, NULL, swfdec_action_call_method, swfdec_action_call_method, swfdec_action_call_method } },
[0x53] = { "NewMethod", NULL },
/* version 6 */
diff-tree f2e4bc2ff2bfa289f325e525619b79dcf4815f9c (from 568f6fdf0b44ea7cfcc87b33ed4ac09e88bbd47e)
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Jan 22 10:23:59 2007 +0100
Implement Jump, If and Not
Also includes a fix to voncert booleans to numbers correctly
11/44 failures
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 104af78..909cba4 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -527,6 +527,8 @@ swfdec_action_to_number (JSContext *cx,
return JSVAL_TO_INT (val);
} else if (JSVAL_IS_DOUBLE (val)) {
return *JSVAL_TO_DOUBLE (val);
+ } else if (JSVAL_IS_BOOLEAN (val)) {
+ return JSVAL_TO_BOOLEAN (val);
} else {
return 0;
}
@@ -704,9 +706,76 @@ swfdec_action_new_comparison_7 (JSContex
return JS_TRUE;
}
+static JSBool
+swfdec_action_not_4 (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ double d;
+
+ d = swfdec_action_to_number (cx, cx->fp->sp[-1]);
+ cx->fp->sp[-1] = INT_TO_JSVAL (d == 0 ? 1 : 0);
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_action_not_5 (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ double d;
+
+ d = swfdec_action_to_number (cx, cx->fp->sp[-1]);
+ cx->fp->sp[-1] = d == 0 ? JSVAL_TRUE : JSVAL_FALSE;
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_action_jump (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ if (len != 2) {
+ SWFDEC_ERROR ("Jump action length invalid (is %u, should be 2", len);
+ return JS_FALSE;
+ }
+ cx->fp->pc += 4 + GINT16_FROM_LE (*((gint16*) data));
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_action_if (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ double d;
+
+ if (len != 2) {
+ SWFDEC_ERROR ("Jump action length invalid (is %u, should be 2", len);
+ return JS_FALSE;
+ }
+ d = swfdec_action_to_number (cx, cx->fp->sp[-1]);
+ cx->fp->sp--;
+ if (d != 0)
+ cx->fp->pc += 4 + GINT16_FROM_LE (*((gint16*) data));
+ return JS_TRUE;
+}
+
/*** PRINT FUNCTIONS ***/
static char *
+swfdec_action_print_if (guint action, const guint8 *data, guint len)
+{
+ if (len != 2) {
+ SWFDEC_ERROR ("If action length invalid (is %u, should be 2", len);
+ return NULL;
+ }
+ return g_strdup_printf ("If %d", GINT16_FROM_LE (*((gint16*) data)));
+}
+
+static char *
+swfdec_action_print_jump (guint action, const guint8 *data, guint len)
+{
+ if (len != 2) {
+ SWFDEC_ERROR ("Jump action length invalid (is %u, should be 2", len);
+ return NULL;
+ }
+ return g_strdup_printf ("Jump %d", GINT16_FROM_LE (*((gint16*) data)));
+}
+
+static char *
swfdec_action_print_push (guint action, const guint8 *data, guint len)
{
gboolean first = TRUE;
@@ -844,7 +913,7 @@ static const SwfdecActionSpec actions[25
[0x0f] = { "Less", NULL },
[0x10] = { "And", NULL },
[0x11] = { "Or", NULL },
- [0x12] = { "Not", NULL },
+ [0x12] = { "Not", NULL, 1, 1, { NULL, swfdec_action_not_4, swfdec_action_not_5, swfdec_action_not_5, swfdec_action_not_5 } },
[0x13] = { "StringEquals", NULL },
[0x14] = { "StringLength", NULL },
[0x15] = { "StringExtract", NULL },
@@ -938,12 +1007,12 @@ static const SwfdecActionSpec actions[25
[0x94] = { "With", NULL },
/* version 4 */
[0x96] = { "Push", swfdec_action_print_push, 0, -1, { NULL, swfdec_action_push, swfdec_action_push, swfdec_action_push, swfdec_action_push } },
- [0x99] = { "Jump", NULL },
+ [0x99] = { "Jump", swfdec_action_print_jump, 0, 0, { NULL, swfdec_action_jump, swfdec_action_jump, swfdec_action_jump, swfdec_action_jump } },
[0x9a] = { "GetURL2", NULL },
/* version 5 */
[0x9b] = { "DefineFunction", NULL },
/* version 4 */
- [0x9d] = { "If", NULL },
+ [0x9d] = { "If", swfdec_action_print_if, 1, 0, { NULL, swfdec_action_if, swfdec_action_if, swfdec_action_if, swfdec_action_if } },
[0x9e] = { "Call", NULL },
[0x9f] = { "GotoFrame2", NULL }
};
diff-tree 568f6fdf0b44ea7cfcc87b33ed4ac09e88bbd47e (from e06e79a0c20256854b9073ee7c73a047e81dd820)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Jan 21 20:48:06 2007 +0100
fix binary ops for undefined2-7.swf
13/44 failures
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 3bbd168..104af78 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -540,8 +540,15 @@ swfdec_action_binary (JSContext *cx, gui
rval = cx->fp->sp[-1];
lval = cx->fp->sp[-2];
- l = swfdec_action_to_number (cx, lval);
- r = swfdec_action_to_number (cx, rval);
+ if (((SwfdecScript *) cx->fp->swf)->version < 7) {
+ l = swfdec_action_to_number (cx, lval);
+ r = swfdec_action_to_number (cx, rval);
+ } else {
+ if (!JS_ValueToNumber(cx, lval, &l) ||
+ !JS_ValueToNumber(cx, rval, &r))
+ return JS_FALSE;
+ }
+ cx->fp->sp--;
switch (action) {
case 0x0a:
l = l + r;
@@ -557,17 +564,22 @@ swfdec_action_binary (JSContext *cx, gui
JSString *str = JS_InternString (cx, "#ERROR#");
if (str == NULL)
return JS_FALSE;
- cx->fp->sp--;
cx->fp->sp[-1] = STRING_TO_JSVAL (str);
return JS_TRUE;
}
+ if (((SwfdecScript *) cx->fp->swf)->version >= 7 &&
+ JSVAL_IS_VOID (rval)) {
+ cx->fp->sp[-1] = DOUBLE_TO_JSVAL (r < 0 ?
+ cx->runtime->jsNegativeInfinity :
+ cx->runtime->jsPositiveInfinity);
+ return JS_TRUE;
+ }
l = l / r;
break;
default:
g_assert_not_reached ();
return r;
}
- cx->fp->sp--;
return JS_NewNumberValue (cx, l, &cx->fp->sp[-1]);
}
diff-tree e06e79a0c20256854b9073ee7c73a047e81dd820 (from 659db3d36cca2f586498ba8dd554f17dd50906f4)
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Jan 21 19:24:27 2007 +0100
implement Less2 and Greater actions and fix a big bug
The code used to always execute the v7 script.
14/44 failues
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 5b9f960..3bbd168 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -651,6 +651,47 @@ swfdec_action_set_member (JSContext *cx,
return JS_TRUE;
}
+static JSBool
+swfdec_action_new_comparison_6 (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ jsval lval, rval;
+ double d, d2;
+
+ rval = cx->fp->sp[-1];
+ lval = cx->fp->sp[-2];
+ cx->fp->sp--;
+ d = swfdec_action_to_number (cx, lval);
+ d2 = swfdec_action_to_number (cx, rval);
+ if (action == 0x48)
+ cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (d < d2);
+ else
+ cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (d > d2);
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_action_new_comparison_7 (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ jsval lval, rval;
+
+ rval = cx->fp->sp[-1];
+ lval = cx->fp->sp[-2];
+ cx->fp->sp--;
+ if (JSVAL_IS_VOID (rval) || JSVAL_IS_VOID (lval)) {
+ cx->fp->sp[-1] = JSVAL_VOID;
+ } else if (JSVAL_IS_STRING(lval) && JSVAL_IS_STRING(rval)) {
+ int comp = JS_CompareStrings (JSVAL_TO_STRING (lval), JSVAL_TO_STRING (rval));
+ cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (action == 0x48 ? comp < 0 : comp > 0);
+ } else {
+ double d, d2;
+ if (!JS_ValueToNumber(cx, lval, &d) ||
+ !JS_ValueToNumber(cx, rval, &d2))
+ return JS_FALSE;
+ cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (action == 0x48 ? d < d2 : d > d2);
+ }
+ return JS_TRUE;
+}
+
/*** PRINT FUNCTIONS ***/
static char *
@@ -762,7 +803,7 @@ swfdec_action_print_wait_for_frame (guin
/* defines minimum and maximum versions for which we have seperate scripts */
#define MINSCRIPTVERSION 3
#define MAXSCRIPTVERSION 7
-#define EXTRACT_VERSION(v) MAX ((v) - MINSCRIPTVERSION, MAXSCRIPTVERSION - MINSCRIPTVERSION)
+#define EXTRACT_VERSION(v) MIN ((v) - MINSCRIPTVERSION, MAXSCRIPTVERSION - MINSCRIPTVERSION)
typedef JSBool (* SwfdecActionExec) (JSContext *cx, guint action, const guint8 *data, guint len);
typedef struct {
@@ -837,7 +878,7 @@ static const SwfdecActionSpec actions[25
[0x45] = { "TargetPath", NULL },
[0x46] = { "Enumerate", NULL },
[0x47] = { "Add2", NULL, 2, 1, { NULL, NULL, NULL, NULL, swfdec_action_add2_7 } },
- [0x48] = { "Less2", NULL },
+ [0x48] = { "Less2", NULL, 2, 1, { NULL, NULL, swfdec_action_new_comparison_6, swfdec_action_new_comparison_6, swfdec_action_new_comparison_7 } },
[0x49] = { "Equals2", NULL },
[0x4a] = { "ToNumber", NULL },
[0x4b] = { "ToString", NULL },
@@ -861,7 +902,7 @@ static const SwfdecActionSpec actions[25
[0x65] = { "BitURShift", NULL },
/* version 6 */
[0x66] = { "StrictEquals", NULL },
- [0x67] = { "Greater", NULL },
+ [0x67] = { "Greater", NULL, 2, 1, { NULL, NULL, NULL, swfdec_action_new_comparison_6, swfdec_action_new_comparison_7 } },
[0x68] = { "StringGreater", NULL },
/* version 7 */
[0x69] = { "Extends", NULL },
diff-tree 659db3d36cca2f586498ba8dd554f17dd50906f4 (from 39276bcb05d190d1fc6a0c35490774ee309f4ffb)
Author: Benjamin Otte <otte at gnome.org>
Date: Sat Jan 20 17:01:06 2007 +0100
Fix case handling (don't make it global anymore) and implement SetVariable
with this there's 17/44 failures
diff --git a/libswfdec/js/jsatom.c b/libswfdec/js/jsatom.c
index f0816b2..c4c85b7 100644
--- a/libswfdec/js/jsatom.c
+++ b/libswfdec/js/jsatom.c
@@ -673,10 +673,10 @@ out:
JSAtom *
js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
{
- if (cx->caseSensitive)
- return js_AtomizeStringWithCompare (cx, str, flags, js_compare_atom_keys);
- else
+ if (flags & ATOM_NOCASE)
return js_AtomizeStringWithCompare (cx, str, flags, js_compare_atom_keys_no_case);
+ else
+ return js_AtomizeStringWithCompare (cx, str, flags, js_compare_atom_keys);
}
JS_FRIEND_API(JSAtom *)
diff --git a/libswfdec/js/jsatom.h b/libswfdec/js/jsatom.h
index 6f486c3..d9d2025 100644
--- a/libswfdec/js/jsatom.h
+++ b/libswfdec/js/jsatom.h
@@ -58,6 +58,7 @@ JS_BEGIN_EXTERN_C
#define ATOM_PINNED 0x01 /* atom is pinned against GC */
#define ATOM_INTERNED 0x02 /* pinned variant for JS_Intern* API */
#define ATOM_MARK 0x04 /* atom is reachable via GC */
+#define ATOM_NOCASE 0x20 /* treat atom case-insensitive */
#define ATOM_NOCOPY 0x40 /* don't copy atom string bytes */
#define ATOM_TMPSTR 0x80 /* internal, to avoid extra string */
diff --git a/libswfdec/swfdec_edittext_movie.c b/libswfdec/swfdec_edittext_movie.c
index 421f6bc..e3d2119 100644
--- a/libswfdec/swfdec_edittext_movie.c
+++ b/libswfdec/swfdec_edittext_movie.c
@@ -80,7 +80,7 @@ swfdec_edit_text_movie_iterate (SwfdecMo
jsobj = swfdec_scriptable_get_object (parent);
if (jsobj == NULL)
return;
- val = swfdec_js_eval (parent->jscx, jsobj, text->text->variable);
+ val = swfdec_js_eval (parent->jscx, jsobj, text->text->variable, FALSE);
if (JSVAL_IS_VOID (val))
return;
@@ -110,7 +110,7 @@ swfdec_edit_text_movie_init_movie (Swfde
if (jsobj == NULL)
return;
if (text->text->variable_prefix) {
- val = swfdec_js_eval (parent->jscx, jsobj, text->text->variable_prefix);
+ val = swfdec_js_eval (parent->jscx, jsobj, text->text->variable_prefix, FALSE);
if (!JSVAL_IS_OBJECT (val))
return;
jsobj = JSVAL_TO_OBJECT (val);
diff --git a/libswfdec/swfdec_js.c b/libswfdec/swfdec_js.c
index cf14f65..bbd6a43 100644
--- a/libswfdec/swfdec_js.c
+++ b/libswfdec/swfdec_js.c
@@ -300,29 +300,26 @@ fail:
static JSBool
swfdec_js_eval_get_property (JSContext *cx, JSObject *obj,
- const char *name, gboolean initial, jsval *ret)
+ const char *name, gboolean initial, gboolean ignore_case, jsval *ret)
{
JSAtom *atom;
JSObject *pobj;
JSProperty *prop;
- if (!JS_GetProperty (cx, obj, name, ret))
- return JS_FALSE;
- if (!JSVAL_IS_VOID (*ret))
- return JS_TRUE;
- if (!initial)
- return JS_FALSE;
-
- atom = js_Atomize(cx, name, strlen(name), 0);
+ atom = js_Atomize (cx, name, strlen(name), ignore_case ? ATOM_NOCASE : 0);
if (!atom)
return JS_FALSE;
- if (!js_FindProperty (cx, (jsid) atom, &obj, &pobj, &prop))
- return JS_FALSE;
- if (!prop)
- return JS_FALSE;
- if (pobj)
- obj = pobj;
- return OBJ_GET_PROPERTY (cx, obj, (jsid) prop->id, ret);
+ if (initial) {
+ return OBJ_GET_PROPERTY (cx, obj, (jsid) atom, ret);
+ } else {
+ if (!js_FindProperty (cx, (jsid) atom, &obj, &pobj, &prop))
+ return JS_FALSE;
+ if (!prop)
+ return JS_FALSE;
+ if (pobj)
+ obj = pobj;
+ return OBJ_GET_PROPERTY (cx, obj, (jsid) prop->id, ret);
+ }
}
/**
@@ -330,6 +327,7 @@ swfdec_js_eval_get_property (JSContext *
* @cx: a #JSContext
* @obj: #JSObject to use as a source for evaluating
* @str: The string to evaluate
+ * @ignore_case: TRUE for case insensitive evaluation
*
* This function works like the Actionscript eval function used on @obj.
* It handles both slash-style and dot-style notation.
@@ -337,7 +335,8 @@ swfdec_js_eval_get_property (JSContext *
* Returns: the value or JSVAL_VOID if no value was found.
**/
jsval
-swfdec_js_eval (JSContext *cx, JSObject *obj, const char *str)
+swfdec_js_eval (JSContext *cx, JSObject *obj, const char *str,
+ gboolean ignore_case)
{
jsval cur;
char *work = NULL;
@@ -365,12 +364,12 @@ swfdec_js_eval (JSContext *cx, JSObject
obj = JSVAL_TO_OBJECT (cur);
if (dot) {
char *name = g_strndup (str, dot - str);
- if (!swfdec_js_eval_get_property (cx, obj, name, initial, &cur))
+ if (!swfdec_js_eval_get_property (cx, obj, name, initial, ignore_case, &cur))
goto out;
g_free (name);
str = dot + 1;
} else {
- if (!swfdec_js_eval_get_property (cx, obj, str, initial, &cur))
+ if (!swfdec_js_eval_get_property (cx, obj, str, initial, ignore_case, &cur))
goto out;
str = NULL;
}
@@ -384,3 +383,5 @@ out:
g_free (work);
return JSVAL_VOID;
}
+
+
diff --git a/libswfdec/swfdec_js.h b/libswfdec/swfdec_js.h
index ced8046..47e97ff 100644
--- a/libswfdec/swfdec_js.h
+++ b/libswfdec/swfdec_js.h
@@ -49,7 +49,8 @@ void swfdec_js_movie_remove_property (S
char * swfdec_js_slash_to_dot (const char * slash_str);
jsval swfdec_js_eval (JSContext * cx,
JSObject * obj,
- const char * str);
+ const char * str,
+ gboolean ignore_case);
/* support functions */
const char * swfdec_js_to_string (JSContext * cx,
diff --git a/libswfdec/swfdec_js_global.c b/libswfdec/swfdec_js_global.c
index 328d74d..27522c1 100644
--- a/libswfdec/swfdec_js_global.c
+++ b/libswfdec/swfdec_js_global.c
@@ -33,7 +33,7 @@ swfdec_js_global_eval (JSContext *cx, JS
const char *bytes = swfdec_js_to_string (cx, argv[0]);
if (bytes == NULL)
return JS_FALSE;
- *rval = swfdec_js_eval (cx, obj, bytes);
+ *rval = swfdec_js_eval (cx, obj, bytes, FALSE);
} else {
*rval = argv[0];
}
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 23ca8ef..5b9f960 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -315,7 +315,26 @@ swfdec_action_get_variable (JSContext *c
s = swfdec_js_to_string (cx, cx->fp->sp[-1]);
if (s == NULL)
return JS_FALSE;
- cx->fp->sp[-1] = swfdec_js_eval (cx, cx->fp->scopeChain, s);
+ cx->fp->sp[-1] = swfdec_js_eval (cx, cx->fp->scopeChain, s,
+ ((SwfdecScript *) cx->fp->swf)->version < 7);
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_action_set_variable (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ const char *s;
+
+ s = swfdec_js_to_string (cx, cx->fp->sp[-2]);
+ if (s == NULL)
+ return JS_FALSE;
+
+ if (strpbrk (s, "./:")) {
+ SWFDEC_WARNING ("FIXME: implement paths");
+ }
+ if (!JS_SetProperty (cx, cx->fp->scopeChain, s, &cx->fp->sp[-1]))
+ return JS_FALSE;
+ cx->fp->sp -= 2;
return JS_TRUE;
}
@@ -425,7 +444,8 @@ swfdec_eval_jsval (JSContext *cx, JSObje
const char *bytes = swfdec_js_to_string (cx, *val);
if (bytes == NULL)
return JS_FALSE;
- *val = swfdec_js_eval (cx, obj, bytes);
+ *val = swfdec_js_eval (cx, obj, bytes,
+ ((SwfdecScript *) cx->fp->swf)->version < 7);
} else {
*val = OBJECT_TO_JSVAL (obj);
}
@@ -500,6 +520,57 @@ out:
return JS_TRUE;
}
+static double
+swfdec_action_to_number (JSContext *cx, jsval val)
+{
+ if (JSVAL_IS_INT (val)) {
+ return JSVAL_TO_INT (val);
+ } else if (JSVAL_IS_DOUBLE (val)) {
+ return *JSVAL_TO_DOUBLE (val);
+ } else {
+ return 0;
+ }
+}
+
+static JSBool
+swfdec_action_binary (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ jsval lval, rval;
+ double l, r;
+
+ rval = cx->fp->sp[-1];
+ lval = cx->fp->sp[-2];
+ l = swfdec_action_to_number (cx, lval);
+ r = swfdec_action_to_number (cx, rval);
+ switch (action) {
+ case 0x0a:
+ l = l + r;
+ break;
+ case 0x0b:
+ l = l - r;
+ break;
+ case 0x0c:
+ l = l * r;
+ break;
+ case 0x0d:
+ if (r == 0 && ((SwfdecScript *) cx->fp->swf)->version < 5) {
+ JSString *str = JS_InternString (cx, "#ERROR#");
+ if (str == NULL)
+ return JS_FALSE;
+ cx->fp->sp--;
+ cx->fp->sp[-1] = STRING_TO_JSVAL (str);
+ return JS_TRUE;
+ }
+ l = l / r;
+ break;
+ default:
+ g_assert_not_reached ();
+ return r;
+ }
+ cx->fp->sp--;
+ return JS_NewNumberValue (cx, l, &cx->fp->sp[-1]);
+}
+
static JSBool
swfdec_action_add2_7 (JSContext *cx, guint action, const guint8 *data, guint len)
{
@@ -539,7 +610,7 @@ swfdec_action_add2_7 (JSContext *cx, gui
return JS_FALSE;
d += d2;
cx->fp->sp--;
- return JS_NewDoubleValue(cx, d, &cx->fp->sp[-1]);
+ return JS_NewNumberValue(cx, d, &cx->fp->sp[-1]);
}
return JS_TRUE;
}
@@ -712,10 +783,10 @@ static const SwfdecActionSpec actions[25
[0x08] = { "ToggleQuality", NULL },
[0x09] = { "StopSounds", NULL },
/* version 4 */
- [0x0a] = { "Add", NULL },
- [0x0b] = { "Subtract", NULL },
- [0x0c] = { "Multiply", NULL },
- [0x0d] = { "Divide", NULL },
+ [0x0a] = { "Add", NULL, 2, 1, { NULL, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary } },
+ [0x0b] = { "Subtract", NULL, 2, 1, { NULL, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary } },
+ [0x0c] = { "Multiply", NULL, 2, 1, { NULL, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary } },
+ [0x0d] = { "Divide", NULL, 2, 1, { NULL, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary, swfdec_action_binary } },
[0x0e] = { "Equals", NULL },
[0x0f] = { "Less", NULL },
[0x10] = { "And", NULL },
@@ -727,7 +798,7 @@ static const SwfdecActionSpec actions[25
[0x17] = { "Pop", NULL, 1, 0, { NULL, swfdec_action_pop, swfdec_action_pop, swfdec_action_pop, swfdec_action_pop } },
[0x18] = { "ToInteger", NULL },
[0x1c] = { "GetVariable", NULL, 1, 1, { NULL, swfdec_action_get_variable, swfdec_action_get_variable, swfdec_action_get_variable, swfdec_action_get_variable } },
- [0x1d] = { "SetVariable", NULL },
+ [0x1d] = { "SetVariable", NULL, 2, 0, { NULL, swfdec_action_set_variable, swfdec_action_set_variable, swfdec_action_set_variable, swfdec_action_set_variable } },
[0x20] = { "SetTarget2", NULL },
[0x21] = { "StringAdd", NULL },
[0x22] = { "GetProperty", NULL, 2, 1, { NULL, swfdec_action_get_property, swfdec_action_get_property, swfdec_action_get_property, swfdec_action_get_property } },
diff-tree 39276bcb05d190d1fc6a0c35490774ee309f4ffb (from 41d6a77090dff7583e4a61937120db79d1c4c547)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Jan 19 22:14:26 2007 +0100
fix SetMember
20/44 failures
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 0256d8c..23ca8ef 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -427,7 +427,7 @@ swfdec_eval_jsval (JSContext *cx, JSObje
return JS_FALSE;
*val = swfdec_js_eval (cx, obj, bytes);
} else {
- SWFDEC_ERROR ("huh?");
+ *val = OBJECT_TO_JSVAL (obj);
}
return JS_TRUE;
}
@@ -475,7 +475,7 @@ swfdec_action_set_property (JSContext *c
JSObject *jsobj;
guint32 id;
- val = cx->fp->sp[-2];
+ val = cx->fp->sp[-3];
if (!swfdec_eval_jsval (cx, cx->fp->scopeChain, &val))
return JS_FALSE;
movie = swfdec_scriptable_from_jsval (cx, val, SWFDEC_TYPE_MOVIE);
@@ -483,7 +483,7 @@ swfdec_action_set_property (JSContext *c
SWFDEC_WARNING ("specified target does not reference a movie clip");
goto out;
}
- if (!JS_ValueToECMAUint32 (cx, cx->fp->sp[-1], &id))
+ if (!JS_ValueToECMAUint32 (cx, cx->fp->sp[-2], &id))
return JS_FALSE;
if (id > (((SwfdecScript *) cx->fp->swf)->version > 4 ? 21 : 18))
@@ -492,7 +492,7 @@ swfdec_action_set_property (JSContext *c
if (!(jsobj = swfdec_scriptable_get_object (SWFDEC_SCRIPTABLE (movie))))
return JS_FALSE;
- if (!JS_SetProperty (cx, jsobj, properties[id], &cx->fp->sp[-3]))
+ if (!JS_SetProperty (cx, jsobj, properties[id], &cx->fp->sp[-1]))
return JS_FALSE;
out:
diff-tree 41d6a77090dff7583e4a61937120db79d1c4c547 (from f07034751126d85a58b48ff77bbf57c5dc8021ca)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Jan 19 21:17:45 2007 +0100
push a double, not a float
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 583c2f1..0256d8c 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -251,7 +251,7 @@ swfdec_action_push (JSContext *cx, guint
break;
case 6: /* double */
{
- double d = swfdec_bits_get_float (&bits);
+ double d = swfdec_bits_get_double (&bits);
if (!JS_NewDoubleValue (cx, d, cx->fp->sp))
return JS_FALSE;
cx->fp->sp++;
diff-tree f07034751126d85a58b48ff77bbf57c5dc8021ca (from 34c98c5cf9deb0b5fc10f0cbee7bf368f3653000)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Jan 19 21:16:28 2007 +0100
fix string Add2
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index e4bf0d4..583c2f1 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -520,11 +520,11 @@ swfdec_action_add2_7 (JSContext *cx, gui
JSString *str, *str2;
if (cond) {
str = JSVAL_TO_STRING (lval);
- if ((str2 = js_ValueToString (cx, rval)) != NULL)
+ if ((str2 = js_ValueToString (cx, rval)) == NULL)
return JS_FALSE;
} else {
str2 = JSVAL_TO_STRING (rval);
- if ((str = js_ValueToString (cx, lval)) != NULL)
+ if ((str = js_ValueToString (cx, lval)) == NULL)
return JS_FALSE;
}
str = js_ConcatStrings (cx, str, str2);
diff-tree 34c98c5cf9deb0b5fc10f0cbee7bf368f3653000 (from 756c3c6c257d890fd5b35221ab7451017bb56d03)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Jan 19 21:16:11 2007 +0100
implement SetMember
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 8f073b7..e4bf0d4 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -563,6 +563,23 @@ swfdec_action_get_member (JSContext *cx,
return JS_TRUE;
}
+static JSBool
+swfdec_action_set_member (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ const char *s;
+
+ s = swfdec_js_to_string (cx, cx->fp->sp[-2]);
+ if (s == NULL)
+ return JS_FALSE;
+
+ if (JSVAL_IS_OBJECT (cx->fp->sp[-3])) {
+ if (!JS_SetProperty (cx, JSVAL_TO_OBJECT (cx->fp->sp[-3]), s, &cx->fp->sp[-1]))
+ return JS_FALSE;
+ }
+ cx->fp->sp -= 3;
+ return JS_TRUE;
+}
+
/*** PRINT FUNCTIONS ***/
static char *
@@ -756,7 +773,7 @@ static const SwfdecActionSpec actions[25
[0x4c] = { "PushDuplicate", NULL },
[0x4d] = { "Swap", NULL },
[0x4e] = { "GetMember", NULL, 2, 1, { NULL, swfdec_action_get_member, swfdec_action_get_member, swfdec_action_get_member, swfdec_action_get_member } },
- [0x4f] = { "SetMember", NULL }, /* apparently the result is ignored */
+ [0x4f] = { "SetMember", NULL, 3, 0, { NULL, swfdec_action_set_member, swfdec_action_set_member, swfdec_action_set_member, swfdec_action_set_member } },
[0x50] = { "Increment", NULL },
[0x51] = { "Decrement", NULL },
[0x52] = { "CallMethod", NULL, -1, 1, { NULL, NULL, swfdec_action_call_method, swfdec_action_call_method, swfdec_action_call_method } },
diff-tree 756c3c6c257d890fd5b35221ab7451017bb56d03 (from 469151c6400bd4dde8b9e0356274bbec5f105c4b)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Jan 19 19:34:22 2007 +0100
implement GetMember and Add2 for Flash7
30/44 failures
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index b8d3dc6..8f073b7 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -500,6 +500,69 @@ out:
return JS_TRUE;
}
+static JSBool
+swfdec_action_add2_7 (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ jsval rval, lval;
+ gboolean cond;
+
+ rval = cx->fp->sp[-1];
+ lval = cx->fp->sp[-2];
+ if (!JSVAL_IS_PRIMITIVE (rval)) {
+ if (!OBJ_DEFAULT_VALUE (cx, JSVAL_TO_OBJECT (rval), 0 , &rval))
+ return JS_FALSE;
+ }
+ if (!JSVAL_IS_PRIMITIVE (lval)) {
+ if (!OBJ_DEFAULT_VALUE (cx, JSVAL_TO_OBJECT (lval), 0 , &lval))
+ return JS_FALSE;
+ }
+ if ((cond = JSVAL_IS_STRING (lval)) || JSVAL_IS_STRING (rval)) {
+ JSString *str, *str2;
+ if (cond) {
+ str = JSVAL_TO_STRING (lval);
+ if ((str2 = js_ValueToString (cx, rval)) != NULL)
+ return JS_FALSE;
+ } else {
+ str2 = JSVAL_TO_STRING (rval);
+ if ((str = js_ValueToString (cx, lval)) != NULL)
+ return JS_FALSE;
+ }
+ str = js_ConcatStrings (cx, str, str2);
+ if (!str)
+ return JS_FALSE;
+ cx->fp->sp--;
+ cx->fp->sp[-1] = STRING_TO_JSVAL (str);
+ } else {
+ double d, d2;
+ if (!JS_ValueToNumber(cx, lval, &d) ||
+ !JS_ValueToNumber(cx, rval, &d2))
+ return JS_FALSE;
+ d += d2;
+ cx->fp->sp--;
+ return JS_NewDoubleValue(cx, d, &cx->fp->sp[-1]);
+ }
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_action_get_member (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ const char *s;
+
+ s = swfdec_js_to_string (cx, cx->fp->sp[-1]);
+ if (s == NULL)
+ return JS_FALSE;
+
+ if (JSVAL_IS_OBJECT (cx->fp->sp[-2])) {
+ if (!JS_GetProperty (cx, JSVAL_TO_OBJECT (cx->fp->sp[-2]), s, &cx->fp->sp[-2]))
+ return JS_FALSE;
+ } else {
+ cx->fp->sp[-2] = JSVAL_VOID;
+ }
+ cx->fp->sp--;
+ return JS_TRUE;
+}
+
/*** PRINT FUNCTIONS ***/
static char *
@@ -685,14 +748,14 @@ static const SwfdecActionSpec actions[25
[0x44] = { "Typeof", NULL },
[0x45] = { "TargetPath", NULL },
[0x46] = { "Enumerate", NULL },
- [0x47] = { "Add2", NULL },
+ [0x47] = { "Add2", NULL, 2, 1, { NULL, NULL, NULL, NULL, swfdec_action_add2_7 } },
[0x48] = { "Less2", NULL },
[0x49] = { "Equals2", NULL },
[0x4a] = { "ToNumber", NULL },
[0x4b] = { "ToString", NULL },
[0x4c] = { "PushDuplicate", NULL },
[0x4d] = { "Swap", NULL },
- [0x4e] = { "GetMember", NULL },
+ [0x4e] = { "GetMember", NULL, 2, 1, { NULL, swfdec_action_get_member, swfdec_action_get_member, swfdec_action_get_member, swfdec_action_get_member } },
[0x4f] = { "SetMember", NULL }, /* apparently the result is ignored */
[0x50] = { "Increment", NULL },
[0x51] = { "Decrement", NULL },
diff-tree 469151c6400bd4dde8b9e0356274bbec5f105c4b (from 1df9fa9d227af58658f4c2b9bf1e9a6719c4d9dc)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Jan 19 13:27:27 2007 +0100
add GetProperty and SetProperty actions
32/44 failures now
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index e688089..b8d3dc6 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -410,6 +410,96 @@ swfdec_action_pop (JSContext *cx, guint
return JS_TRUE;
}
+static const char *properties[22] = {
+ "_x", "_y", "_xscale", "_yscale", "_currentframe",
+ "_totalframes", "_alpha", "_visible", "_width", "_height",
+ "_rotation", "_target", "_framesloaded", "_name", "_droptarget",
+ "_url", "_highquality", "_focusrect", "_soundbuftime", "_quality",
+ "_xmouse", "_ymouse"
+};
+
+static JSBool
+swfdec_eval_jsval (JSContext *cx, JSObject *obj, jsval *val)
+{
+ if (JSVAL_IS_STRING (*val)) {
+ const char *bytes = swfdec_js_to_string (cx, *val);
+ if (bytes == NULL)
+ return JS_FALSE;
+ *val = swfdec_js_eval (cx, obj, bytes);
+ } else {
+ SWFDEC_ERROR ("huh?");
+ }
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_action_get_property (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ jsval val;
+ SwfdecMovie *movie;
+ JSObject *jsobj;
+ guint32 id;
+
+ val = cx->fp->sp[-2];
+ if (!swfdec_eval_jsval (cx, cx->fp->scopeChain, &val))
+ return JS_FALSE;
+ movie = swfdec_scriptable_from_jsval (cx, val, SWFDEC_TYPE_MOVIE);
+ val = JSVAL_VOID;
+ if (movie == NULL) {
+ SWFDEC_WARNING ("specified target does not reference a movie clip");
+ goto out;
+ }
+ if (!JS_ValueToECMAUint32 (cx, cx->fp->sp[-1], &id))
+ return JS_FALSE;
+
+ if (id > (((SwfdecScript *) cx->fp->swf)->version > 4 ? 21 : 18))
+ goto out;
+
+ if (!(jsobj = swfdec_scriptable_get_object (SWFDEC_SCRIPTABLE (movie))))
+ return JS_FALSE;
+
+ if (!JS_GetProperty (cx, jsobj, properties[id], &val))
+ return JS_FALSE;
+
+out:
+ cx->fp->sp -= 1;
+ cx->fp->sp[-1] = val;
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_action_set_property (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ jsval val;
+ SwfdecMovie *movie;
+ JSObject *jsobj;
+ guint32 id;
+
+ val = cx->fp->sp[-2];
+ if (!swfdec_eval_jsval (cx, cx->fp->scopeChain, &val))
+ return JS_FALSE;
+ movie = swfdec_scriptable_from_jsval (cx, val, SWFDEC_TYPE_MOVIE);
+ if (movie == NULL) {
+ SWFDEC_WARNING ("specified target does not reference a movie clip");
+ goto out;
+ }
+ if (!JS_ValueToECMAUint32 (cx, cx->fp->sp[-1], &id))
+ return JS_FALSE;
+
+ if (id > (((SwfdecScript *) cx->fp->swf)->version > 4 ? 21 : 18))
+ goto out;
+
+ if (!(jsobj = swfdec_scriptable_get_object (SWFDEC_SCRIPTABLE (movie))))
+ return JS_FALSE;
+
+ if (!JS_SetProperty (cx, jsobj, properties[id], &cx->fp->sp[-3]))
+ return JS_FALSE;
+
+out:
+ cx->fp->sp -= 3;
+ return JS_TRUE;
+}
+
/*** PRINT FUNCTIONS ***/
static char *
@@ -560,8 +650,8 @@ static const SwfdecActionSpec actions[25
[0x1d] = { "SetVariable", NULL },
[0x20] = { "SetTarget2", NULL },
[0x21] = { "StringAdd", NULL },
- [0x22] = { "GetProperty", NULL },
- [0x23] = { "SetProperty", NULL },
+ [0x22] = { "GetProperty", NULL, 2, 1, { NULL, swfdec_action_get_property, swfdec_action_get_property, swfdec_action_get_property, swfdec_action_get_property } },
+ [0x23] = { "SetProperty", NULL, 3, 0, { NULL, swfdec_action_set_property, swfdec_action_set_property, swfdec_action_set_property, swfdec_action_set_property } },
[0x24] = { "CloneSprite", NULL },
[0x25] = { "RemoveSprite", NULL },
[0x26] = { "Trace", NULL, 1, 0, { NULL, swfdec_action_trace, swfdec_action_trace, swfdec_action_trace, swfdec_action_trace } },
diff-tree 1df9fa9d227af58658f4c2b9bf1e9a6719c4d9dc (from 1fbe061229c9be6b6374f95fc0e70a786e8a33d5)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Jan 19 13:27:05 2007 +0100
add stub for _quality property
diff --git a/libswfdec/swfdec_js_movie.c b/libswfdec/swfdec_js_movie.c
index f5bf871..70ddece 100644
--- a/libswfdec/swfdec_js_movie.c
+++ b/libswfdec/swfdec_js_movie.c
@@ -1056,6 +1056,7 @@ static JSPropertySpec movieclip_props[]
{"_highquality", -1, MC_PROP_ATTRS, not_reached, not_reached },
{"_focusrect", -1, MC_PROP_ATTRS, not_reached, not_reached },
{"_soundbuftime", -1, MC_PROP_ATTRS, not_reached, not_reached },
+ {"_quality", -1, MC_PROP_ATTRS, not_reached, not_reached },
{"_xmouse", -1, MC_PROP_ATTRS, not_reached, not_reached },
{"_ymouse", -1, MC_PROP_ATTRS, not_reached, not_reached },
{"_parent", -1, MC_PROP_ATTRS | JSPROP_READONLY, mc_parent, NULL},
diff-tree 1fbe061229c9be6b6374f95fc0e70a786e8a33d5 (from 5f777f6697273122587f8bcf645e3a81a7f77228)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Jan 19 12:53:56 2007 +0100
implement CallMethod and Pop + lots of bugfixing
after this commit, test/trace has 33/44 failures
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index ed5ac44..e688089 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -304,7 +304,7 @@ swfdec_action_push (JSContext *cx, guint
return JS_FALSE;
}
}
- return swfdec_bits_left (&bits) ? JS_TRUE : JS_FALSE;
+ return swfdec_bits_left (&bits) ? JS_FALSE : JS_TRUE;
}
static JSBool
@@ -326,6 +326,7 @@ swfdec_action_trace (JSContext *cx, guin
const char *bytes;
bytes = swfdec_js_to_string (cx, cx->fp->sp[-1]);
+ cx->fp->sp--;
if (bytes == NULL)
return JS_TRUE;
@@ -333,6 +334,82 @@ swfdec_action_trace (JSContext *cx, guin
return JS_TRUE;
}
+/**
+ * swfdec_action_invoke:
+ * @cx: the #JSContext
+ * @n_args: number of arguments
+ *
+ * This function is similar to js_Invoke, however it uses a reversed stack
+ * order. sp[-1] has to be the function to call, sp[-2] will be the object the
+ * function is called on, sp[-3] is the first argument, followed by the rest of
+ * the arguments. The function reorders the stack on success and pushes the
+ * return value on top.
+ *
+ * Returns: JS_TRUE on success, JS_FALSE on failure.
+ **/
+static JSBool
+swfdec_action_call (JSContext *cx, guint n_args, guint flags)
+{
+ int i, j;
+ jsval tmp;
+
+ j = -1;
+ i = - (n_args + 2);
+ while (i < j) {
+ tmp = cx->fp->sp[j];
+ cx->fp->sp[j] = cx->fp->sp[i];
+ cx->fp->sp[i] = tmp;
+ j--;
+ i++;
+ }
+ return js_Invoke (cx, n_args, flags);
+}
+
+static JSBool
+swfdec_action_call_method (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ JSStackFrame *fp = cx->fp;
+ const char *s;
+ guint32 n_args;
+ JSObject *obj;
+ jsval fun;
+
+ s = swfdec_js_to_string (cx, fp->sp[-1]);
+ if (s == NULL)
+ return JS_FALSE;
+ if (!JS_ValueToECMAUint32 (cx, fp->sp[-3], &n_args))
+ return JS_FALSE;
+ if (n_args + 3 > (guint) (fp->sp - fp->spbase))
+ return JS_FALSE;
+
+ if (!JSVAL_IS_OBJECT (fp->sp[-2]))
+ goto fail;
+ obj = JSVAL_TO_OBJECT (fp->sp[-2]);
+ if (s[0] == '\0') {
+ fun = OBJECT_TO_JSVAL (obj);
+ } else {
+ if (!JS_GetProperty (cx, obj, s, &fun))
+ return JS_FALSE;
+ }
+ fp->sp--;
+ fp->sp[-1] = fun;
+ fp->sp[-2] = OBJECT_TO_JSVAL (obj);
+ swfdec_action_call (cx, n_args, 0);
+ return JS_TRUE;
+
+fail:
+ fp->sp -= 2 + n_args;
+ fp->sp[-1] = JSVAL_VOID;
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_action_pop (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ cx->fp->sp--;
+ return JS_TRUE;
+}
+
/*** PRINT FUNCTIONS ***/
static char *
@@ -477,7 +554,7 @@ static const SwfdecActionSpec actions[25
[0x13] = { "StringEquals", NULL },
[0x14] = { "StringLength", NULL },
[0x15] = { "StringExtract", NULL },
- [0x17] = { "Pop", NULL },
+ [0x17] = { "Pop", NULL, 1, 0, { NULL, swfdec_action_pop, swfdec_action_pop, swfdec_action_pop, swfdec_action_pop } },
[0x18] = { "ToInteger", NULL },
[0x1c] = { "GetVariable", NULL, 1, 1, { NULL, swfdec_action_get_variable, swfdec_action_get_variable, swfdec_action_get_variable, swfdec_action_get_variable } },
[0x1d] = { "SetVariable", NULL },
@@ -529,7 +606,7 @@ static const SwfdecActionSpec actions[25
[0x4f] = { "SetMember", NULL }, /* apparently the result is ignored */
[0x50] = { "Increment", NULL },
[0x51] = { "Decrement", NULL },
- [0x52] = { "CallMethod", NULL },
+ [0x52] = { "CallMethod", NULL, -1, 1, { NULL, NULL, swfdec_action_call_method, swfdec_action_call_method, swfdec_action_call_method } },
[0x53] = { "NewMethod", NULL },
/* version 6 */
[0x54] = { "InstanceOf", NULL },
@@ -726,7 +803,7 @@ swfdec_script_interpret (SwfdecScript *s
guint8 *startpc, *pc, *endpc, *nextpc;
JSBool ok = JS_TRUE;
void *mark;
- jsval *startsp, *endsp;
+ jsval *startsp, *endsp, *checksp;
int stack_check;
guint action, len;
guint8 *data;
@@ -800,6 +877,8 @@ swfdec_script_interpret (SwfdecScript *s
goto internal_error;
}
if (spec->add < 0) {
+ /* HACK FIXME: if added args are -1, we pass the number of free space on the stack
+ * instead of the action */
action = endsp - fp->sp;
} else {
if (fp->sp + spec->add - MAX (spec->remove, 0) > endsp) {
@@ -807,9 +886,18 @@ swfdec_script_interpret (SwfdecScript *s
goto internal_error;
}
}
+ checksp = (spec->add >= 0 && spec->remove >= 0) ? fp->sp + spec->add - spec->remove : NULL;
ok = spec->exec[version] (cx, action, data, len);
- if (!ok)
+ if (!ok) {
+ SWFDEC_WARNING ("action %s failed", spec->name);
goto out;
+ }
+ if (checksp != NULL && checksp != fp->sp) {
+ /* check stack was handled like expected */
+ g_error ("action %s was supposed to change the stack by %d (+%d -%d), but it changed by %d",
+ spec->name, spec->add - spec->remove, spec->add, spec->remove,
+ fp->sp - checksp + spec->add - spec->remove);
+ }
if (fp->pc == pc) {
fp->pc = pc = nextpc;
} else {
diff-tree 5f777f6697273122587f8bcf645e3a81a7f77228 (from 878ec656b0711cd19c11554d0617109a058af799)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Jan 18 18:15:51 2007 +0100
implement Trace action
includes changing the API to have a swfdec_player_trace function
diff --git a/libswfdec/swfdec_js_global.c b/libswfdec/swfdec_js_global.c
index daa8f75..328d74d 100644
--- a/libswfdec/swfdec_js_global.c
+++ b/libswfdec/swfdec_js_global.c
@@ -50,8 +50,7 @@ swfdec_js_trace (JSContext *cx, JSObject
if (bytes == NULL)
return JS_TRUE;
- /* FIXME: accumulate and emit after JS handling? */
- g_signal_emit_by_name (player, "trace", bytes);
+ swfdec_player_trace (player, bytes);
return JS_TRUE;
}
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 811e7c6..4b29d28 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -837,6 +837,16 @@ swfdec_player_stop_all_sounds (SwfdecPla
}
void
+swfdec_player_trace (SwfdecPlayer *player, const char *text)
+{
+ g_return_if_fail (SWFDEC_IS_PLAYER (player));
+ g_return_if_fail (text != NULL);
+
+ /* FIXME: accumulate and emit after JS handling? */
+ g_signal_emit (player, signals[TRACE], 0, text);
+}
+
+void
swfdec_player_invalidate (SwfdecPlayer *player, const SwfdecRect *rect)
{
if (swfdec_rect_is_empty (rect)) {
diff --git a/libswfdec/swfdec_player_internal.h b/libswfdec/swfdec_player_internal.h
index dd10949..2da8ecc 100644
--- a/libswfdec/swfdec_player_internal.h
+++ b/libswfdec/swfdec_player_internal.h
@@ -122,6 +122,8 @@ void swfdec_player_set_drag_movie (Swfd
SwfdecMovie * drag,
gboolean center,
SwfdecRect * rect);
+void swfdec_player_trace (SwfdecPlayer * player,
+ const char * text);
void swfdec_player_stop_all_sounds (SwfdecPlayer * player);
SwfdecRootMovie * swfdec_player_add_level_from_loader
(SwfdecPlayer * player,
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 49ad92f..ed5ac44 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -31,6 +31,7 @@
#include "swfdec_decoder.h"
#include "swfdec_js.h"
#include "swfdec_movie.h"
+#include "swfdec_player_internal.h"
#include "swfdec_root_movie.h"
/*** CONSTANT POOLS ***/
@@ -318,6 +319,20 @@ swfdec_action_get_variable (JSContext *c
return JS_TRUE;
}
+static JSBool
+swfdec_action_trace (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+ SwfdecPlayer *player = JS_GetContextPrivate (cx);
+ const char *bytes;
+
+ bytes = swfdec_js_to_string (cx, cx->fp->sp[-1]);
+ if (bytes == NULL)
+ return JS_TRUE;
+
+ swfdec_player_trace (player, bytes);
+ return JS_TRUE;
+}
+
/*** PRINT FUNCTIONS ***/
static char *
@@ -472,7 +487,7 @@ static const SwfdecActionSpec actions[25
[0x23] = { "SetProperty", NULL },
[0x24] = { "CloneSprite", NULL },
[0x25] = { "RemoveSprite", NULL },
- [0x26] = { "Trace", NULL },
+ [0x26] = { "Trace", NULL, 1, 0, { NULL, swfdec_action_trace, swfdec_action_trace, swfdec_action_trace, swfdec_action_trace } },
[0x27] = { "StartDrag", NULL },
[0x28] = { "EndDrag", NULL },
[0x29] = { "StringLess", NULL },
More information about the Swfdec
mailing list