make swfdec_as_object_mark() only mark if not marked yet
[swfdec.git] / swfdec / swfdec_file_loader.c
blob1632075eb832912ecada6bb65df888e9800a2126
1 /* Swfdec
2 * Copyright (C) 2006-2007 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include <string.h>
25 #include "swfdec_loader_internal.h"
26 #include "swfdec_buffer.h"
27 #include "swfdec_debug.h"
28 #include "swfdec_player_internal.h"
30 /**
31 * SwfdecFileLoader:
33 * This is a #SwfdecLoader that can load content from files. This symbol is
34 * exported so you can subclass your own loaders from it and have automatic
35 * file access.
38 G_DEFINE_TYPE (SwfdecFileLoader, swfdec_file_loader, SWFDEC_TYPE_LOADER)
40 static void
41 swfdec_file_loader_load (SwfdecLoader *loader, SwfdecPlayer *player,
42 const char *url_string, SwfdecBuffer *buffer, guint header_count,
43 const char **header_names, const char **header_values)
45 SwfdecStream *stream = SWFDEC_STREAM (loader);
46 GError *error = NULL;
47 char *real, *unescape, *concat;
48 SwfdecURL *url;
50 if (swfdec_url_path_is_relative (url_string)) {
51 url = swfdec_url_new_relative (swfdec_player_get_base_url (player), url_string);
52 } else {
53 url = swfdec_url_new (url_string);
55 if (url == NULL) {
56 swfdec_stream_error (stream, "%s is an invalid URL", url_string);
57 return;
59 swfdec_loader_set_url (loader, swfdec_url_get_url (url));
60 if (!g_str_equal (swfdec_url_get_protocol (url), "file")) {
61 swfdec_stream_error (stream, "Don't know how to handle this protocol");
62 swfdec_url_free (url);
63 return;
65 if (swfdec_url_get_host (url)) {
66 swfdec_stream_error (stream, "filenames cannot have hostnames");
67 swfdec_url_free (url);
68 return;
71 // FIXME: Should probably use swfdec_as_string_unescape here
72 if (strstr (swfdec_url_get_path (url), "%00") != 0) {
73 char *path = g_strdup (swfdec_url_get_path (url));
74 *strstr (path, "%00") = 0;
75 unescape = g_uri_unescape_string (path, NULL);
76 g_free (path);
77 } else {
78 unescape = g_uri_unescape_string (swfdec_url_get_path (url), NULL);
80 if (unescape == NULL) {
81 swfdec_stream_error (stream, "unescaping file path failed");
82 swfdec_url_free (url);
83 return;
85 /* Swfdec ignores query strings, just like Flash 9.0.124.0 and onwards.
86 * Might be a useful quirk to have though */
87 #ifdef QUIRKS_MODE
88 if (swfdec_url_get_query (url)) {
89 concat = g_strconcat ("/", unescape, "?", swfdec_url_get_query (url), NULL);
90 } else {
91 concat = g_strconcat ("/", unescape, NULL);
93 #else
94 concat = g_strconcat ("/", unescape, NULL);
95 #endif
96 g_free (unescape);
97 real = g_filename_from_utf8 (concat, -1, NULL, NULL, &error);
98 g_free (concat);
99 if (real == NULL) {
100 swfdec_stream_error (stream, "%s", error->message);
101 g_error_free (error);
102 swfdec_url_free (url);
103 return;
105 buffer = swfdec_buffer_new_from_file (real, &error);
106 g_free (real);
107 if (buffer == NULL) {
108 swfdec_stream_error (stream, "%s", error->message);
109 g_error_free (error);
110 } else {
111 swfdec_loader_set_size (loader, buffer->length);
112 swfdec_stream_open (stream);
113 swfdec_stream_push (stream, buffer);
114 swfdec_stream_close (stream);
116 swfdec_url_free (url);
119 static void
120 swfdec_file_loader_class_init (SwfdecFileLoaderClass *klass)
122 SwfdecLoaderClass *loader_class = SWFDEC_LOADER_CLASS (klass);
124 loader_class->load = swfdec_file_loader_load;
127 static void
128 swfdec_file_loader_init (SwfdecFileLoader *loader)