diff options
author | Alan F <ajf@eth0.org.uk> | 2014-04-13 17:36:26 +0100 |
---|---|---|
committer | Alan F <ajf@eth0.org.uk> | 2014-04-13 17:36:26 +0100 |
commit | 91356636c1e2d02a76ff31189e106de53b569c49 (patch) | |
tree | 57e56f6fddec9a40451a345727eb3822e2291dd6 /extern/rss-glib/rss-parser.c | |
parent | ec6a252a019e90ecc6825078ee7d79a24b82770f (diff) |
bundle the libmrss wrapper to make building easier
Diffstat (limited to 'extern/rss-glib/rss-parser.c')
-rw-r--r-- | extern/rss-glib/rss-parser.c | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/extern/rss-glib/rss-parser.c b/extern/rss-glib/rss-parser.c new file mode 100644 index 0000000..184db19 --- /dev/null +++ b/extern/rss-glib/rss-parser.c @@ -0,0 +1,334 @@ +/* rss-generator.c + * + * This file is part of RSS-GLib. + * Copyright (C) 2008 Christian Hergert <chris@dronelabs.com> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Christian Hergert <chris@dronelabs.com> + */ + +/** + * SECTION:rss-parser + * @short_description: Parse RSS data streams + * + * #RssParser provides an object for parsing a RSS data stream, either + * inside a file or inside a static buffer. + */ + +#include "rss-parser.h" +#include "rss-parser-private.h" + +#include "rss-item.h" +#include "rss-item-private.h" + +#include "rss-document.h" +#include "rss-document-private.h" + +GQuark +rss_parser_error_quark (void) +{ + return g_quark_from_static_string ("rss_parser_error"); +} + +enum +{ + PARSE_START, + PARSE_END, + + LAST_SIGNAL +}; + +static guint parser_signals[LAST_SIGNAL] = { 0, }; + +G_DEFINE_TYPE (RssParser, rss_parser, G_TYPE_OBJECT); + +static void +rss_parser_dispose (GObject *object) +{ + RssParserPrivate *priv = RSS_PARSER (object)->priv; + + if (priv->document) { + g_object_unref (priv->document); + priv->document = NULL; + } + + G_OBJECT_CLASS (rss_parser_parent_class)->dispose (object); +} + +static void +rss_parser_class_init (RssParserClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (RssParserPrivate)); + object_class->dispose = rss_parser_dispose; + + /** + * RssParser::parse-start: + * @parser: the #RssParser that received the signal + * + * The ::parse-signal is emitted when the parser began parsing + * a RSS data stream. + */ + parser_signals[PARSE_START] = + g_signal_new ("parse-start", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (RssParserClass, parse_start), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * RssParser::parse-end: + * @parser: the #RssParser that received the signal + * + * The ::parse-end signal is emitted when the parser successfully + * finished parsing a RSS data stream. + */ + parser_signals[PARSE_END] = + g_signal_new ("parse-end", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (RssParserClass, parse_end), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +rss_parser_init (RssParser *self) +{ + self->priv = + G_TYPE_INSTANCE_GET_PRIVATE (self, RSS_TYPE_PARSER, + RssParserPrivate); +} + +/** + * rss_parser_new: + * + * Creates a new #RssParser instance. You can use the #RssParser to + * load a RSS stream from either a file or a buffer and then walk the + * items discovered through the resulting RssDocument. + * + * Return value: the new created #RssParser. Use g_object_unref() to + * release all the memory it allocates. + */ +RssParser* +rss_parser_new (void) +{ + return g_object_new (RSS_TYPE_PARSER, NULL); +} + +static RssDocument* +rss_parser_parse (RssParser *self, mrss_t *mrss) +{ + RssDocument *document; + RssItem *rss_item; + GList *list, *list2; + mrss_category_t *cat; + mrss_item_t *item; + + g_return_val_if_fail (RSS_IS_PARSER (self), NULL); + g_return_val_if_fail (mrss != NULL, NULL); + + /* create our document object */ + document = rss_document_new (); + + /* set our document level properties */ + g_object_set (document, + "encoding", mrss->encoding, + "guid", mrss->id, + "title", mrss->title, + "description", mrss->description, + "link", mrss->link, + "language", mrss->language, + "rating", mrss->rating, + "copyright", mrss->copyright, + "pub-date", mrss->pubDate, + "ttl", mrss->ttl, + "about", mrss->about, + "contributor", mrss->contributor, + "contributor-email", mrss->contributor_email, + "contributor-uri", mrss->contributor_uri, + "generator", mrss->generator, + "generator-uri", mrss->generator_uri, + "generator-version", mrss->generator_version, + "image-title", mrss->image_title, + "image-url", mrss->image_url, + "image-link", mrss->image_link, + NULL); + + /* build the list of categories */ + if (NULL != (cat = mrss->category)) { + list = NULL; + do { + list = g_list_prepend (list, g_strdup (cat->category)); + } while (NULL != (cat = cat->next)); + document->priv->categories = list; + } + + /* build the list of items */ + if (NULL != (item = mrss->item)) { + list = NULL; + do { + rss_item = rss_item_new (); + + /* set the rss item properties */ + g_object_set (rss_item, + "guid", item->guid, + "title", item->title, + "link", item->link, + "description", item->description, + "copyright", item->copyright, + "author", item->author, + "author-uri", item->author_uri, + "author-email", item->author_email, + "contributor", item->contributor, + "contributor-uri", item->contributor_uri, + "contributor-email", item->contributor_email, + "comments", item->comments, + "pub-date", item->pubDate, + "source", item->source, + "source-url", item->source_url, + NULL); + + /* parse the items categories */ + if (NULL != (cat = item->category)) { + list2 = NULL; + do { + list2 = g_list_prepend (list2, g_strdup (cat->category)); + } while (NULL != (cat = cat->next)); + rss_item->priv->categories = list2; + } + + list = g_list_prepend (list, rss_item); + } while (NULL != (item = item->next)); + document->priv->items = list; + } + + return document; +} + +/** + * rss_parser_load_from_data: + * @self: a #RssParser + * @data: a buffer containing the syndication data + * @length: the length of the buffer + * @error: a location to place a newly created GError in case of error + * + * Parses the contents found at @data as an rss file. You can retrieve + * the parsed document with rss_parser_get_document(). + * + * Returns: TRUE on success. + */ +gboolean +rss_parser_load_from_data (RssParser *self, + const gchar *data, + gsize length, + GError **error) +{ + mrss_t *mrss; + mrss_error_t res; + + g_signal_emit (self, parser_signals[PARSE_START], 0); + + /* parse the buffer */ + res = mrss_parse_buffer ((char*)data, length, &mrss); + + /* if there was an error parsing, set the error and return false */ + if (MRSS_OK != res) { + if (error) { + g_set_error (error, RSS_PARSER_ERROR, + RSS_PARSER_ERROR_INVALID_DATA, + "Could not parse data contents"); + } + return FALSE; + } + + /* keep a copy of our parsed document */ + self->priv->document = rss_parser_parse (self, mrss); + + /* free our mrss data */ + mrss_free (mrss); + + g_signal_emit (self, parser_signals[PARSE_END], 0); + + return TRUE; +} + +/** + * rss_parser_load_from_file: + * @self: a #RssParser + * @filename: the path to the file to parse + * @error: a location for a newly created #GError + * + * Parses the file found at @filename as an rss file. You can retrieve + * the parsed document with rss_parser_get_document(). + * + * Returns: TRUE if the parse was successful + */ +gboolean +rss_parser_load_from_file (RssParser *self, + gchar *filename, + GError **error) +{ + mrss_t *mrss; + mrss_error_t res; + + g_signal_emit (self, parser_signals[PARSE_START], 0); + + /* parse the buffer */ + res = mrss_parse_file (filename, &mrss); + + /* if there was an error parsing, set the error and return false */ + if (MRSS_OK != res) { + if (error) { + g_set_error (error, RSS_PARSER_ERROR, + RSS_PARSER_ERROR_INVALID_DATA, + "Could not parse file contents"); + } + return FALSE; + } + + /* keep a copy of our parsed document */ + self->priv->document = rss_parser_parse (self, mrss); + + /* free our mrss data */ + mrss_free (mrss); + + g_signal_emit (self, parser_signals[PARSE_END], 0); + + return TRUE; +} + +/** + * rss_parser_get_document: + * @self: a #RssParser + * + * Retreives the document result from parsing rss data from either + * a buffer or a file. The document's ref-count is increased, so + * call g_object_unref when you are done. + * + * Returns: a #RssDocument + */ +RssDocument* +rss_parser_get_document (RssParser *self) +{ + g_return_val_if_fail (RSS_IS_PARSER (self), NULL); + + return g_object_ref (self->priv->document); +} |