[totem-pl-parser] Use GZlibDecompressor
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [totem-pl-parser] Use GZlibDecompressor
- Date: Wed, 5 May 2010 10:53:03 +0000 (UTC)
commit 71ab73dd80816243958f997460b68c81192f6341
Author: Christian Persch <chpe gnome org>
Date: Wed May 5 01:40:37 2010 +0200
Use GZlibDecompressor
Untested!
Bug #617664.
configure.in | 2 +-
plparse/totem-pl-parser-podcast.c | 180 +++++++++++++------------------------
2 files changed, 64 insertions(+), 118 deletions(-)
---
diff --git a/configure.in b/configure.in
index a3b56d4..d2249c0 100644
--- a/configure.in
+++ b/configure.in
@@ -40,7 +40,7 @@ AC_PATH_PROG([GLIB_MKENUMS],[glib-mkenums])
# Requirements
GLIB_REQS=2.21.6
-GIO_REQS=2.17.3
+GIO_REQS=2.24.0
# Before making a release, the PLPARSER_LT_VERSION string should be modified.
# The string is of the form C:R:A.
diff --git a/plparse/totem-pl-parser-podcast.c b/plparse/totem-pl-parser-podcast.c
index 6b91894..7ca0319 100644
--- a/plparse/totem-pl-parser-podcast.c
+++ b/plparse/totem-pl-parser-podcast.c
@@ -572,91 +572,6 @@ totem_pl_parser_add_xml_feed (TotemPlParser *parser,
#endif /* !HAVE_GMIME */
}
-/* From libgsf's gsf-utils.h */
-#define GSF_LE_GET_GUINT32(p) \
- (guint32)((((guint8 const *)(p))[0] << 0) | \
- (((guint8 const *)(p))[1] << 8) | \
- (((guint8 const *)(p))[2] << 16) | \
- (((guint8 const *)(p))[3] << 24))
-
-/* From libgsf's gsf-input-gzip.c */
-/* gzip flag byte */
-#define GZIP_IS_ASCII 0x01 /* file contains text ? */
-#define GZIP_HEADER_CRC 0x02 /* there is a CRC in the header */
-#define GZIP_EXTRA_FIELD 0x04 /* there is an 'extra' field */
-#define GZIP_ORIGINAL_NAME 0x08 /* the original is stored */
-#define GZIP_HAS_COMMENT 0x10 /* There is a comment in the header */
-#define GZIP_HEADER_FLAGS (unsigned)(GZIP_IS_ASCII |GZIP_HEADER_CRC |GZIP_EXTRA_FIELD |GZIP_ORIGINAL_NAME |GZIP_HAS_COMMENT)
-
-static guint32
-check_header (char *data, gsize len)
-{
- static guint8 const signature[2] = {0x1f, 0x8b};
- unsigned flags;
-
- if (len < 2 + 1 + 1 + 6)
- return 0;
-
- /* Check signature */
- if (memcmp (data, signature, sizeof (signature)) != 0)
- return 0;
-
- /* verify flags and compression type */
- flags = data[3];
- if (data[2] != Z_DEFLATED || (flags & ~GZIP_HEADER_FLAGS) != 0)
- return 0;
-
- /* Get the uncompressed size */
- /* FIXME, but how? The size read here is modulo 2^32. */
- return GSF_LE_GET_GUINT32 (data + len - 4);
-}
-
-static char *
-decompress_gzip (char *data, gsize len)
-{
- guint32 retlen;
- char *ret;
- int zerr;
- z_stream stream;
-
- retlen = check_header (data, len);
- if (retlen == 0)
- return g_strdup (data);
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
- stream.opaque = (voidpf)0;
- stream.next_in = Z_NULL;
- stream.next_out = Z_NULL;
- stream.avail_in = stream.avail_out = 0;
-
- /* 16 + MAX_WBITS as per http://hewgill.com/journal/entries/349 */
- if (Z_OK != inflateInit2 (&stream, 16 + MAX_WBITS))
- return NULL;
-
- /* +1 so it's NULL-terminated */
- ret = g_malloc0 (retlen + 1);
-
- stream.next_in = (unsigned char *) data;
- stream.avail_in = len;
-
- stream.next_out = (unsigned char *) ret;
- stream.avail_out = retlen;
-
- zerr = inflate (&stream, Z_NO_FLUSH);
- if (zerr != Z_OK && zerr != Z_STREAM_END) {
- g_free (ret);
- return NULL;
- }
- zerr = inflateEnd (&stream);
- if (zerr != Z_OK) {
- g_free (ret);
- return NULL;
- }
-
- return ret;
-}
-
static const char *
totem_pl_parser_parse_itms_doc (xml_node_t *item)
{
@@ -713,8 +628,49 @@ totem_pl_parser_get_feed_uri (char *data, gsize len)
return ret;
}
+static GByteArray *
+totem_pl_parser_get_content_decompressed (GFile *file)
+{
+ GFileInputStream *file_in;
+ GInputStream *converter_in;
+ GConverter *decompressor;
+ GByteArray *data;
+ gsize position;
+ gssize n_read;
+
+ file_in = g_file_read (file, NULL, NULL);
+ if (file_in == NULL)
+ return NULL;
+
+ decompressor = G_CONVERTER (g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP));
+ converter_in = g_converter_input_stream_new (G_INPUT_STREAM (file_in), decompressor);
+ g_object_unref (file_in);
+ g_object_unref (decompressor);
+
+#define BLOCK_SIZE 8192
+ position = 0;
+ data = g_byte_array_sized_new (BLOCK_SIZE + 1);
+ while ((n_read = g_input_stream_read (converter_in,
+ data->data + position,
+ BLOCK_SIZE,
+ NULL, NULL)) > 0) {
+ position += n_read;
+ g_byte_array_set_size (data, position + BLOCK_SIZE + 1);
+ }
+
+ g_object_unref (converter_in);
+
+ if (n_read < 0) {
+ g_byte_array_free (data, TRUE);
+ return NULL;
+ }
+
+ return data;
+}
+
static char *
-totem_pl_parser_get_itms_uri (const char *data)
+totem_pl_parser_get_itms_uri (const char *data,
+ gsize data_len)
{
char *s, *end, *ret;
#define ITMS_OPEN "<body onload=\"return itmsOpen('"
@@ -722,11 +678,14 @@ totem_pl_parser_get_itms_uri (const char *data)
/* The bit of text looks like:
* <body onload="return itmsOpen('itms://ax.phobos.apple.com.edgesuite.net/WebObjects/MZStore.woa/wa/viewPodcast?id=207870198&ign-mscache=1','http://www.apple.com/uk/itunes/affiliates/download/?itmsUrl=itms%3A%2F%2Fax.phobos.apple.com.edgesuite.net%2FWebObjects%2FMZStore.woa%2Fwa%2FviewPodcast%3Fid%3D207870198%26ign-mscache%3D1','userOverridePanel',false)"> */
- s = strstr (data, ITMS_OPEN);
+ s = g_strstr_len (data, data_len, ITMS_OPEN);
if (s == NULL)
return NULL;
- s = s + strlen (ITMS_OPEN);
- end = strchr (s, '\'');
+ s += strlen (ITMS_OPEN);
+ if (s[0] != 'i' || s[1] != 't' || s[2] != 'm' || s[3] != 's')
+ return NULL;
+
+ end = g_strstr_len (s, data + data_len - s, "\'");
if (end == NULL)
return NULL;
@@ -745,57 +704,44 @@ totem_pl_parser_add_itms (TotemPlParser *parser,
#ifndef HAVE_GMIME
WARN_NO_GMIME;
#else
- char *contents, *uncompressed, *itms_uri;
+ GByteArray *content;
+ char *itms_uri;
GFile *itms_file, *feed_file;
TotemPlParserResult ret;
- gsize size;
if (g_file_has_uri_scheme (file, "itms") == FALSE) {
- /* Get the webpage */
- if (g_file_load_contents (file, NULL, &contents, &size, NULL, NULL) == FALSE) {
- DEBUG(file, g_print ("Couldn't load contents for %s\n", uri));
- return TOTEM_PL_PARSER_RESULT_ERROR;
- }
-
- uncompressed = decompress_gzip (contents, size);
- g_free (contents);
- if (uncompressed == NULL) {
- DEBUG(file, g_print ("Couldn't decompress %s\n", uri));
+ content = totem_pl_parser_get_content_decompressed (file);
+ if (content == NULL)
return TOTEM_PL_PARSER_RESULT_ERROR;
- }
/* Look for the link to the itms on phobos */
- itms_uri = totem_pl_parser_get_itms_uri (uncompressed);
- g_free (uncompressed);
+ itms_uri = totem_pl_parser_get_itms_uri ((const char*) content->data, content->len);
+ g_byte_array_free (content, TRUE);
} else {
itms_uri= g_file_get_uri (file);
memcpy (itms_uri, "http", 4);
}
+ if (itms_uri == NULL)
+ return TOTEM_PL_PARSER_RESULT_ERROR;
+
/* Get the phobos linked, in some weird iTunes only format */
itms_file = g_file_new_for_uri (itms_uri);
g_free (itms_uri);
- if (g_file_load_contents (itms_file, NULL, &contents, &size, NULL, NULL) == FALSE) {
+ content = totem_pl_parser_get_content_decompressed (itms_file);
+ if (content == NULL) {
DEBUG(itms_file, g_print ("Couldn't load contents for itms_file %s\n", uri));
g_object_unref (itms_file);
return TOTEM_PL_PARSER_RESULT_ERROR;
}
g_object_unref (itms_file);
- uncompressed = decompress_gzip (contents, size);
- g_free (contents);
- if (uncompressed == NULL) {
- DEBUG(itms_file, g_print ("Couldn't decompress itms_file %s\n", uri));
- return TOTEM_PL_PARSER_RESULT_ERROR;
- }
-
/* And look in the file for the feedURL */
- feed_file = totem_pl_parser_get_feed_uri (uncompressed, strlen (uncompressed) + 1);
- if (feed_file == NULL) {
- g_free (uncompressed);
+ feed_file = totem_pl_parser_get_feed_uri ((char *) content->data, content->len);
+ g_byte_array_free (content, TRUE);
+ if (feed_file == NULL)
return TOTEM_PL_PARSER_RESULT_ERROR;
- }
DEBUG(feed_file, g_print ("Found feed URI: %s\n", uri));
@@ -827,7 +773,7 @@ totem_pl_parser_is_itms_feed (GFile *file)
if (strstr (uri, "phobos.apple.com/") != NULL
&& strstr (uri, "viewPodcast") != NULL) {
- g_free (uri);
+ g_free (uri);
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]