1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
6 * appcast.c is free software.
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
17 #include <glib/gstdio.h>
18 #include "icon_tools.h"
36 static tag_map_t tag_map[] =
38 {"sparkle:releaseNotesLink", A_DESCRIPTION},
39 {"enclosure", A_ENCLOSURE},
42 #define TAG_MAP_SZ (sizeof(tag_map)/sizeof(tag_map_t))
59 const gchar **attr_names,
60 const gchar **attr_values)
64 if (attr_names == NULL) return NULL;
65 for (ii = 0; attr_names[ii] != NULL; ii++)
67 if (strcmp(name, attr_names[ii]) == 0)
68 return attr_values[ii];
75 GMarkupParseContext *ctx,
77 const gchar **attr_names,
78 const gchar **attr_values,
82 parse_data_t *pd = (parse_data_t*)ud;
90 for (ii = 0; ii < TAG_MAP_SZ; ii++)
92 if (strcmp(tag, tag_map[ii].tag) == 0)
94 id.id = tag_map[ii].id;
100 g_debug("Unrecognized start tag (%s)", tag);
103 g_queue_push_head(pd->tag_stack, id.pid);
112 const gchar *build, *version;
113 build = lookup_attr_value(
114 "sparkle:version", attr_names, attr_values);
115 version = lookup_attr_value(
116 "sparkle:shortVersionString", attr_names, attr_values);
118 pd->build = g_strdup(build);
120 pd->version = g_strdup(version);
127 GMarkupParseContext *ctx,
132 parse_data_t *pd = (parse_data_t*)ud;
141 for (ii = 0; ii < TAG_MAP_SZ; ii++)
143 if (strcmp(tag, tag_map[ii].tag) == 0)
149 if (ii == TAG_MAP_SZ)
151 g_debug("Unrecognized end tag (%s)", tag);
154 start_id.pid = g_queue_pop_head(pd->tag_stack);
155 if (start_id.id != id)
156 g_warning("start tag != end tag: (%s %d) %d", tag, start_id.id, id);
172 GMarkupParseContext *ctx,
178 parse_data_t *pd = (parse_data_t*)ud;
185 start_id.pid = g_queue_peek_head(pd->tag_stack);
192 g_string_append(pd->description, text);
197 if (pd->value) g_free(pd->value);
198 pd->value = g_strdup(text);
205 GMarkupParseContext *ctx,
211 //parse_data_t *pd = (parse_data_t*)ud;
213 //g_debug("passthrough %s", text);
217 parse_error(GMarkupParseContext *ctx, GError *error, gpointer ud)
219 g_warning("Resource parse error: %s", error->message);
222 // This is required or the parser crashes
224 destroy_notify(gpointer data)
226 //g_debug("destroy parser");
230 ghb_appcast_parse(gchar *buf, gchar **desc, gchar **build, gchar **version)
232 GMarkupParseContext *ctx;
233 GMarkupParser parser;
240 // Skip junk at beginning of buffer
241 start = strstr(buf, "<?xml ");
242 pd.description = g_string_new("");
247 pd.tag_stack = g_queue_new();
251 parser.start_element = start_element;
252 parser.end_element = end_element;
253 parser.text = text_data;
254 parser.passthrough = passthrough;
255 parser.error = parse_error;
256 ctx = g_markup_parse_context_new(
257 &parser, G_MARKUP_TREAT_CDATA_AS_TEXT, &pd, destroy_notify);
259 g_markup_parse_context_parse(ctx, start, len, &err);
260 g_markup_parse_context_end_parse(ctx, &err);
261 g_markup_parse_context_free(ctx);
262 g_queue_free(pd.tag_stack);
263 *desc = g_string_free(pd.description, FALSE);
264 // work around a bug to leaves the CDATA closing brakets on the string
266 glitch = g_strrstr(*desc, "]]>");
270 *version = pd.version;