[libgdata] core: Virtualise feed parsing in GDataService



commit 1e5e69909cec7cc4d75c8ac2ae326b29795f01a8
Author: Philip Withnall <philip withnall collabora co uk>
Date:   Fri Dec 12 19:45:40 2014 +0000

    core: Virtualise feed parsing in GDataService
    
    Split the bulk of feed parsing out into a virtual method on
    GDataService. This will allow subclasses of GDataService to implement
    service-specific tweaks to feed parsing, which is required for
    pagination handling with Google Documents.
    
    New API:
     • GDataServiceClass.parse_feed
    
    This does not break ABI — it consumes one of the struct’s expansion
    slots.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=741345

 gdata/gdata-service.c |   49 ++++++++++++++++++++++++++++++++++++++++---------
 gdata/gdata-service.h |   15 +++++++++++++--
 2 files changed, 53 insertions(+), 11 deletions(-)
---
diff --git a/gdata/gdata-service.c b/gdata/gdata-service.c
index cc3ff71..ad4c1bc 100644
--- a/gdata/gdata-service.c
+++ b/gdata/gdata-service.c
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 /*
  * GData Client
- * Copyright (C) Philip Withnall 2008–2010 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2008, 2009, 2010, 2014 <philip tecnocode co uk>
  *
  * GData Client is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -68,6 +68,16 @@ static void gdata_service_set_property (GObject *object, guint property_id, cons
 static void real_append_query_headers (GDataService *self, GDataAuthorizationDomain *domain, SoupMessage 
*message);
 static void real_parse_error_response (GDataService *self, GDataOperationType operation_type, guint status, 
const gchar *reason_phrase,
                                        const gchar *response_body, gint length, GError **error);
+static GDataFeed *
+real_parse_feed (GDataService *self,
+                 GDataAuthorizationDomain *domain,
+                 GDataQuery *query,
+                 GType entry_type,
+                 SoupMessage *message,
+                 GCancellable *cancellable,
+                 GDataQueryProgressCallback progress_callback,
+                 gpointer progress_user_data,
+                 GError **error);
 static void notify_proxy_uri_cb (GObject *gobject, GParamSpec *pspec, GObject *self);
 static void notify_timeout_cb (GObject *gobject, GParamSpec *pspec, GObject *self);
 static void debug_handler (const char *log_domain, GLogLevelFlags log_level, const char *message, gpointer 
user_data);
@@ -113,6 +123,7 @@ gdata_service_class_init (GDataServiceClass *klass)
        klass->feed_type = GDATA_TYPE_FEED;
        klass->append_query_headers = real_append_query_headers;
        klass->parse_error_response = real_parse_error_response;
+       klass->parse_feed = real_parse_feed;
        klass->get_authorization_domains = NULL; /* equivalent to returning an empty list of domains */
 
        /**
@@ -949,10 +960,8 @@ __gdata_service_query (GDataService *self, GDataAuthorizationDomain *domain, con
                        GCancellable *cancellable, GDataQueryProgressCallback progress_callback, gpointer 
progress_user_data, GError **error)
 {
        GDataServiceClass *klass;
-       GDataFeed *feed = NULL;
        SoupMessage *message;
-       SoupMessageHeaders *headers;
-       const gchar *content_type;
+       GDataFeed *feed;
 
        message = _gdata_service_query (self, domain, feed_uri, query, cancellable, error);
        if (message == NULL)
@@ -960,7 +969,34 @@ __gdata_service_query (GDataService *self, GDataAuthorizationDomain *domain, con
 
        g_assert (message->response_body->data != NULL);
        klass = GDATA_SERVICE_GET_CLASS (self);
+       g_assert (klass->parse_feed != NULL);
+
+       feed = klass->parse_feed (self, domain, query, entry_type,
+                                 message, cancellable, progress_callback,
+                                 progress_user_data, error);
 
+       g_object_unref (message);
+
+       return feed;
+}
+
+static GDataFeed *
+real_parse_feed (GDataService *self,
+                 GDataAuthorizationDomain *domain,
+                 GDataQuery *query,
+                 GType entry_type,
+                 SoupMessage *message,
+                 GCancellable *cancellable,
+                 GDataQueryProgressCallback progress_callback,
+                 gpointer progress_user_data,
+                 GError **error)
+{
+       GDataServiceClass *klass;
+       GDataFeed *feed = NULL;
+       SoupMessageHeaders *headers;
+       const gchar *content_type;
+
+       klass = GDATA_SERVICE_GET_CLASS (self);
        headers = message->response_headers;
        content_type = soup_message_headers_get_content_type (headers, NULL);
 
@@ -977,11 +1013,6 @@ __gdata_service_query (GDataService *self, GDataAuthorizationDomain *domain, con
                                                 progress_callback, progress_user_data, error);
        }
 
-       g_object_unref (message);
-
-       if (feed == NULL)
-               return NULL;
-
        /* Update the query with the feed's ETag */
        if (query != NULL && feed != NULL && gdata_feed_get_etag (feed) != NULL)
                gdata_query_set_etag (query, gdata_feed_get_etag (feed));
diff --git a/gdata/gdata-service.h b/gdata/gdata-service.h
index e5db304..745f267 100644
--- a/gdata/gdata-service.h
+++ b/gdata/gdata-service.h
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 /*
  * GData Client
- * Copyright (C) Philip Withnall 2008–2010 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2008, 2009, 2010, 2014 <philip tecnocode co uk>
  *
  * GData Client is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -26,6 +26,7 @@
 
 #include <gdata/gdata-authorizer.h>
 #include <gdata/gdata-feed.h>
+#include <gdata/gdata-query.h>
 
 G_BEGIN_DECLS
 
@@ -139,6 +140,8 @@ typedef struct {
  * @get_authorization_domains: a function to return a newly-allocated list of all the 
#GDataAuthorizationDomain<!-- -->s the service makes use of;
  * while the list should be newly-allocated, the individual domains should not be; not implementing this 
function is equivalent to returning an
  * empty list; new in version 0.9.0
+ * @parse_feed: a function to parse feed responses to queries from the online
+ * service; new in version UNRELEASED
  *
  * The class structure for the #GDataService type.
  *
@@ -154,10 +157,18 @@ typedef struct {
        void (*parse_error_response) (GDataService *self, GDataOperationType operation_type, guint status, 
const gchar *reason_phrase,
                                      const gchar *response_body, gint length, GError **error);
        GList *(*get_authorization_domains) (void);
+       GDataFeed *(*parse_feed) (GDataService *self,
+                                 GDataAuthorizationDomain *domain,
+                                 GDataQuery *query,
+                                 GType entry_type,
+                                 SoupMessage *message,
+                                 GCancellable *cancellable,
+                                 GDataQueryProgressCallback progress_callback,
+                                 gpointer progress_user_data,
+                                 GError **error);
 
        /*< private >*/
        /* Padding for future expansion */
-       void (*_g_reserved0) (void);
        void (*_g_reserved1) (void);
        void (*_g_reserved2) (void);
        void (*_g_reserved3) (void);


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