OSDN Git Service

LinGui: oops. forgot to add new appcast files
authorjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Sun, 9 Nov 2008 19:27:46 +0000 (19:27 +0000)
committerjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Sun, 9 Nov 2008 19:27:46 +0000 (19:27 +0000)
git-svn-id: svn://localhost/HandBrake/trunk@1911 b64f7644-9d1e-0410-96f1-a4d463321fa5

gtk/src/appcast.c [new file with mode: 0644]
gtk/src/appcast.h [new file with mode: 0644]

diff --git a/gtk/src/appcast.c b/gtk/src/appcast.c
new file mode 100644 (file)
index 0000000..114b653
--- /dev/null
@@ -0,0 +1,271 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * appcast.c
+ * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
+ * 
+ * appcast.c is free software.
+ * 
+ * You may redistribute it and/or modify it under the terms of the
+ * GNU General Public License, as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include "icon_tools.h"
+#include "plist.h"
+#include "values.h"
+
+enum
+{
+       A_NONE = 0,
+       A_DESCRIPTION,
+       A_ENCLOSURE,
+       A_ITEM,
+};
+
+typedef struct
+{
+       gchar *tag;
+       gint id;
+} tag_map_t;
+
+static tag_map_t tag_map[] =
+{
+       {"description", A_DESCRIPTION},
+       {"enclosure", A_ENCLOSURE},
+       {"item", A_ITEM},
+};
+#define TAG_MAP_SZ     (sizeof(tag_map)/sizeof(tag_map_t))
+
+typedef struct
+{
+       gchar *key;
+       gchar *value;
+       GQueue *stack;
+       GQueue *tag_stack;
+       GString *description;
+       gchar *build;
+       gchar *version;
+       gboolean item;
+} parse_data_t;
+
+static const gchar*
+lookup_attr_value(
+       const gchar *name, 
+       const gchar **attr_names, 
+       const gchar **attr_values)
+{
+       gint ii;
+
+       if (attr_names == NULL) return NULL;
+       for (ii = 0; attr_names[ii] != NULL; ii++)
+       {
+               if (strcmp(name, attr_names[ii]) == 0)
+                       return attr_values[ii];
+       }
+       return NULL;
+}
+static void
+start_element(
+       GMarkupParseContext *ctx, 
+       const gchar *tag, 
+       const gchar **attr_names,
+       const gchar **attr_values,
+       gpointer ud,
+       GError **error)
+{
+       parse_data_t *pd = (parse_data_t*)ud;
+       union 
+       {
+               gint id;
+               gpointer pid;
+       } id;
+       gint ii;
+
+       for (ii = 0; ii < TAG_MAP_SZ; ii++)
+       {
+               if (strcmp(tag, tag_map[ii].tag) == 0)
+               {
+                       id.id = tag_map[ii].id;
+                       break;
+               }
+       }
+       if (ii == TAG_MAP_SZ)
+       {
+               g_debug("Unrecognized start tag (%s)", tag);
+               id.id = A_NONE;
+       }
+       g_queue_push_head(pd->tag_stack, id.pid);
+       switch (id.id)
+       {
+               case A_ITEM:
+               {
+                       pd->item = TRUE;
+               } break;
+               case A_ENCLOSURE:
+               {
+                       const gchar *build, *version;
+                       build = lookup_attr_value(
+                                               "sparkle:version", attr_names, attr_values);
+                       version = lookup_attr_value(
+                                               "sparkle:shortVersionString", attr_names, attr_values);
+                       if (build)
+                               pd->build = g_strdup(build);
+                       if (version)
+                               pd->version = g_strdup(version);
+               } break;
+       }
+}
+
+static void
+end_element(
+       GMarkupParseContext *ctx, 
+       const gchar *tag, 
+       gpointer ud,
+       GError **error)
+{
+       parse_data_t *pd = (parse_data_t*)ud;
+       gint id;
+       union 
+       {
+               gint id;
+               gpointer pid;
+       } start_id;
+       gint ii;
+
+       for (ii = 0; ii < TAG_MAP_SZ; ii++)
+       {
+               if (strcmp(tag, tag_map[ii].tag) == 0)
+               {
+                       id = tag_map[ii].id;
+                       break;
+               }
+       }
+       if (ii == TAG_MAP_SZ)
+       {
+               g_debug("Unrecognized end tag (%s)", tag);
+               id = A_NONE;
+       }
+       start_id.pid = g_queue_pop_head(pd->tag_stack);
+       if (start_id.id != id)
+               g_warning("start tag != end tag: (%s %d) %d", tag, start_id.id, id);
+       switch (id)
+       {
+               case A_ITEM:
+               {
+                       pd->item = FALSE;
+               } break;
+               default:
+               {
+               } break;
+       }
+
+}
+
+static void
+text_data(
+       GMarkupParseContext *ctx, 
+       const gchar *text, 
+       gsize len,
+       gpointer ud,
+       GError **error)
+{
+       parse_data_t *pd = (parse_data_t*)ud;
+       union 
+       {
+               gint id;
+               gpointer pid;
+       } start_id;
+
+       start_id.pid = g_queue_peek_head(pd->tag_stack);
+       switch (start_id.id)
+       {
+               case A_DESCRIPTION:
+               {
+                       if (pd->item)
+                       {
+                               g_string_append(pd->description, text);
+                       }
+               } break;
+               default:
+               {
+                       if (pd->value) g_free(pd->value);
+                       pd->value = g_strdup(text);
+               } break;
+       }
+}
+
+static void
+passthrough(
+       GMarkupParseContext *ctx, 
+       const gchar *text, 
+       gsize len,
+       gpointer ud,
+       GError **error)
+{
+       //parse_data_t *pd = (parse_data_t*)ud;
+
+       //g_debug("passthrough %s", text);
+}
+
+static void
+parse_error(GMarkupParseContext *ctx, GError *error, gpointer ud)
+{
+       g_warning("Resource parse error: %s", error->message);
+}
+
+// This is required or the parser crashes
+static void 
+destroy_notify(gpointer data)
+{ // Do nothing
+       //g_debug("destroy parser");
+}
+
+void
+ghb_appcast_parse(gchar *buf, gchar **desc, gchar **build, gchar **version)
+{
+       GMarkupParseContext *ctx;
+       GMarkupParser parser;
+       parse_data_t pd;
+       GError *err = NULL;
+       gint len;
+       gchar *start;
+       //gchar tmp[4096]
+
+       // Skip junk at beginning of buffer
+       start = strstr(buf, "<?xml ");
+       pd.description = g_string_new("");
+       pd.item = FALSE;
+       pd.build = NULL;
+       pd.version = NULL;
+       len = strlen(start);
+       pd.tag_stack = g_queue_new();
+       pd.key = NULL;
+       pd.value = NULL;
+
+       parser.start_element = start_element;
+       parser.end_element = end_element;
+       parser.text = text_data;
+       parser.passthrough = passthrough;
+       parser.error = parse_error;
+       ctx = g_markup_parse_context_new(
+                       &parser, G_MARKUP_TREAT_CDATA_AS_TEXT, &pd, destroy_notify);
+
+       g_markup_parse_context_parse(ctx, start, len, &err);
+       g_markup_parse_context_end_parse(ctx, &err);
+       g_markup_parse_context_free(ctx);
+       g_queue_free(pd.tag_stack);
+       *desc = g_string_free(pd.description, FALSE);
+       // work around a bug to leaves the CDATA closing brakets on the string
+       gchar *glitch;
+       glitch = g_strrstr(*desc, "]]>");
+       if (glitch)
+               *glitch = 0;
+       *build = pd.build;
+       *version = pd.version;
+}
diff --git a/gtk/src/appcast.h b/gtk/src/appcast.h
new file mode 100644 (file)
index 0000000..2520be6
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program 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 Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
+ */
+#if !defined(_GHB_APPCAST_H_)
+#define _GHB_APPCAST_H_
+
+void ghb_appcast_parse(
+       gchar *buf, gchar **desc, gchar **build, gchar **version);
+
+#endif // _GHB_APPCAST_H_