[libgrss] Added grss_feed_parser_parse_channel(), to skip parsing items from XML when not required



commit 71a1dc2ba0c831757783519eb8400c8604aaa664
Author: Roberto Guido <bob4job gmail com>
Date:   Wed Dec 25 18:28:42 2013 +0100

    Added grss_feed_parser_parse_channel(), to skip parsing items from XML when not required

 src/feed-atom-handler.c |    4 +-
 src/feed-channel.c      |   32 ++----------------
 src/feed-handler.c      |    4 +-
 src/feed-handler.h      |    4 +-
 src/feed-parser.c       |   81 ++++++++++++++++++++++++++++++++++-------------
 src/feed-parser.h       |    1 +
 src/feed-pie-handler.c  |    4 +-
 src/feed-rss-handler.c  |    7 ++--
 8 files changed, 75 insertions(+), 62 deletions(-)
---
diff --git a/src/feed-atom-handler.c b/src/feed-atom-handler.c
index 085bba2..7cedb62 100644
--- a/src/feed-atom-handler.c
+++ b/src/feed-atom-handler.c
@@ -765,7 +765,7 @@ atom10_parse_feed_updated (xmlNodePtr cur, GrssFeedChannel *feed)
 }
 
 static GList*
-feed_atom_handler_parse (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc, GError **error)
+feed_atom_handler_parse (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc, gboolean do_items, GError 
**error)
 {
        time_t now;
        xmlNodePtr cur;
@@ -821,7 +821,7 @@ feed_atom_handler_parse (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc
                        if (func) {
                                (*func) (cur, feed);
                        }
-                       else if (xmlStrEqual (cur->name, BAD_CAST"entry")) {
+                       else if (do_items == TRUE && xmlStrEqual (cur->name, BAD_CAST"entry")) {
                                item = atom10_parse_entry (self, feed, cur);
                                if (item) {
                                        if (grss_feed_item_get_publish_time (item) == 0)
diff --git a/src/feed-channel.c b/src/feed-channel.c
index 0bc2fa1..0463ff4 100644
--- a/src/feed-channel.c
+++ b/src/feed-channel.c
@@ -180,7 +180,6 @@ GrssFeedChannel*
 grss_feed_channel_new_from_file (const gchar *path, GError **error)
 {
        struct stat sbuf;
-       GList *items;
        GList *iter;
        xmlDocPtr doc;
        GrssFeedParser *parser;
@@ -201,20 +200,7 @@ grss_feed_channel_new_from_file (const gchar *path, GError **error)
 
        ret = g_object_new (GRSS_FEED_CHANNEL_TYPE, NULL);
        parser = grss_feed_parser_new ();
-
-       /*
-               TODO    This function is quite inefficent because parses all
-                       the feed with a GrssFeedParser and then trash obtained
-                       GrssFeedItems. Perhaps a more aimed function in
-                       GrssFeedParser would help...
-       */
-       items = grss_feed_parser_parse (parser, ret, doc, NULL);
-
-       if (items != NULL) {
-               for (iter = items; iter; iter = g_list_next (iter))
-                       g_object_unref (iter->data);
-               g_list_free (items);
-       }
+       grss_feed_parser_parse_channel (parser, ret, doc, NULL);
 
        g_object_unref (parser);
        xmlFreeDoc (doc);
@@ -901,26 +887,16 @@ quick_and_dirty_parse (GrssFeedChannel *channel, SoupMessage *msg, GList **save_
        xmlDocPtr doc;
        GrssFeedParser *parser;
 
-       /*
-               TODO    This function is quite inefficent because parses all
-                       the feed with a GrssFeedParser also when not required
-                       (save_items == NULL) and wastes time obtained
-                       GrssFeedItems. Perhaps a more aimed function in
-                       GrssFeedParser would help...
-       */
-
        doc = content_to_xml (msg->response_body->data, msg->response_body->length);
 
        if (doc != NULL) {
                parser = grss_feed_parser_new ();
-               items = grss_feed_parser_parse (parser, channel, doc, NULL);
 
-               if (save_items == NULL && items != NULL) {
-                       for (iter = items; iter; iter = g_list_next (iter))
-                               g_object_unref (iter->data);
-                       g_list_free (items);
+               if (save_items == NULL) {
+                       grss_feed_parser_parse_channel (parser, channel, doc, NULL);
                }
                else {
+                       items = grss_feed_parser_parse (parser, channel, doc, NULL);
                        *save_items = items;
                }
 
diff --git a/src/feed-handler.c b/src/feed-handler.c
index 61dcd5c..c4e1feb 100644
--- a/src/feed-handler.c
+++ b/src/feed-handler.c
@@ -63,10 +63,10 @@ feed_handler_check_format (FeedHandler *self, xmlDocPtr doc, xmlNodePtr cur)
 }
 
 GList*
-feed_handler_parse (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc, GError **error)
+feed_handler_parse (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc, gboolean do_items, GError 
**error)
 {
        if (IS_FEED_HANDLER (self) == FALSE)
                return FALSE;
 
-       return FEED_HANDLER_GET_INTERFACE (self)->parse (self, feed, doc, error);
+       return FEED_HANDLER_GET_INTERFACE (self)->parse (self, feed, doc, do_items, error);
 }
diff --git a/src/feed-handler.h b/src/feed-handler.h
index 987ea96..d192bf8 100644
--- a/src/feed-handler.h
+++ b/src/feed-handler.h
@@ -37,13 +37,13 @@ struct _FeedHandlerInterface {
 
        void (*set_ns_handler) (FeedHandler *self, NSHandler *handler);
        gboolean (*check_format) (FeedHandler *self, xmlDocPtr doc, xmlNodePtr cur);
-       GList* (*parse) (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc, GError **error);
+       GList* (*parse) (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc, gboolean do_items, GError 
**error);
 };
 
 GType          feed_handler_get_type           ();
 
 void           feed_handler_set_ns_handler     (FeedHandler *self, NSHandler *handler);
 gboolean       feed_handler_check_format       (FeedHandler *self, xmlDocPtr doc, xmlNodePtr cur);
-GList*         feed_handler_parse              (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc, 
GError **error);
+GList*         feed_handler_parse              (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc, 
gboolean do_items, GError **error);
 
 #endif /* __FEED_HANDLER_H__ */
diff --git a/src/feed-parser.c b/src/feed-parser.c
index de38b8d..73f9a82 100644
--- a/src/feed-parser.c
+++ b/src/feed-parser.c
@@ -148,29 +148,13 @@ retrieve_feed_handler (GrssFeedParser *parser, xmlDocPtr doc, xmlNodePtr cur)
        return NULL;
 }
 
-/**
- * grss_feed_parser_parse:
- * @parser: a #GrssFeedParser.
- * @feed: a #GrssFeedChannel to be parsed.
- * @doc: XML document extracted from the contents of the feed, which must
- *       already been fetched.
- * @error: location for eventual errors.
- *
- * Parses the given XML @doc, belonging to the given @feed, to obtain a list
- * of #GrssFeedItem.
- *
- * Return value: (element-type GrssFeedItem) (transfer full): a list of
- * #GrssFeedItem, to be freed when no longer in use, or NULL if anerror occours
- * and @error is set.
- */
-GList*
-grss_feed_parser_parse (GrssFeedParser *parser, GrssFeedChannel *feed, xmlDocPtr doc, GError **error)
+static FeedHandler*
+init_parsing (GrssFeedParser *parser, xmlDocPtr doc, GError **error)
 {
        xmlNodePtr cur;
-       GList *items;
        FeedHandler *handler;
 
-       items = NULL;
+       handler = NULL;
 
        do {
                if ((cur = xmlDocGetRootElement (doc)) == NULL) {
@@ -197,9 +181,62 @@ grss_feed_parser_parse (GrssFeedParser *parser, GrssFeedChannel *feed, xmlDocPtr
                        break;
                }
 
-               items = feed_handler_parse (handler, feed, doc, error);
-
        } while (0);
 
-       return items;
+       return handler;
 }
+
+/**
+ * grss_feed_parser_parse:
+ * @parser: a #GrssFeedParser.
+ * @feed: a #GrssFeedChannel to be parsed.
+ * @doc: XML document extracted from the contents of the feed, which must
+ *       already been fetched.
+ * @error: location for eventual errors.
+ *
+ * Parses the given XML @doc, belonging to the given @feed, to obtain a list
+ * of #GrssFeedItem.
+ *
+ * Return value: (element-type GrssFeedItem) (transfer full): a list of
+ * #GrssFeedItem, to be freed when no longer in use, or NULL if anerror occours
+ * and @error is set.
+ */
+GList*
+grss_feed_parser_parse (GrssFeedParser *parser, GrssFeedChannel *feed, xmlDocPtr doc, GError **error)
+{
+       FeedHandler *handler;
+
+       handler = init_parsing (parser, doc, error);
+
+       if (handler != NULL)
+               return feed_handler_parse (handler, feed, doc, TRUE, error);
+       else
+               return NULL;
+}
+
+/**
+ * grss_feed_parser_parse_channel:
+ * @parser: a #GrssFeedParser.
+ * @feed: a #GrssFeedChannel to be parsed.
+ * @doc: XML document extracted from the contents of the feed, which must
+ *       already been fetched.
+ * @error: location for eventual errors.
+ *
+ * Parses the given XML @doc, belonging to the given @feed.
+ * 
+ * Similar to grss_feed_parser_parse(), but grss_feed_parser_parse_channel()
+ * skips parsing of items into the document.
+ */
+void
+grss_feed_parser_parse_channel (GrssFeedParser *parser, GrssFeedChannel *feed, xmlDocPtr doc, GError **error)
+{
+       FeedHandler *handler;
+
+       handler = init_parsing (parser, doc, error);
+
+       if (handler != NULL)
+               return feed_handler_parse (handler, feed, doc, FALSE, error);
+       else
+               return NULL;
+}
+
diff --git a/src/feed-parser.h b/src/feed-parser.h
index 461c472..7ed2b14 100644
--- a/src/feed-parser.h
+++ b/src/feed-parser.h
@@ -47,5 +47,6 @@ GType         grss_feed_parser_get_type       () G_GNUC_CONST;
 GrssFeedParser*        grss_feed_parser_new            ();
 
 GList*         grss_feed_parser_parse          (GrssFeedParser *parser, GrssFeedChannel *feed, xmlDocPtr 
doc, GError **error);
+void           grss_feed_parser_parse_channel  (GrssFeedParser *parser, GrssFeedChannel *feed, xmlDocPtr 
doc, GError **error);
 
 #endif /* __FEED_PARSER_H__ */
diff --git a/src/feed-pie-handler.c b/src/feed-pie-handler.c
index 71bc612..5864112 100644
--- a/src/feed-pie-handler.c
+++ b/src/feed-pie-handler.c
@@ -300,7 +300,7 @@ parse_entry (FeedPieHandler *parser, GrssFeedChannel *feed, xmlDocPtr doc, xmlNo
 }
 
 static GList*
-feed_pie_handler_parse (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc, GError **error)
+feed_pie_handler_parse (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc, gboolean do_items, GError 
**error)
 {
        gchar *tmp2;
        gchar *tmp = NULL;
@@ -440,7 +440,7 @@ feed_pie_handler_parse (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc,
                                        g_free (tmp);
                                }
                        }
-                       else if ((!xmlStrcmp (cur->name, BAD_CAST"entry"))) {
+                       else if (do_items == TRUE && (!xmlStrcmp (cur->name, BAD_CAST"entry"))) {
                                item = parse_entry (parser, feed, doc, cur);
                                if (item) {
                                        if (grss_feed_item_get_publish_time (item) == 0)
diff --git a/src/feed-rss-handler.c b/src/feed-rss-handler.c
index 1adbde5..3a7f379 100644
--- a/src/feed-rss-handler.c
+++ b/src/feed-rss-handler.c
@@ -424,7 +424,7 @@ parse_image (xmlNodePtr cur) {
 }
 
 static GList*
-feed_rss_handler_parse (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc, GError **error)
+feed_rss_handler_parse (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc, gboolean do_items, GError 
**error)
 {
        gchar *tmp;
        gboolean rdf;
@@ -499,7 +499,7 @@ feed_rss_handler_parse (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc,
                                g_free (tmp);
                        }
                }
-               else if ((!xmlStrcmp (cur->name, BAD_CAST"items"))) { /* RSS 1.1 */
+               else if (do_items == TRUE && (!xmlStrcmp (cur->name, BAD_CAST"items"))) { /* RSS 1.1 */
                        xmlNodePtr iter = cur->xmlChildrenNode;
 
                        while (iter) {
@@ -514,7 +514,7 @@ feed_rss_handler_parse (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc,
                                iter = iter->next;
                        }
                }
-               else if ((!xmlStrcmp (cur->name, BAD_CAST"item"))) { /* RSS 1.0, 2.0 */
+               else if (do_items == TRUE && (!xmlStrcmp (cur->name, BAD_CAST"item"))) { /* RSS 1.0, 2.0 */
                        item = parse_rss_item (parser, feed, doc, cur);
 
                        if (item != NULL) {
@@ -522,7 +522,6 @@ feed_rss_handler_parse (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc,
                                        grss_feed_item_set_publish_time (item, now);
                                items = g_list_append (items, item);
                        }
-
                }
 
                cur = cur->next;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]