Benjamin Otte
2007-Mar-01 02:36 UTC
[Swfdec] 11 commits - libswfdec/Makefile.am libswfdec/swfdec_connection.c libswfdec/swfdec_connection.h libswfdec/swfdec_flv_decoder.c libswfdec/swfdec_js.c libswfdec/swfdec_js_connection.c libswfdec/swfdec_js.h libswfdec/swfdec_js_net_stream.c libswfdec/swfdec_js_xml.c libswfdec/swfdec_loader.c libswfdec/swfdec_loader.h libswfdec/swfdec_loader_internal.h libswfdec/swfdec_loadertarget.c libswfdec/swfdec_loadertarget.h libswfdec/swfdec_net_stream.c libswfdec/swfdec_net_stream.h libswfdec/swfdec_player.c libswfdec/swfdec_player_internal.h libswfdec/swfdec_root_movie.c libswfdec/swfdec_scriptable.c libswfdec/swfdec_script.c libswfdec/swfdec_xml.c libswfdec/swfdec_xml.h test/trace
libswfdec/Makefile.am | 11 +- libswfdec/swfdec_connection.c | 119 +++++++++++++++++++++++ libswfdec/swfdec_connection.h | 57 +++++++++++ libswfdec/swfdec_flv_decoder.c | 4 libswfdec/swfdec_js.c | 3 libswfdec/swfdec_js.h | 3 libswfdec/swfdec_js_connection.c | 109 +++++++++++++++++++++ libswfdec/swfdec_js_net_stream.c | 94 ++++++++++++++++++ libswfdec/swfdec_js_xml.c | 101 +++++++++++++++++++ libswfdec/swfdec_loader.c | 156 +++++++++++++++++------------- libswfdec/swfdec_loader.h | 9 - libswfdec/swfdec_loader_internal.h | 5 libswfdec/swfdec_loadertarget.c | 87 +++++++++++++++-- libswfdec/swfdec_loadertarget.h | 6 - libswfdec/swfdec_net_stream.c | 25 ++++ libswfdec/swfdec_net_stream.h | 9 + libswfdec/swfdec_player.c | 16 +++ libswfdec/swfdec_player_internal.h | 3 libswfdec/swfdec_root_movie.c | 2 libswfdec/swfdec_script.c | 7 + libswfdec/swfdec_scriptable.c | 9 + libswfdec/swfdec_xml.c | 187 +++++++++++++++++++++++++++++++++++++ libswfdec/swfdec_xml.h | 59 +++++++++++ test/trace/Makefile.am | 2 test/trace/netconnection.swf |binary test/trace/netconnection.swf.trace | 6 + 26 files changed, 993 insertions(+), 96 deletions(-) New commits: diff-tree 66e63dc1d746e5b3d5bffd3b780a028aa6b995be (from 9ea16e8cfcae227f0742865e8f47be32392036c5) Author: Benjamin Otte <otte@gnome.org> Date: Thu Mar 1 11:36:17 2007 +0100 add NetStream stub diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am index 0c8564c..68cdbbf 100644 --- a/libswfdec/Makefile.am +++ b/libswfdec/Makefile.am @@ -52,6 +52,7 @@ libswfdec_@SWFDEC_MAJORMINOR@_la_SOURCES swfdec_js_global.c \ swfdec_js_mouse.c \ swfdec_js_movie.c \ + swfdec_js_net_stream.c \ swfdec_js_sound.c \ swfdec_js_xml.c \ swfdec_listener.c \ diff --git a/libswfdec/swfdec_js.c b/libswfdec/swfdec_js.c index 7fe7ae2..e26e33d 100644 --- a/libswfdec/swfdec_js.c +++ b/libswfdec/swfdec_js.c @@ -114,6 +114,7 @@ swfdec_js_init_player (SwfdecPlayer *pla swfdec_js_add_sound (player); swfdec_js_add_xml (player); swfdec_js_add_connection (player); + swfdec_js_add_net_stream (player); player->mouse_listener = swfdec_listener_new (player); player->key_listener = swfdec_listener_new (player); } diff --git a/libswfdec/swfdec_js.h b/libswfdec/swfdec_js.h index fc16871..6c5b804 100644 --- a/libswfdec/swfdec_js.h +++ b/libswfdec/swfdec_js.h @@ -42,6 +42,7 @@ void swfdec_js_add_connection (SwfdecPl void swfdec_js_add_globals (SwfdecPlayer * player); void swfdec_js_add_mouse (SwfdecPlayer * player); void swfdec_js_add_movieclip_class (SwfdecPlayer * player); +void swfdec_js_add_net_stream (SwfdecPlayer * player); void swfdec_js_add_sound (SwfdecPlayer * player); void swfdec_js_add_xml (SwfdecPlayer * player); diff --git a/libswfdec/swfdec_js_net_stream.c b/libswfdec/swfdec_js_net_stream.c new file mode 100644 index 0000000..7b53cfb --- /dev/null +++ b/libswfdec/swfdec_js_net_stream.c @@ -0,0 +1,94 @@ +/* Swfdec + * Copyright (C) 2007 Benjamin Otte <otte@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 "swfdec_net_stream.h" +#include "swfdec_debug.h" +#include "swfdec_js.h" +#include "swfdec_player_internal.h" + +static JSBool +swfdec_js_net_stream_to_string (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *string; + + string = JS_InternString (cx, "[object Object]"); + if (string == NULL) + return JS_FALSE; + + *rval = STRING_TO_JSVAL (string); + return JS_TRUE; +} + +static JSFunctionSpec net_stream_methods[] = { + { "toString", swfdec_js_net_stream_to_string, 0, 0, 0 }, + {0,0,0,0,0} +}; + +static void +swfdec_js_net_stream_finalize (JSContext *cx, JSObject *obj) +{ + SwfdecNetStream *stream; + + stream = JS_GetPrivate (cx, obj); + if (stream) { + SWFDEC_SCRIPTABLE (stream)->jsobj = NULL; + g_object_unref (stream); + } +} + +static JSClass net_stream_class = { + "NetStream", JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, swfdec_js_net_stream_finalize, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + +static JSBool +swfdec_js_net_stream_new (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + SwfdecNetStream *stream; + SwfdecConnection *conn; + + conn = swfdec_scriptable_from_jsval (cx, argv[0], SWFDEC_TYPE_CONNECTION); + if (conn == NULL) { + SWFDEC_WARNING ("no connection passed to NetStream ()"); + *rval = JSVAL_VOID; + return JS_TRUE; + } + stream = swfdec_net_stream_new (JS_GetContextPrivate (cx), conn); + + JS_SetPrivate (cx, obj, stream); + SWFDEC_SCRIPTABLE (stream)->jsobj = obj; + + *rval = OBJECT_TO_JSVAL (obj); + return JS_TRUE; +} + +void +swfdec_js_add_net_stream (SwfdecPlayer *player) +{ + JS_InitClass (player->jscx, player->jsobj, NULL, + &net_stream_class, swfdec_js_net_stream_new, 0, NULL, net_stream_methods, + NULL, NULL); +} + diff-tree 9ea16e8cfcae227f0742865e8f47be32392036c5 (from b388b559727066550385b938933b85e443fde2c9) Author: Benjamin Otte <otte@gnome.org> Date: Thu Mar 1 11:35:50 2007 +0100 Some changes to make API of NetStream more like AS NetStream - NetStream takes a connection on creation now. - connections are now created without a JSObject. diff --git a/libswfdec/swfdec_connection.c b/libswfdec/swfdec_connection.c index 2360804..8e423df 100644 --- a/libswfdec/swfdec_connection.c +++ b/libswfdec/swfdec_connection.c @@ -89,18 +89,16 @@ swfdec_connection_onstatus (SwfdecConnec } SwfdecConnection * -swfdec_connection_new (JSContext *cx, JSObject *obj) +swfdec_connection_new (JSContext *cx) { SwfdecConnection *conn; SwfdecScriptable *script; g_return_val_if_fail (cx != NULL, NULL); - g_return_val_if_fail (obj != NULL, NULL); conn = g_object_new (SWFDEC_TYPE_CONNECTION, NULL); script = SWFDEC_SCRIPTABLE (conn); script->jscx = cx; - script->jsobj = obj; return conn; } diff --git a/libswfdec/swfdec_connection.h b/libswfdec/swfdec_connection.h index 737a139..7219a89 100644 --- a/libswfdec/swfdec_connection.h +++ b/libswfdec/swfdec_connection.h @@ -47,8 +47,7 @@ struct _SwfdecConnectionClass { GType swfdec_connection_get_type (void); -SwfdecConnection * swfdec_connection_new (JSContext * cx, - JSObject * obj); +SwfdecConnection * swfdec_connection_new (JSContext * cx); void swfdec_connection_connect (SwfdecConnection * conn, const char * url); diff --git a/libswfdec/swfdec_flv_decoder.c b/libswfdec/swfdec_flv_decoder.c index 00666bc..b5640f7 100644 --- a/libswfdec/swfdec_flv_decoder.c +++ b/libswfdec/swfdec_flv_decoder.c @@ -458,6 +458,7 @@ swfdec_flv_decoder_add_movie (SwfdecFlvD SwfdecContent *content = swfdec_content_new (0); SwfdecMovie *movie; SwfdecVideo *video; + SwfdecConnection *conn; SwfdecNetStream *stream; /* set up the video movie */ @@ -469,7 +470,8 @@ swfdec_flv_decoder_add_movie (SwfdecFlvD g_object_weak_ref (G_OBJECT (movie), (GWeakNotify) swfdec_content_free, content); g_object_weak_ref (G_OBJECT (movie), (GWeakNotify) g_object_unref, video); /* set up the playback stream */ - stream = swfdec_net_stream_new (SWFDEC_ROOT_MOVIE (parent)->player); + conn = swfdec_connection_new (SWFDEC_ROOT_MOVIE (parent)->player->jscx); + stream = swfdec_net_stream_new (SWFDEC_ROOT_MOVIE (parent)->player, conn); swfdec_net_stream_set_loader (stream, SWFDEC_ROOT_MOVIE (parent)->loader); g_object_ref (SWFDEC_ROOT_MOVIE (parent)->decoder); if (!swfdec_loader_target_set_decoder (SWFDEC_LOADER_TARGET (stream), SWFDEC_ROOT_MOVIE (parent)->decoder)) { diff --git a/libswfdec/swfdec_js_connection.c b/libswfdec/swfdec_js_connection.c index 7e820f8..1ff1032 100644 --- a/libswfdec/swfdec_js_connection.c +++ b/libswfdec/swfdec_js_connection.c @@ -91,9 +91,10 @@ static JSClass connection_class = { static JSBool swfdec_js_connection_new (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - SwfdecConnection *conn = swfdec_connection_new (cx, obj); + SwfdecConnection *conn = swfdec_connection_new (cx); JS_SetPrivate (cx, obj, conn); + SWFDEC_SCRIPTABLE (conn)->jsobj = obj; *rval = OBJECT_TO_JSVAL (obj); return JS_TRUE; } diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c index eee3f72..3fb4937 100644 --- a/libswfdec/swfdec_net_stream.c +++ b/libswfdec/swfdec_net_stream.c @@ -216,6 +216,8 @@ swfdec_net_stream_dispose (GObject *obje if (stream->decoder) swfdec_video_codec_finish (stream->codec, stream->decoder); swfdec_net_stream_set_loader (stream, NULL); + g_object_unref (stream->conn); + stream->conn = NULL; G_OBJECT_CLASS (swfdec_net_stream_parent_class)->dispose (object); } @@ -236,16 +238,35 @@ swfdec_net_stream_init (SwfdecNetStream } SwfdecNetStream * -swfdec_net_stream_new (SwfdecPlayer *player) +swfdec_net_stream_new (SwfdecPlayer *player, SwfdecConnection *conn) { - SwfdecNetStream *stream = g_object_new (SWFDEC_TYPE_NET_STREAM, NULL); + SwfdecNetStream *stream; + + g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL); + g_return_val_if_fail (SWFDEC_IS_CONNECTION (conn), NULL); + stream = g_object_new (SWFDEC_TYPE_NET_STREAM, NULL); stream->player = player; + stream->conn = conn; + g_object_ref (conn); return stream; } void +swfdec_net_stream_set_url (SwfdecNetStream *stream, const char *url) +{ + SwfdecLoader *loader; + + g_return_if_fail (SWFDEC_IS_NET_STREAM (stream)); + g_return_if_fail (url != NULL); + + /* FIXME: use the connection once connections are implemented */ + loader = swfdec_player_load (stream->player, url); + swfdec_net_stream_set_loader (stream, loader); +} + +void swfdec_net_stream_set_loader (SwfdecNetStream *stream, SwfdecLoader *loader) { g_return_if_fail (SWFDEC_IS_NET_STREAM (stream)); diff --git a/libswfdec/swfdec_net_stream.h b/libswfdec/swfdec_net_stream.h index cf5fd5a..012a11d 100644 --- a/libswfdec/swfdec_net_stream.h +++ b/libswfdec/swfdec_net_stream.h @@ -21,6 +21,7 @@ #define _SWFDEC_NET_STREAM_H_ #include <libswfdec/swfdec.h> +#include <libswfdec/swfdec_connection.h> #include <libswfdec/swfdec_flv_decoder.h> #include <libswfdec/swfdec_player_internal.h> #include <libswfdec/swfdec_scriptable.h> @@ -43,7 +44,8 @@ struct _SwfdecNetStream SwfdecScriptable scriptable; SwfdecPlayer * player; /* the player we play in */ - SwfdecLoader * loader; /* input connection */ + SwfdecConnection * conn; /* connection used for opening streams */ + SwfdecLoader * loader; /* input stream */ SwfdecFlvDecoder * flvdecoder; /* flv decoder */ gboolean playing; /* TRUE if this stream is playing */ gboolean error; /* in error */ @@ -69,8 +71,11 @@ struct _SwfdecNetStreamClass GType swfdec_net_stream_get_type (void); -SwfdecNetStream * swfdec_net_stream_new (SwfdecPlayer * player); +SwfdecNetStream * swfdec_net_stream_new (SwfdecPlayer * player, + SwfdecConnection * conn); +void swfdec_net_stream_set_url (SwfdecNetStream * stream, + const char * url); void swfdec_net_stream_set_loader (SwfdecNetStream * stream, SwfdecLoader * loader); void swfdec_net_stream_set_playing (SwfdecNetStream * stream, diff-tree b388b559727066550385b938933b85e443fde2c9 (from 28e968cbba77ca5493a624527e58513f52e542ac) Author: Benjamin Otte <otte@gnome.org> Date: Thu Mar 1 11:33:13 2007 +0100 Fix read-out-of-bounds when processing valid strings diff --git a/libswfdec/swfdec_scriptable.c b/libswfdec/swfdec_scriptable.c index f48c9be..772a7de 100644 --- a/libswfdec/swfdec_scriptable.c +++ b/libswfdec/swfdec_scriptable.c @@ -173,8 +173,11 @@ swfdec_scriptable_set_variables (SwfdecS g_return_if_fail (SWFDEC_IS_SCRIPTABLE (script)); g_return_if_fail (variables != NULL); + SWFDEC_DEBUG ("setting variables on %p: %s", script, variables); + if (*variables == '\0') + return; object = swfdec_scriptable_get_object (script); - while (*variables) { + while (TRUE) { char *name, *value; JSString *string; jsval val; @@ -183,7 +186,9 @@ swfdec_scriptable_set_variables (SwfdecS SWFDEC_WARNING ("variables invalid at \"%s\"", variables); break; } - if (*variables != '&' && *variables != '\0') { + if (*variables == '\0') { + break; + } else if (*variables != '&') { SWFDEC_WARNING ("variables not delimited with & at \"%s\"", variables); g_free (name); g_free (value); diff-tree 28e968cbba77ca5493a624527e58513f52e542ac (from bdd525b89076158bfd947ed1eb0f48fcc24c55cb) Author: Benjamin Otte <otte@gnome.org> Date: Thu Mar 1 10:19:01 2007 +0100 implement the downloading part of the XML object diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am index 7f5cfb7..0c8564c 100644 --- a/libswfdec/Makefile.am +++ b/libswfdec/Makefile.am @@ -53,6 +53,7 @@ libswfdec_@SWFDEC_MAJORMINOR@_la_SOURCES swfdec_js_mouse.c \ swfdec_js_movie.c \ swfdec_js_sound.c \ + swfdec_js_xml.c \ swfdec_listener.c \ swfdec_loader.c \ swfdec_loadertarget.c \ @@ -76,7 +77,8 @@ libswfdec_@SWFDEC_MAJORMINOR@_la_SOURCES swfdec_tag.c \ swfdec_text.c \ swfdec_video.c \ - swfdec_video_movie.c + swfdec_video_movie.c \ + swfdec_xml.c libswfdec_@SWFDEC_MAJORMINOR@_la_CFLAGS = \ $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(CAIRO_CFLAGS) $(GLIB_CFLAGS) $(PANGO_CFLAGS) \ @@ -92,7 +94,6 @@ public_headers = \ swfdec.h \ swfdec_audio.h \ swfdec_buffer.h \ - swfdec_connection.h \ swfdec_loader.h \ swfdec_player.h @@ -113,6 +114,7 @@ noinst_HEADERS = \ swfdec_character.h \ swfdec_codec.h \ swfdec_color.h \ + swfdec_connection.h \ swfdec_debug.h \ swfdec_debugger.h \ swfdec_decoder.h \ @@ -149,7 +151,8 @@ noinst_HEADERS = \ swfdec_text.h \ swfdec_types.h \ swfdec_video.h \ - swfdec_video_movie.h + swfdec_video_movie.h \ + swfdec_xml.h EXTRA_DIST = swfdec_marshal.list diff --git a/libswfdec/swfdec_js.c b/libswfdec/swfdec_js.c index 6c39088..7fe7ae2 100644 --- a/libswfdec/swfdec_js.c +++ b/libswfdec/swfdec_js.c @@ -112,6 +112,7 @@ swfdec_js_init_player (SwfdecPlayer *pla swfdec_js_add_movieclip_class (player); swfdec_js_add_color (player); swfdec_js_add_sound (player); + swfdec_js_add_xml (player); swfdec_js_add_connection (player); player->mouse_listener = swfdec_listener_new (player); player->key_listener = swfdec_listener_new (player); diff --git a/libswfdec/swfdec_js.h b/libswfdec/swfdec_js.h index 77b5e89..fc16871 100644 --- a/libswfdec/swfdec_js.h +++ b/libswfdec/swfdec_js.h @@ -43,6 +43,7 @@ void swfdec_js_add_globals (SwfdecPlay void swfdec_js_add_mouse (SwfdecPlayer * player); void swfdec_js_add_movieclip_class (SwfdecPlayer * player); void swfdec_js_add_sound (SwfdecPlayer * player); +void swfdec_js_add_xml (SwfdecPlayer * player); void swfdec_js_movie_add_property (SwfdecMovie * movie); void swfdec_js_movie_remove_property (SwfdecMovie * movie); diff --git a/libswfdec/swfdec_js_xml.c b/libswfdec/swfdec_js_xml.c new file mode 100644 index 0000000..d6d0df5 --- /dev/null +++ b/libswfdec/swfdec_js_xml.c @@ -0,0 +1,101 @@ +/* Swfdec + * Copyright (C) 2007 Benjamin Otte <otte@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 "swfdec_xml.h" +#include "swfdec_debug.h" +#include "swfdec_js.h" +#include "swfdec_player_internal.h" + +static JSBool +swfdec_js_xml_load (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + SwfdecXml *xml; + const char *url; + + xml = JS_GetPrivate (cx, obj); + if (xml == NULL) + return JS_TRUE; + url = swfdec_js_to_string (cx, argv[0]); + if (url == NULL) + return JS_FALSE; + swfdec_xml_load (xml, url); + return JS_TRUE; +} + +static JSBool +swfdec_js_xml_to_string (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *string; + + string = JS_InternString (cx, "[object Object]"); + if (string == NULL) + return JS_FALSE; + + *rval = STRING_TO_JSVAL (string); + return JS_TRUE; +} + +static JSFunctionSpec xml_methods[] = { + { "load", swfdec_js_xml_load, 1, 0, 0 }, + { "toString", swfdec_js_xml_to_string, 0, 0, 0 }, + {0,0,0,0,0} +}; + +static void +swfdec_js_xml_finalize (JSContext *cx, JSObject *obj) +{ + SwfdecXml *conn; + + conn = JS_GetPrivate (cx, obj); + if (conn) { + SWFDEC_SCRIPTABLE (conn)->jsobj = NULL; + g_object_unref (conn); + } +} + +static JSClass xml_class = { + "XML", JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, swfdec_js_xml_finalize, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + +static JSBool +swfdec_js_xml_new (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + SwfdecXml *xml = swfdec_xml_new (JS_GetContextPrivate (cx)); + + JS_SetPrivate (cx, obj, xml); + SWFDEC_SCRIPTABLE (xml)->jsobj = obj; + *rval = OBJECT_TO_JSVAL (obj); + return JS_TRUE; +} + +void +swfdec_js_add_xml (SwfdecPlayer *player) +{ + JS_InitClass (player->jscx, player->jsobj, NULL, + &xml_class, swfdec_js_xml_new, 0, NULL, xml_methods, + NULL, NULL); +} + diff --git a/libswfdec/swfdec_xml.c b/libswfdec/swfdec_xml.c new file mode 100644 index 0000000..1f05c7d --- /dev/null +++ b/libswfdec/swfdec_xml.c @@ -0,0 +1,187 @@ +/* Swfdec + * Copyright (C) 2007 Benjamin Otte <otte@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_xml.h" +#include "swfdec_debug.h" +#include "swfdec_loadertarget.h" +#include "swfdec_player_internal.h" +#include "js/jsapi.h" +#include "js/jsinterp.h" + +/*** SWFDEC_LOADER_TARGET ***/ + +static SwfdecPlayer * +swfdec_xml_loader_target_get_player (SwfdecLoaderTarget *target) +{ + SwfdecXml *xml = SWFDEC_XML (target); + + return xml->player; +} + +static void +swfdec_xml_ondata (SwfdecXml *xml) +{ + JSContext *cx = SWFDEC_SCRIPTABLE (xml)->jscx; + JSObject *obj = SWFDEC_SCRIPTABLE (xml)->jsobj; + jsval val, fun; + JSString *string; + + if (!JS_GetProperty (cx, obj, "onData", &fun)) + return; + if (fun == JSVAL_VOID) + return; + if (xml->text) { + string = JS_NewStringCopyZ (cx, xml->text); + if (string == NULL) { + SWFDEC_ERROR ("Could not convert text to JS string"); + return; + } + val = STRING_TO_JSVAL (string); + } else { + val = JSVAL_VOID; + } + js_InternalCall (cx, obj, fun, 1, &val, &fun); +} + +static void +swfdec_xml_loader_target_parse (SwfdecLoaderTarget *target, SwfdecLoader *loader) +{ + SwfdecXml *xml = SWFDEC_XML (target); + + if (xml->loader != loader || + (!loader->eof && !loader->error)) + return; + + /* get the text from the loader */ + if (loader->error) { + /* nothing to do here */ + } else { + guint size; + g_assert (loader->eof); + size = swfdec_buffer_queue_get_depth (loader->queue); + xml->text = g_try_malloc (size + 1); + if (xml->text) { + SwfdecBuffer *buffer; + guint i = 0; + while ((buffer = swfdec_buffer_queue_pull_buffer (loader->queue))) { + memcpy (xml->text + i, buffer->data, buffer->length); + i += buffer->length; + swfdec_buffer_unref (buffer); + } + g_assert (i == size); + xml->text[size] = '\0'; + /* FIXME: validate otherwise? */ + if (!g_utf8_validate (xml->text, size, NULL)) { + SWFDEC_ERROR ("downloaded data is not valid utf-8"); + g_free (xml->text); + xml->text = NULL; + } + } else { + SWFDEC_ERROR ("not enough memory to copy %u bytes", size); + } + } + /* break reference to the loader */ + xml->loader = NULL; + g_object_unref (loader); + /* emit onData */ + swfdec_xml_ondata (xml); +} + +static void +swfdec_xml_loader_target_init (SwfdecLoaderTargetInterface *iface) +{ + iface->get_player = swfdec_xml_loader_target_get_player; + iface->parse = swfdec_xml_loader_target_parse; +} + +/*** SWFDEC_XML ***/ + +G_DEFINE_TYPE_WITH_CODE (SwfdecXml, swfdec_xml, SWFDEC_TYPE_SCRIPTABLE, + G_IMPLEMENT_INTERFACE (SWFDEC_TYPE_LOADER_TARGET, swfdec_xml_loader_target_init)) + +static void +swfdec_xml_reset (SwfdecXml *xml) +{ + if (xml->loader) { + g_object_unref (xml->loader); + xml->loader = NULL; + } + g_free (xml->text); + xml->text = NULL; +} + +static void +swfdec_xml_dispose (GObject *object) +{ + SwfdecXml *xml = SWFDEC_XML (object); + + swfdec_xml_reset (xml); + + G_OBJECT_CLASS (swfdec_xml_parent_class)->dispose (object); +} + +static void +swfdec_xml_class_init (SwfdecXmlClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = swfdec_xml_dispose; +} + +static void +swfdec_xml_init (SwfdecXml *xml) +{ +} + +SwfdecXml * +swfdec_xml_new (SwfdecPlayer *player) +{ + SwfdecXml *xml; + SwfdecScriptable *script; + + g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL); + + xml= g_object_new (SWFDEC_TYPE_XML, NULL); + xml->player = player; + + script = SWFDEC_SCRIPTABLE (xml); + script->jscx = player->jscx; + + return xml; +} + +void +swfdec_xml_load (SwfdecXml *xml, const char *url) +{ + g_return_if_fail (SWFDEC_IS_XML (xml)); + g_return_if_fail (url != NULL); + + swfdec_xml_reset (xml); + xml->loader = swfdec_player_load (xml->player, url); + if (xml->loader == NULL) { + swfdec_xml_ondata (xml); + } else { + swfdec_xml_loader_target_parse (SWFDEC_LOADER_TARGET (xml), xml->loader); + } +} diff --git a/libswfdec/swfdec_xml.h b/libswfdec/swfdec_xml.h new file mode 100644 index 0000000..b2b3ea8 --- /dev/null +++ b/libswfdec/swfdec_xml.h @@ -0,0 +1,59 @@ +/* Swfdec + * Copyright (C) 2007 Benjamin Otte <otte@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_XML_H_ +#define _SWFDEC_XML_H_ + +#include <libswfdec/swfdec_scriptable.h> + +G_BEGIN_DECLS + + +typedef struct _SwfdecXml SwfdecXml; +typedef struct _SwfdecXmlClass SwfdecXmlClass; + +#define SWFDEC_TYPE_XML (swfdec_xml_get_type()) +#define SWFDEC_IS_XML(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_XML)) +#define SWFDEC_IS_XML_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_XML)) +#define SWFDEC_XML(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_XML, SwfdecXml)) +#define SWFDEC_XML_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_XML, SwfdecXmlClass)) +#define SWFDEC_XML_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_XML, SwfdecXmlClass)) + +struct _SwfdecXml { + SwfdecScriptable scriptable; + + char * text; /* string that this XML displays */ + SwfdecPlayer * player; /* player we're playing in */ + SwfdecLoader * loader; /* loader when loading or NULL */ +}; + +struct _SwfdecXmlClass { + SwfdecScriptableClass scriptable_class; +}; + +GType swfdec_xml_get_type (void); + +SwfdecXml * swfdec_xml_new (SwfdecPlayer * player); + +void swfdec_xml_load (SwfdecXml * xml, + const char * url); + + +G_END_DECLS +#endif diff-tree bdd525b89076158bfd947ed1eb0f48fcc24c55cb (from 93fbadb06ab7eed16312904ecae3994af890532b) Author: Benjamin Otte <otte@gnome.org> Date: Thu Mar 1 10:18:22 2007 +0100 call the parse function after an error This gets around the need to connect to notify::error diff --git a/libswfdec/swfdec_loader.c b/libswfdec/swfdec_loader.c index 828852a..32d0ca4 100644 --- a/libswfdec/swfdec_loader.c +++ b/libswfdec/swfdec_loader.c @@ -319,6 +319,7 @@ swfdec_loader_error_locked (SwfdecLoader SWFDEC_ERROR ("error in loader %p: %s", loader, error); loader->error = g_strdup (error); g_object_notify (G_OBJECT (loader), "error"); + swfdec_loader_target_parse (loader->target, loader); } void diff --git a/libswfdec/swfdec_loadertarget.c b/libswfdec/swfdec_loadertarget.c index 8fd629d..6af5504 100644 --- a/libswfdec/swfdec_loadertarget.c +++ b/libswfdec/swfdec_loadertarget.c @@ -78,6 +78,8 @@ swfdec_loader_target_parse_default (Swfd SwfdecDecoder *dec; SwfdecDecoderClass *klass; + if (loader->error) + return; dec = swfdec_loader_target_get_decoder (target); if (dec == NULL) { SwfdecPlayer *player; diff-tree 93fbadb06ab7eed16312904ecae3994af890532b (from 767aca406c495f3eddbb0583cc0dc2e249d7fbf0) Author: Benjamin Otte <otte@gnome.org> Date: Wed Feb 28 21:10:10 2007 +0100 implement swfdec_player_load Also keep the initial loader around. This may be interesting if we ever want to implement swfdec_player_reset() to restart from the beginning. The only feature missing for that is non-destructive reading from the loader. diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c index 76c93e7..6de320b 100644 --- a/libswfdec/swfdec_player.c +++ b/libswfdec/swfdec_player.c @@ -367,6 +367,10 @@ swfdec_player_dispose (GObject *object) } g_assert (player->timeouts == NULL); swfdec_cache_unref (player->cache); + if (player->loader) { + g_object_unref (player->loader); + player->loader = NULL; + } G_OBJECT_CLASS (swfdec_player_parent_class)->dispose (object); } @@ -948,6 +952,16 @@ swfdec_player_remove_level (SwfdecPlayer SWFDEC_LOG ("no movie to remove at level %u", depth); } +SwfdecLoader * +swfdec_player_load (SwfdecPlayer *player, const char *url) +{ + g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL); + g_return_val_if_fail (url != NULL, NULL); + + g_assert (player->loader); + return swfdec_loader_load (player->loader, url); +} + void swfdec_player_launch (SwfdecPlayer *player, const char *url, const char *target) { @@ -1057,6 +1071,8 @@ swfdec_player_set_loader_with_variables g_return_if_fail (player->roots == NULL); g_return_if_fail (SWFDEC_IS_LOADER (loader)); + player->loader = loader; + g_object_ref (loader); movie = swfdec_player_add_level_from_loader (player, 0, loader, variables); swfdec_loader_parse (loader); } diff --git a/libswfdec/swfdec_player_internal.h b/libswfdec/swfdec_player_internal.h index 2e63b78..6d40273 100644 --- a/libswfdec/swfdec_player_internal.h +++ b/libswfdec/swfdec_player_internal.h @@ -49,6 +49,7 @@ struct _SwfdecPlayer SwfdecCache * cache; /* player cache */ gboolean bgcolor_set; /* TRUE if the background color has been set */ SwfdecColor bgcolor; /* background color */ + SwfdecLoader * loader; /* initial loader */ /* javascript */ JSContext * jscx; /* global Javascript context */ @@ -139,6 +140,8 @@ SwfdecRootMovie * swfdec_player_add_leve const char * variables); void swfdec_player_remove_level (SwfdecPlayer * player, guint depth); +SwfdecLoader * swfdec_player_load (SwfdecPlayer * player, + const char * url); void swfdec_player_launch (SwfdecPlayer * player, const char * url, const char * target); diff-tree 767aca406c495f3eddbb0583cc0dc2e249d7fbf0 (from 107c424998f16d2d4a2dd2d8645a7cff46094714) Author: Benjamin Otte <otte@gnome.org> Date: Wed Feb 28 16:18:49 2007 +0100 make swfdec_loader_error a properly exported function diff --git a/libswfdec/swfdec_loader.c b/libswfdec/swfdec_loader.c index 3beff3e..828852a 100644 --- a/libswfdec/swfdec_loader.c +++ b/libswfdec/swfdec_loader.c @@ -110,6 +110,7 @@ swfdec_loader_dispose (GObject *object) swfdec_buffer_queue_free (loader->queue); g_free (loader->url); + g_free (loader->error); G_OBJECT_CLASS (swfdec_loader_parent_class)->dispose (object); } @@ -281,9 +282,20 @@ swfdec_loader_new_from_file (const char return loader; } +/** + * swfdec_loader_error: + * @loader: a #SwfdecLoader + * @error: a string describing the error + * + * Moves the loader in the error state if it wasn't before. A loader that is in + * the error state will not process any more data. Also, internal error + * handling scripts may be executed. + **/ void swfdec_loader_error (SwfdecLoader *loader, const char *error) { + SwfdecPlayer *player; + g_return_if_fail (SWFDEC_IS_LOADER (loader)); g_return_if_fail (error != NULL); @@ -291,6 +303,20 @@ swfdec_loader_error (SwfdecLoader *loade if (loader->error) return; + player = swfdec_loader_target_get_player (loader->target); + swfdec_player_lock (player); + swfdec_loader_error_locked (loader, error); + swfdec_player_perform_actions (player); + swfdec_player_unlock (player); +} + +void +swfdec_loader_error_locked (SwfdecLoader *loader, const char *error) +{ + if (loader->error) + return; + + SWFDEC_ERROR ("error in loader %p: %s", loader, error); loader->error = g_strdup (error); g_object_notify (G_OBJECT (loader), "error"); } diff --git a/libswfdec/swfdec_loader_internal.h b/libswfdec/swfdec_loader_internal.h index c49f078..3c99959 100644 --- a/libswfdec/swfdec_loader_internal.h +++ b/libswfdec/swfdec_loader_internal.h @@ -31,6 +31,8 @@ SwfdecLoader * swfdec_loader_load (Swf void swfdec_loader_parse (SwfdecLoader * loader); void swfdec_loader_set_target (SwfdecLoader * loader, SwfdecLoaderTarget * target); +void swfdec_loader_error_locked (SwfdecLoader * loader, + const char * error); gboolean swfdec_urldecode_one (const char * string, char ** name, diff --git a/libswfdec/swfdec_loadertarget.c b/libswfdec/swfdec_loadertarget.c index 218a156..8fd629d 100644 --- a/libswfdec/swfdec_loadertarget.c +++ b/libswfdec/swfdec_loadertarget.c @@ -22,6 +22,7 @@ #endif #include "swfdec_loadertarget.h" +#include "swfdec_loader_internal.h" static void swfdec_loader_target_base_init (gpointer g_class) @@ -85,11 +86,11 @@ swfdec_loader_target_parse_default (Swfd player = swfdec_loader_target_get_player (target); dec = swfdec_decoder_new (player, loader->queue); if (dec == NULL) { - swfdec_loader_error (loader, "Unknown format"); + swfdec_loader_error_locked (loader, "Unknown format"); return; } if (!swfdec_loader_target_set_decoder (target, dec)) { - swfdec_loader_error (loader, "Internal error"); + swfdec_loader_error_locked (loader, "Internal error"); return; } } @@ -99,7 +100,7 @@ swfdec_loader_target_parse_default (Swfd SwfdecStatus status = klass->parse (dec); switch (status) { case SWFDEC_STATUS_ERROR: - swfdec_loader_error (loader, "parsing error"); + swfdec_loader_error_locked (loader, "parsing error"); return; case SWFDEC_STATUS_OK: break; @@ -107,7 +108,7 @@ swfdec_loader_target_parse_default (Swfd return; case SWFDEC_STATUS_IMAGE: if (!swfdec_loader_target_image (target)) { - swfdec_loader_error (loader, "Internal error"); + swfdec_loader_error_locked (loader, "Internal error"); return; } break; @@ -115,7 +116,7 @@ swfdec_loader_target_parse_default (Swfd g_assert (dec->width > 0); g_assert (dec->height > 0); if (!swfdec_loader_target_init (target)) { - swfdec_loader_error (loader, "Internal error"); + swfdec_loader_error_locked (loader, "Internal error"); return; } break; diff-tree 107c424998f16d2d4a2dd2d8645a7cff46094714 (from 2345e9a94736cce68debbc3519c4c645b462e2ae) Author: Benjamin Otte <otte@gnome.org> Date: Wed Feb 28 15:09:42 2007 +0100 rework Loader <=> LoaderTarget interaction These changes are preparing the use of loaders by the XML class. I also consider the overloaded SwfdecLoaderTarget interface pretty much deprecated in favour of the new parse method. I just need the will to implement it properly. :) diff --git a/libswfdec/swfdec_loader.c b/libswfdec/swfdec_loader.c index 49d7642..3beff3e 100644 --- a/libswfdec/swfdec_loader.c +++ b/libswfdec/swfdec_loader.c @@ -1,5 +1,5 @@ /* Swfdec - * Copyright (C) 2006 Benjamin Otte <otte@gnome.org> + * Copyright (C) 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -56,23 +56,62 @@ /*** SwfdecLoader ***/ +enum { + PROP_0, + PROP_ERROR, + PROP_EOF +}; + G_DEFINE_ABSTRACT_TYPE (SwfdecLoader, swfdec_loader, G_TYPE_OBJECT) static void -swfdec_loader_dispose (GObject *object) +swfdec_loader_get_property (GObject *object, guint param_id, GValue *value, + GParamSpec * pspec) { SwfdecLoader *loader = SWFDEC_LOADER (object); + + switch (param_id) { + case PROP_ERROR: + g_value_set_string (value, loader->error); + break; + case PROP_EOF: + g_value_set_boolean (value, loader->eof); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} - swfdec_buffer_queue_free (loader->queue); - g_free (loader->url); +static void +swfdec_loader_set_property (GObject *object, guint param_id, const GValue *value, + GParamSpec *pspec) +{ + SwfdecLoader *loader = SWFDEC_LOADER (object); - G_OBJECT_CLASS (swfdec_loader_parent_class)->dispose (object); + switch (param_id) { + case PROP_ERROR: + swfdec_loader_error (loader, g_value_get_string (value)); + break; + case PROP_EOF: + if (g_value_get_boolean (value) && !loader->eof) + swfdec_loader_eof (loader); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } } static void -swfdec_loader_do_error (SwfdecLoader *loader, const char *error) +swfdec_loader_dispose (GObject *object) { - SWFDEC_ERROR ("Error from loader %p: %s", loader, error); + SwfdecLoader *loader = SWFDEC_LOADER (object); + + swfdec_buffer_queue_free (loader->queue); + g_free (loader->url); + + G_OBJECT_CLASS (swfdec_loader_parent_class)->dispose (object); } static void @@ -81,8 +120,15 @@ swfdec_loader_class_init (SwfdecLoaderCl GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->dispose = swfdec_loader_dispose; + object_class->get_property = swfdec_loader_get_property; + object_class->set_property = swfdec_loader_set_property; - klass->error = swfdec_loader_do_error; + g_object_class_install_property (object_class, PROP_ERROR, + g_param_spec_string ("error", "error", "NULL when no error or string describing error", + NULL, G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_EOF, + g_param_spec_boolean ("eof", "eof", "TRUE when all data has been handed to the loader", + FALSE, G_PARAM_READABLE)); } static void @@ -235,70 +281,18 @@ swfdec_loader_new_from_file (const char return loader; } -static void -swfdec_loader_error (SwfdecLoader *loader, gboolean notify) -{ - loader->error = TRUE; - SWFDEC_INFO ("error in loader %p (%s)", loader, loader->url); - if (loader->target && notify) - swfdec_loader_target_error (loader->target); -} - void -swfdec_loader_parse_internal (SwfdecLoader *loader) +swfdec_loader_error (SwfdecLoader *loader, const char *error) { - SwfdecDecoder *dec; - SwfdecDecoderClass *klass; + g_return_if_fail (SWFDEC_IS_LOADER (loader)); + g_return_if_fail (error != NULL); - dec = swfdec_loader_target_get_decoder (loader->target); - if (dec == NULL) { - SwfdecPlayer *player; - if (!swfdec_decoder_can_detect (loader->queue)) - return; - player = swfdec_loader_target_get_player (loader->target); - dec = swfdec_decoder_new (player, loader->queue); - if (dec == NULL) { - swfdec_loader_error (loader, TRUE); - return; - } - if (!swfdec_loader_target_set_decoder (loader->target, dec)) { - swfdec_loader_error (loader, FALSE); - return; - } - } - klass = SWFDEC_DECODER_GET_CLASS (dec); - g_return_if_fail (klass->parse); - while (TRUE) { - SwfdecStatus status = klass->parse (dec); - switch (status) { - case SWFDEC_STATUS_ERROR: - swfdec_loader_error (loader, TRUE); - return; - case SWFDEC_STATUS_OK: - break; - case SWFDEC_STATUS_NEEDBITS: - return; - case SWFDEC_STATUS_IMAGE: - if (!swfdec_loader_target_image (loader->target)) { - swfdec_loader_error (loader, TRUE); - return; - } - break; - case SWFDEC_STATUS_INIT: - g_assert (dec->width > 0); - g_assert (dec->height > 0); - if (!swfdec_loader_target_init (loader->target)) { - swfdec_loader_error (loader, TRUE); - return; - } - break; - case SWFDEC_STATUS_EOF: - return; - default: - g_assert_not_reached (); - return; - } - } + SWFDEC_ERROR ("error in loader %p: %s", loader, error); + if (loader->error) + return; + + loader->error = g_strdup (error); + g_object_notify (G_OBJECT (loader), "error"); } void @@ -312,7 +306,7 @@ swfdec_loader_parse (SwfdecLoader *loade player = swfdec_loader_target_get_player (loader->target); swfdec_player_lock (player); - swfdec_loader_parse_internal (loader); + swfdec_loader_target_parse (loader->target, loader); swfdec_player_perform_actions (player); swfdec_player_unlock (player); } @@ -349,6 +343,7 @@ swfdec_loader_eof (SwfdecLoader *loader) g_return_if_fail (loader->eof == FALSE); loader->eof = TRUE; + g_object_notify (G_OBJECT (loader), "eof"); swfdec_loader_parse (loader); } diff --git a/libswfdec/swfdec_loader.h b/libswfdec/swfdec_loader.h index cf1d65a..87153b4 100644 --- a/libswfdec/swfdec_loader.h +++ b/libswfdec/swfdec_loader.h @@ -1,5 +1,5 @@ /* Swfdec - * Copyright (C) 2006 Benjamin Otte <otte@gnome.org> + * Copyright (C) 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -43,7 +43,7 @@ struct _SwfdecLoader char * url; /* the URL for this loader in UTF-8 - must be set on creation */ /*< private >*/ gboolean eof; /* if we're in EOF already */ - gboolean error; /* if there's an error (from parsing the loader) */ + char * error; /* if there's an error (from parsing the loader) */ gpointer target; /* SwfdecLoaderTarget that gets notified about loading progress */ SwfdecBufferQueue * queue; /* SwfdecBufferQueue managing the input buffers */ }; @@ -55,9 +55,6 @@ struct _SwfdecLoaderClass /* FIXME: better error reporting? */ SwfdecLoader * (* load) (SwfdecLoader * loader, const char * url); - /* FIXME: make this a GError? */ - void (* error) (SwfdecLoader * loader, - const char * error); }; GType swfdec_loader_get_type (void); @@ -68,6 +65,8 @@ SwfdecLoader * swfdec_loader_new_from_fi void swfdec_loader_push (SwfdecLoader * loader, SwfdecBuffer * buffer); void swfdec_loader_eof (SwfdecLoader * loader); +void swfdec_loader_error (SwfdecLoader * loader, + const char * error); char * swfdec_loader_get_filename (SwfdecLoader * loader); diff --git a/libswfdec/swfdec_loader_internal.h b/libswfdec/swfdec_loader_internal.h index 8f9a3db..c49f078 100644 --- a/libswfdec/swfdec_loader_internal.h +++ b/libswfdec/swfdec_loader_internal.h @@ -1,5 +1,5 @@ /* Swfdec - * Copyright (C) 2006 Benjamin Otte <otte@gnome.org> + * Copyright (C) 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,7 +29,6 @@ G_BEGIN_DECLS SwfdecLoader * swfdec_loader_load (SwfdecLoader * loader, const char * url); void swfdec_loader_parse (SwfdecLoader * loader); -void swfdec_loader_parse_internal (SwfdecLoader * loader); void swfdec_loader_set_target (SwfdecLoader * loader, SwfdecLoaderTarget * target); diff --git a/libswfdec/swfdec_loadertarget.c b/libswfdec/swfdec_loadertarget.c index 48b4090..218a156 100644 --- a/libswfdec/swfdec_loadertarget.c +++ b/libswfdec/swfdec_loadertarget.c @@ -71,28 +71,92 @@ swfdec_loader_target_get_player (SwfdecL return iface->get_player (target); } -SwfdecDecoder * -swfdec_loader_target_get_decoder (SwfdecLoaderTarget *target) +void +swfdec_loader_target_parse_default (SwfdecLoaderTarget *target, SwfdecLoader *loader) +{ + SwfdecDecoder *dec; + SwfdecDecoderClass *klass; + + dec = swfdec_loader_target_get_decoder (target); + if (dec == NULL) { + SwfdecPlayer *player; + if (!swfdec_decoder_can_detect (loader->queue)) + return; + player = swfdec_loader_target_get_player (target); + dec = swfdec_decoder_new (player, loader->queue); + if (dec == NULL) { + swfdec_loader_error (loader, "Unknown format"); + return; + } + if (!swfdec_loader_target_set_decoder (target, dec)) { + swfdec_loader_error (loader, "Internal error"); + return; + } + } + klass = SWFDEC_DECODER_GET_CLASS (dec); + g_return_if_fail (klass->parse); + while (TRUE) { + SwfdecStatus status = klass->parse (dec); + switch (status) { + case SWFDEC_STATUS_ERROR: + swfdec_loader_error (loader, "parsing error"); + return; + case SWFDEC_STATUS_OK: + break; + case SWFDEC_STATUS_NEEDBITS: + return; + case SWFDEC_STATUS_IMAGE: + if (!swfdec_loader_target_image (target)) { + swfdec_loader_error (loader, "Internal error"); + return; + } + break; + case SWFDEC_STATUS_INIT: + g_assert (dec->width > 0); + g_assert (dec->height > 0); + if (!swfdec_loader_target_init (target)) { + swfdec_loader_error (loader, "Internal error"); + return; + } + break; + case SWFDEC_STATUS_EOF: + return; + default: + g_assert_not_reached (); + return; + } + } +} + +void +swfdec_loader_target_parse (SwfdecLoaderTarget *target, SwfdecLoader *loader) { SwfdecLoaderTargetInterface *iface; - g_return_val_if_fail (SWFDEC_IS_LOADER_TARGET (target), NULL); + g_return_if_fail (SWFDEC_IS_LOADER_TARGET (target)); + g_return_if_fail (SWFDEC_IS_LOADER (loader)); + + if (loader->error) + return; iface = SWFDEC_LOADER_TARGET_GET_INTERFACE (target); - g_assert (iface->get_decoder != NULL); - return iface->get_decoder (target); + if (iface->parse == NULL) { + swfdec_loader_target_parse_default (target, loader); + } else { + iface->parse (target, loader); + } } -void -swfdec_loader_target_error (SwfdecLoaderTarget *target) +SwfdecDecoder * +swfdec_loader_target_get_decoder (SwfdecLoaderTarget *target) { SwfdecLoaderTargetInterface *iface; - g_return_if_fail (SWFDEC_IS_LOADER_TARGET (target)); + g_return_val_if_fail (SWFDEC_IS_LOADER_TARGET (target), NULL); iface = SWFDEC_LOADER_TARGET_GET_INTERFACE (target); - if (iface->error != NULL) - iface->error (target); + g_assert (iface->get_decoder != NULL); + return iface->get_decoder (target); } gboolean diff --git a/libswfdec/swfdec_loadertarget.h b/libswfdec/swfdec_loadertarget.h index fe26c5e..806ce82 100644 --- a/libswfdec/swfdec_loadertarget.h +++ b/libswfdec/swfdec_loadertarget.h @@ -38,11 +38,13 @@ struct _SwfdecLoaderTargetInterface { /* mandatory vfuncs */ SwfdecPlayer * (* get_player) (SwfdecLoaderTarget * target); + void (* parse) (SwfdecLoaderTarget * target, + SwfdecLoader * loader); + /* if default parser is used, you need the following - consider them deprecated */ SwfdecDecoder * (* get_decoder) (SwfdecLoaderTarget * target); gboolean (* set_decoder) (SwfdecLoaderTarget * target, SwfdecDecoder * decoder); /* optional vfuncs */ - void (* error) (SwfdecLoaderTarget * target); gboolean (* init) (SwfdecLoaderTarget * target); gboolean (* image) (SwfdecLoaderTarget * target); }; @@ -50,6 +52,8 @@ struct _SwfdecLoaderTargetInterface { GType swfdec_loader_target_get_type (void) G_GNUC_CONST; SwfdecPlayer * swfdec_loader_target_get_player (SwfdecLoaderTarget * target); +void swfdec_loader_target_parse (SwfdecLoaderTarget * target, + SwfdecLoader * loader); SwfdecDecoder * swfdec_loader_target_get_decoder (SwfdecLoaderTarget * target); gboolean swfdec_loader_target_set_decoder (SwfdecLoaderTarget * target, SwfdecDecoder * decoder); diff --git a/libswfdec/swfdec_root_movie.c b/libswfdec/swfdec_root_movie.c index 414838e..1b7c264 100644 --- a/libswfdec/swfdec_root_movie.c +++ b/libswfdec/swfdec_root_movie.c @@ -171,7 +171,7 @@ swfdec_root_movie_init (SwfdecRootMovie void swfdec_root_movie_do_parse (gpointer movie, gpointer unused) { - swfdec_loader_parse_internal (SWFDEC_ROOT_MOVIE (movie)->loader); + swfdec_loader_target_parse (SWFDEC_LOADER_TARGET (movie), SWFDEC_ROOT_MOVIE (movie)->loader); } void diff-tree 2345e9a94736cce68debbc3519c4c645b462e2ae (from a383a7e1a96e96c9718421b26d92e11ec9f69ea6) Author: Benjamin Otte <otte@gnome.org> Date: Wed Feb 28 12:40:29 2007 +0100 add simple test for NetConnection diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am index ea517f7..96d586f 100644 --- a/test/trace/Makefile.am +++ b/test/trace/Makefile.am @@ -82,6 +82,8 @@ EXTRA_DIST = \ name2.swf.trace \ names.swf \ names.swf.trace \ + netconnection.swf \ + netconnection.swf.trace \ number.swf \ number.swf.trace \ object-math-5.swf \ diff --git a/test/trace/netconnection.swf b/test/trace/netconnection.swf new file mode 100755 index 0000000..cb822ac Binary files /dev/null and b/test/trace/netconnection.swf differ diff --git a/test/trace/netconnection.swf.trace b/test/trace/netconnection.swf.trace new file mode 100755 index 0000000..296c2b7 --- /dev/null +++ b/test/trace/netconnection.swf.trace @@ -0,0 +1,6 @@ +test basic NetConnection functionality +caliing connect on [object Object]... +NetConnection.Connect.Success +status +undefined + done diff-tree a383a7e1a96e96c9718421b26d92e11ec9f69ea6 (from 134c98d16a0ce78f6869f8ef41c276d334750dc6) Author: Benjamin Otte <otte@gnome.org> Date: Wed Feb 28 12:38:03 2007 +0100 implement NetConnection object in a pretty stubbed form diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am index 1fd20c9..7f5cfb7 100644 --- a/libswfdec/Makefile.am +++ b/libswfdec/Makefile.am @@ -32,6 +32,7 @@ libswfdec_@SWFDEC_MAJORMINOR@_la_SOURCES $(CODECS) \ swfdec_codec_screen.c \ swfdec_color.c \ + swfdec_connection.c \ swfdec_debug.c \ swfdec_debugger.c \ swfdec_decoder.c \ @@ -47,6 +48,7 @@ libswfdec_@SWFDEC_MAJORMINOR@_la_SOURCES swfdec_image.c \ swfdec_js.c \ swfdec_js_color.c \ + swfdec_js_connection.c \ swfdec_js_global.c \ swfdec_js_mouse.c \ swfdec_js_movie.c \ @@ -90,6 +92,7 @@ public_headers = \ swfdec.h \ swfdec_audio.h \ swfdec_buffer.h \ + swfdec_connection.h \ swfdec_loader.h \ swfdec_player.h diff --git a/libswfdec/swfdec_connection.c b/libswfdec/swfdec_connection.c new file mode 100644 index 0000000..2360804 --- /dev/null +++ b/libswfdec/swfdec_connection.c @@ -0,0 +1,121 @@ +/* Swfdec + * Copyright (C) 2007 Benjamin Otte <otte@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_connection.h" +#include "swfdec_debug.h" +#include "js/jsapi.h" +#include "js/jsinterp.h" + +/*** SwfdecConnection ***/ + +G_DEFINE_TYPE (SwfdecConnection, swfdec_connection, SWFDEC_TYPE_SCRIPTABLE) + +static void +swfdec_connection_dispose (GObject *object) +{ + SwfdecConnection *connection = SWFDEC_CONNECTION (object); + + g_free (connection->url); + connection->url = NULL; + + G_OBJECT_CLASS (swfdec_connection_parent_class)->dispose (object); +} + +static void +swfdec_connection_class_init (SwfdecConnectionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = swfdec_connection_dispose; +} + +static void +swfdec_connection_init (SwfdecConnection *connection) +{ +} + +static void +swfdec_connection_onstatus (SwfdecConnection *conn, const char *code, + const char *level, const char *description) +{ + JSContext *cx = SWFDEC_SCRIPTABLE (conn)->jscx; + JSObject *obj = SWFDEC_SCRIPTABLE (conn)->jsobj; + JSObject *info; + jsval val, fun; + JSString *string; + + if (!JS_GetProperty (cx, obj, "onStatus", &fun)) + return; + if (fun == JSVAL_VOID) + return; + info = JS_NewObject (cx, NULL, NULL, NULL); + if (info == NULL || + (string = JS_NewStringCopyZ (cx, code)) == NULL || + (val = STRING_TO_JSVAL (string)) == 0 || + !JS_SetProperty (cx, info, "code", &val) || + (string = JS_NewStringCopyZ (cx, level)) == NULL || + (val = STRING_TO_JSVAL (string)) == 0 || + !JS_SetProperty (cx, info, "level", &val)) + return; + if (description) { + if ((string = JS_NewStringCopyZ (cx, level)) == NULL || + (val = STRING_TO_JSVAL (string)) == 0 || + !JS_SetProperty (cx, info, "description", &val)) + return; + } + val = OBJECT_TO_JSVAL (info); + js_InternalCall (cx, obj, fun, 1, &val, &fun); +} + +SwfdecConnection * +swfdec_connection_new (JSContext *cx, JSObject *obj) +{ + SwfdecConnection *conn; + SwfdecScriptable *script; + + g_return_val_if_fail (cx != NULL, NULL); + g_return_val_if_fail (obj != NULL, NULL); + + conn = g_object_new (SWFDEC_TYPE_CONNECTION, NULL); + script = SWFDEC_SCRIPTABLE (conn); + script->jscx = cx; + script->jsobj = obj; + + return conn; +} + +void +swfdec_connection_connect (SwfdecConnection *conn, const char *url) +{ + g_return_if_fail (SWFDEC_IS_CONNECTION (conn)); + + g_free (conn->url); + conn->url = g_strdup (url); + if (url) { + SWFDEC_ERROR ("FIXME: using NetConnection with non-null URLs is not implemented"); + } + swfdec_connection_onstatus (conn, "NetConnection.Connect.Success", + "status", NULL); +} + diff --git a/libswfdec/swfdec_connection.h b/libswfdec/swfdec_connection.h new file mode 100644 index 0000000..737a139 --- /dev/null +++ b/libswfdec/swfdec_connection.h @@ -0,0 +1,58 @@ +/* Swfdec + * Copyright (C) 2007 Benjamin Otte <otte@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_CONNECTION_H_ +#define _SWFDEC_CONNECTION_H_ + +#include <libswfdec/swfdec_scriptable.h> + +G_BEGIN_DECLS + + +typedef struct _SwfdecConnection SwfdecConnection; +typedef struct _SwfdecConnectionClass SwfdecConnectionClass; + +#define SWFDEC_TYPE_CONNECTION (swfdec_connection_get_type()) +#define SWFDEC_IS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_CONNECTION)) +#define SWFDEC_IS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_CONNECTION)) +#define SWFDEC_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_CONNECTION, SwfdecConnection)) +#define SWFDEC_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_CONNECTION, SwfdecConnectionClass)) +#define SWFDEC_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_CONNECTION, SwfdecConnectionClass)) + +struct _SwfdecConnection { + SwfdecScriptable scriptable; + + char * url; /* url for this connection or NULL for none */ +}; + +struct _SwfdecConnectionClass { + SwfdecScriptableClass scriptable_class; +}; + +GType swfdec_connection_get_type (void); + +SwfdecConnection * swfdec_connection_new (JSContext * cx, + JSObject * obj); + +void swfdec_connection_connect (SwfdecConnection * conn, + const char * url); + + +G_END_DECLS +#endif diff --git a/libswfdec/swfdec_js.c b/libswfdec/swfdec_js.c index b9313c1..6c39088 100644 --- a/libswfdec/swfdec_js.c +++ b/libswfdec/swfdec_js.c @@ -112,6 +112,7 @@ swfdec_js_init_player (SwfdecPlayer *pla swfdec_js_add_movieclip_class (player); swfdec_js_add_color (player); swfdec_js_add_sound (player); + swfdec_js_add_connection (player); player->mouse_listener = swfdec_listener_new (player); player->key_listener = swfdec_listener_new (player); } diff --git a/libswfdec/swfdec_js.h b/libswfdec/swfdec_js.h index 5e58152..77b5e89 100644 --- a/libswfdec/swfdec_js.h +++ b/libswfdec/swfdec_js.h @@ -38,6 +38,7 @@ gboolean swfdec_js_run (SwfdecPlayer * jsval * rval); void swfdec_js_add_color (SwfdecPlayer * player); +void swfdec_js_add_connection (SwfdecPlayer * player); void swfdec_js_add_globals (SwfdecPlayer * player); void swfdec_js_add_mouse (SwfdecPlayer * player); void swfdec_js_add_movieclip_class (SwfdecPlayer * player); diff --git a/libswfdec/swfdec_js_connection.c b/libswfdec/swfdec_js_connection.c new file mode 100644 index 0000000..7e820f8 --- /dev/null +++ b/libswfdec/swfdec_js_connection.c @@ -0,0 +1,108 @@ +/* Swfdec + * Copyright (C) 2007 Benjamin Otte <otte@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 "swfdec_connection.h" +#include "swfdec_debug.h" +#include "swfdec_js.h" +#include "swfdec_player_internal.h" + +static JSBool +swfdec_js_connection_connect (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + const char *url; + SwfdecConnection *conn = SWFDEC_CONNECTION (JS_GetPrivate (cx, obj)); + + if (conn == NULL) { + SWFDEC_INFO ("connect called on prototype, ignoring"); + return JS_TRUE; + } + if (JSVAL_IS_STRING (argv[0])) { + url = swfdec_js_to_string (cx, argv[0]); + if (url == NULL) + return JS_FALSE; + } else if (JSVAL_IS_NULL (argv[0])) { + url = NULL; + } else { + SWFDEC_INFO ("untested argument to NetConnection.connect: %lu", argv[0]); + url = NULL; + } + swfdec_connection_connect (conn, url); + return JS_TRUE; +} + +static JSBool +swfdec_js_connection_to_string (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *string; + + string = JS_InternString (cx, "[object Object]"); + if (string == NULL) + return JS_FALSE; + + *rval = STRING_TO_JSVAL (string); + return JS_TRUE; +} + +static JSFunctionSpec connection_methods[] = { + { "connect", swfdec_js_connection_connect, 1, 0, 0 }, + { "toString", swfdec_js_connection_to_string, 0, 0, 0 }, + {0,0,0,0,0} +}; + +static void +swfdec_js_connection_finalize (JSContext *cx, JSObject *obj) +{ + SwfdecConnection *conn; + + conn = JS_GetPrivate (cx, obj); + if (conn) { + SWFDEC_SCRIPTABLE (conn)->jsobj = NULL; + g_object_unref (conn); + } +} + +static JSClass connection_class = { + "NetConnection", JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, swfdec_js_connection_finalize, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + +static JSBool +swfdec_js_connection_new (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + SwfdecConnection *conn = swfdec_connection_new (cx, obj); + + JS_SetPrivate (cx, obj, conn); + *rval = OBJECT_TO_JSVAL (obj); + return JS_TRUE; +} + +void +swfdec_js_add_connection (SwfdecPlayer *player) +{ + JS_InitClass (player->jscx, player->jsobj, NULL, + &connection_class, swfdec_js_connection_new, 0, NULL, connection_methods, + NULL, NULL); +} + diff-tree 134c98d16a0ce78f6869f8ef41c276d334750dc6 (from 66851d9bc67c5663464a4c9488235e3c233579a7) Author: Benjamin Otte <otte@gnome.org> Date: Thu Feb 22 22:58:31 2007 +0100 add debug warning about missing constructors diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index d688693..6e75785 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -1391,9 +1391,11 @@ swfdec_action_new_object (JSContext *cx, JSObject *object; const JSClass *clasp; guint n_args; + const char *name; constructor = fp->sp[-1]; - if (!swfdec_eval_jsval (cx, NULL, &constructor)) + name = swfdec_eval_jsval (cx, NULL, &constructor); + if (name == NULL) return JS_FALSE; if (!JS_ValueToECMAUint32 (cx, fp->sp[-2], &n_args)) return JS_FALSE; @@ -1401,6 +1403,9 @@ swfdec_action_new_object (JSContext *cx, SWFDEC_ERROR ("not enough stack space"); return JS_FALSE; } + if (constructor == JSVAL_VOID) { + SWFDEC_WARNING ("no constructor for %s", name); + } fp->sp[-1] = constructor; if (!JSVAL_IS_OBJECT (constructor) || JSVAL_IS_NULL (constructor))
Reasonably Related Threads
- Branch 'as' - 17 commits - configure.ac doc/Makefile.am doc/swfdec-docs.sgml doc/swfdec-sections.txt doc/swfdec.types libswfdec-gtk/Makefile.am libswfdec-gtk/swfdec-gtk.h libswfdec-gtk/swfdec_gtk_loader.c libswfdec-gtk/swfdec_gtk_loader.h
- 9 commits - doc/swfdec-sections.txt libswfdec/swfdec_as_frame.c libswfdec/swfdec_loader.c libswfdec/swfdec_loader.h libswfdec/swfdec_loader_internal.h libswfdec/swfdec_loadertarget.c libswfdec/swfdec_loadertarget.h libswfdec/swfdec_movie.c
- 15 commits - configure.ac doc/swfdec-sections.txt libswfdec-gtk/Makefile.am libswfdec-gtk/swfdec_gtk_loader.c libswfdec/Makefile.am libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_file_loader.c libswfdec/swfdec_file_loader.h
- 5 commits - doc/Makefile.am doc/swfdec-docs.sgml doc/swfdec-sections.txt libswfdec/swfdec_loader.c libswfdec/swfdec_player.c
- libswfdec/swfdec_loader.c libswfdec/swfdec_loader.h libswfdec/swfdec_loader_internal.h libswfdec/swfdec_net_stream.c libswfdec/swfdec_root_movie.c libswfdec/swfdec_xml.c