diff options
author | jstebbins <[email protected]> | 2008-11-09 19:27:46 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2008-11-09 19:27:46 +0000 |
commit | ad10a55f3c2af2ec89c989d722983c318fcd860b (patch) | |
tree | dd1af9c2e9d8496a9cef9df3b3a4899ea2b99bdf /gtk | |
parent | ad1d412f8e4cddd7685aa6421fb78fd2b08973ff (diff) |
LinGui: oops. forgot to add new appcast files
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1911 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/src/appcast.c | 271 | ||||
-rw-r--r-- | gtk/src/appcast.h | 22 |
2 files changed, 293 insertions, 0 deletions
diff --git a/gtk/src/appcast.c b/gtk/src/appcast.c new file mode 100644 index 000000000..114b653f2 --- /dev/null +++ b/gtk/src/appcast.c @@ -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 index 000000000..2520be601 --- /dev/null +++ b/gtk/src/appcast.h @@ -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_ |